<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>APL on CPEX Documentation</title><link>https://contextforge-org.github.io/cpex/docs/apl/</link><description>Recent content in APL on CPEX Documentation</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://contextforge-org.github.io/cpex/docs/apl/index.xml" rel="self" type="application/rss+xml"/><item><title>Effects &amp; Sequencing</title><link>https://contextforge-org.github.io/cpex/docs/apl/effects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://contextforge-org.github.io/cpex/docs/apl/effects/</guid><description>&lt;h1 id="effects-and-sequencing"&gt;Effects and Sequencing&lt;a class="anchor" href="#effects-and-sequencing"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;An APL rule does something. That something is an &lt;strong&gt;effect&lt;/strong&gt;. Effects are the building blocks of policy: a &lt;code&gt;policy:&lt;/code&gt; block is an ordered list of them, and they run in sequence until one denies.&lt;/p&gt;
&lt;h2 id="the-effects"&gt;The effects&lt;a class="anchor" href="#the-effects"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Effect&lt;/th&gt;
					&lt;th&gt;What it does&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;allow&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;No-op. Continue to the next effect.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;deny&lt;/code&gt; / &lt;code&gt;deny('reason')&lt;/code&gt; / &lt;code&gt;deny('reason', 'code')&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Halt the phase and all later phases with a violation.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;plugin(name)&lt;/code&gt; (alias &lt;code&gt;run(name)&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;Invoke a registered plugin (PII scan, audit log, custom check).&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;delegate(name, ...)&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Mint a downstream credential via a delegator plugin. See &lt;a href="https://contextforge-org.github.io/cpex/docs/apl/delegation/"&gt;Delegation&lt;/a&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;taint(label[, scope])&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Attach a label to the session or message. See &lt;a href="https://contextforge-org.github.io/cpex/docs/apl/tainting/"&gt;Session Tainting&lt;/a&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;field pipelines&lt;/td&gt;
					&lt;td&gt;Validate or transform &lt;code&gt;args&lt;/code&gt;/&lt;code&gt;result&lt;/code&gt; fields. See &lt;a href="https://contextforge-org.github.io/cpex/docs/apl/"&gt;APL&lt;/a&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PDP call (&lt;code&gt;cedar:&lt;/code&gt;, &lt;code&gt;cel:&lt;/code&gt;, &lt;code&gt;opa(...)&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;Delegate the decision to a policy engine. See &lt;a href="https://contextforge-org.github.io/cpex/docs/apl/pdp/"&gt;PDP Integration&lt;/a&gt;.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="sequencing-and-halt-on-deny"&gt;Sequencing and halt-on-deny&lt;a class="anchor" href="#sequencing-and-halt-on-deny"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Effects in a &lt;code&gt;policy:&lt;/code&gt; block run top to bottom. The first &lt;code&gt;deny&lt;/code&gt; halts the phase and skips every later phase, so order is a tool: put cheap gates first and expensive effects last.&lt;/p&gt;</description></item><item><title>PDP Integration</title><link>https://contextforge-org.github.io/cpex/docs/apl/pdp/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://contextforge-org.github.io/cpex/docs/apl/pdp/</guid><description>&lt;h1 id="pdp-integration"&gt;PDP Integration&lt;a class="anchor" href="#pdp-integration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;APL predicates handle attribute checks well: roles, permissions, scopes, comparisons. They are a poor fit for relationship questions (&amp;ldquo;is this user on the team that owns this repo?&amp;rdquo;) and for policy you already maintain in a dedicated engine. For those, APL hands the decision to a &lt;strong&gt;Policy Decision Point&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="the-requirement"&gt;The requirement&lt;a class="anchor" href="#the-requirement"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The scenario&amp;rsquo;s repository search must allow a read when the caller is an engineer and the repo is internal, or when the caller is on the security team, regardless of repo. That is a relationship-and-attribute decision over entities, which is exactly what an engine like Cedar exists to express. APL should make the coarse gate and let the engine make the fine-grained call.&lt;/p&gt;</description></item><item><title>Identity &amp; IdP</title><link>https://contextforge-org.github.io/cpex/docs/apl/identity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://contextforge-org.github.io/cpex/docs/apl/identity/</guid><description>&lt;h1 id="identity-and-idp-integration"&gt;Identity and IdP Integration&lt;a class="anchor" href="#identity-and-idp-integration"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Policy reads attributes: &lt;code&gt;role.hr&lt;/code&gt;, &lt;code&gt;perm.view_ssn&lt;/code&gt;, &lt;code&gt;subject.id&lt;/code&gt;. Those attributes have to come from somewhere trustworthy. They come from identity resolution, which runs before policy and turns a verified credential into the attribute bag that predicates read.&lt;/p&gt;
&lt;h2 id="the-requirement"&gt;The requirement&lt;a class="anchor" href="#the-requirement"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The scenario authorizes with &lt;code&gt;require(role.hr)&lt;/code&gt; and redacts with &lt;code&gt;redact(!perm.view_ssn)&lt;/code&gt;. For those to mean anything, CPEX must know, for each request, who the caller is and what roles and permissions they hold, established from a token the caller cannot forge, not from anything the LLM said.&lt;/p&gt;</description></item><item><title>Delegation</title><link>https://contextforge-org.github.io/cpex/docs/apl/delegation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://contextforge-org.github.io/cpex/docs/apl/delegation/</guid><description>&lt;h1 id="delegation-and-token-exchange"&gt;Delegation and Token Exchange&lt;a class="anchor" href="#delegation-and-token-exchange"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;When CPEX forwards an operation to a backend, the backend needs a credential. Forwarding the caller&amp;rsquo;s inbound token is usually wrong: it is scoped for the agent, not the backend, and it carries more privilege than the operation needs. Delegation mints a fresh, narrowly scoped credential for the specific downstream call.&lt;/p&gt;
&lt;h2 id="the-requirement"&gt;The requirement&lt;a class="anchor" href="#the-requirement"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The scenario&amp;rsquo;s &lt;code&gt;get_compensation&lt;/code&gt; reads from a backend HR system that expects its own audience-scoped token with only the &lt;code&gt;read_compensation&lt;/code&gt; scope. The caller never holds that token. CPEX must exchange the caller&amp;rsquo;s verified identity for a downstream credential, scoped down to exactly what the operation needs, and only after authorization has passed.&lt;/p&gt;</description></item><item><title>Session Tainting</title><link>https://contextforge-org.github.io/cpex/docs/apl/tainting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://contextforge-org.github.io/cpex/docs/apl/tainting/</guid><description>&lt;h1 id="session-tainting-and-information-flow"&gt;Session Tainting and Information Flow&lt;a class="anchor" href="#session-tainting-and-information-flow"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Some controls cannot be decided from a single request. &amp;ldquo;Do not send anything externally after reading secret data&amp;rdquo; depends on what the session did earlier. CPEX tracks that history as &lt;strong&gt;taint labels&lt;/strong&gt;: facts attached to a session that later policy can read. This is how CPEX enforces information-flow control, including write-down prevention.&lt;/p&gt;
&lt;h2 id="the-requirement"&gt;The requirement&lt;a class="anchor" href="#the-requirement"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A caller reads compensation data, then asks the agent to send an email. The email body is clean: no SSN, no salary, nothing sensitive in the text. It should still be blocked, because this session has handled secret data and an external send is a write-down. The LLM cannot be trusted to remember this or to refuse on its own, and a content scan of the email body would not catch it. The control has to live in state the model cannot see.&lt;/p&gt;</description></item></channel></rss>