Simplify spec: remove sub, move compensation and policy to ext
- Remove sub claim (always equals iss, added no information) - Move compensation_required and compensation_reason to ext keys - Move pol, pol_decision, pol_enforcer to ext keys - IANA JWT Claims table reduced from 11 to 6 registered claims - Trim witness attestation section to concise guidance - Fix remaining ledger-mandatory language in verification step 15 and minimal implementation guidance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1242,7 +1242,7 @@ li > p:last-of-type:only-child {
|
|||||||
</tr></thead>
|
</tr></thead>
|
||||||
<tfoot><tr>
|
<tfoot><tr>
|
||||||
<td class="left">Nennemann</td>
|
<td class="left">Nennemann</td>
|
||||||
<td class="center">Expires 28 August 2026</td>
|
<td class="center">Expires 29 August 2026</td>
|
||||||
<td class="right">[Page]</td>
|
<td class="right">[Page]</td>
|
||||||
</tr></tfoot>
|
</tr></tfoot>
|
||||||
</table>
|
</table>
|
||||||
@@ -1255,12 +1255,12 @@ li > p:last-of-type:only-child {
|
|||||||
<dd class="internet-draft">draft-nennemann-wimse-execution-context-00</dd>
|
<dd class="internet-draft">draft-nennemann-wimse-execution-context-00</dd>
|
||||||
<dt class="label-published">Published:</dt>
|
<dt class="label-published">Published:</dt>
|
||||||
<dd class="published">
|
<dd class="published">
|
||||||
<time datetime="2026-02-24" class="published">24 February 2026</time>
|
<time datetime="2026-02-25" class="published">25 February 2026</time>
|
||||||
</dd>
|
</dd>
|
||||||
<dt class="label-intended-status">Intended Status:</dt>
|
<dt class="label-intended-status">Intended Status:</dt>
|
||||||
<dd class="intended-status">Standards Track</dd>
|
<dd class="intended-status">Standards Track</dd>
|
||||||
<dt class="label-expires">Expires:</dt>
|
<dt class="label-expires">Expires:</dt>
|
||||||
<dd class="expires"><time datetime="2026-08-28">28 August 2026</time></dd>
|
<dd class="expires"><time datetime="2026-08-29">29 August 2026</time></dd>
|
||||||
<dt class="label-authors">Author:</dt>
|
<dt class="label-authors">Author:</dt>
|
||||||
<dd class="authors">
|
<dd class="authors">
|
||||||
<div class="author">
|
<div class="author">
|
||||||
@@ -1312,7 +1312,7 @@ regulatory frameworks.<a href="#section-abstract-1" class="pilcrow">¶</a></p>
|
|||||||
time. It is inappropriate to use Internet-Drafts as reference
|
time. It is inappropriate to use Internet-Drafts as reference
|
||||||
material or to cite them other than as "work in progress."<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p>
|
material or to cite them other than as "work in progress."<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p>
|
||||||
<p id="section-boilerplate.1-4">
|
<p id="section-boilerplate.1-4">
|
||||||
This Internet-Draft will expire on 28 August 2026.<a href="#section-boilerplate.1-4" class="pilcrow">¶</a></p>
|
This Internet-Draft will expire on 29 August 2026.<a href="#section-boilerplate.1-4" class="pilcrow">¶</a></p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="copyright">
|
<div id="copyright">
|
||||||
@@ -1391,7 +1391,7 @@ regulatory frameworks.<a href="#section-abstract-1" class="pilcrow">¶</a></p>
|
|||||||
<p id="section-toc.1-1.4.2.2.2.2.1"><a href="#section-4.2.2" class="auto internal xref">4.2.2</a>. <a href="#name-execution-context" class="internal xref">Execution Context</a></p>
|
<p id="section-toc.1-1.4.2.2.2.2.1"><a href="#section-4.2.2" class="auto internal xref">4.2.2</a>. <a href="#name-execution-context" class="internal xref">Execution Context</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.3">
|
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.3">
|
||||||
<p id="section-toc.1-1.4.2.2.2.3.1"><a href="#section-4.2.3" class="auto internal xref">4.2.3</a>. <a href="#name-policy-evaluation" class="internal xref">Policy Evaluation</a></p>
|
<p id="section-toc.1-1.4.2.2.2.3.1"><a href="#section-4.2.3" class="auto internal xref">4.2.3</a>. <a href="#name-policy-evaluation-extension" class="internal xref">Policy Evaluation Extension Keys</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.4">
|
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.4">
|
||||||
<p id="section-toc.1-1.4.2.2.2.4.1"><a href="#section-4.2.4" class="auto internal xref">4.2.4</a>. <a href="#name-data-integrity" class="internal xref">Data Integrity</a></p>
|
<p id="section-toc.1-1.4.2.2.2.4.1"><a href="#section-4.2.4" class="auto internal xref">4.2.4</a>. <a href="#name-data-integrity" class="internal xref">Data Integrity</a></p>
|
||||||
@@ -1475,11 +1475,6 @@ regulatory frameworks.<a href="#section-abstract-1" class="pilcrow">¶</a></p>
|
|||||||
</li>
|
</li>
|
||||||
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10.2.2">
|
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10.2.2">
|
||||||
<p id="section-toc.1-1.10.2.2.1"><a href="#section-10.2" class="auto internal xref">10.2</a>. <a href="#name-self-assertion-limitation" class="internal xref">Self-Assertion Limitation</a></p>
|
<p id="section-toc.1-1.10.2.2.1"><a href="#section-10.2" class="auto internal xref">10.2</a>. <a href="#name-self-assertion-limitation" class="internal xref">Self-Assertion Limitation</a></p>
|
||||||
<ul class="compact toc ulBare ulEmpty">
|
|
||||||
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10.2.2.2.1">
|
|
||||||
<p id="section-toc.1-1.10.2.2.2.1.1"><a href="#section-10.2.1" class="auto internal xref">10.2.1</a>. <a href="#name-witness-attestation-model" class="internal xref">Witness Attestation Model</a></p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10.2.3">
|
<li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10.2.3">
|
||||||
<p id="section-toc.1-1.10.2.3.1"><a href="#section-10.3" class="auto internal xref">10.3</a>. <a href="#name-organizational-prerequisite" class="internal xref">Organizational Prerequisites</a></p>
|
<p id="section-toc.1-1.10.2.3.1"><a href="#section-10.3" class="auto internal xref">10.3</a>. <a href="#name-organizational-prerequisite" class="internal xref">Organizational Prerequisites</a></p>
|
||||||
@@ -1705,7 +1700,7 @@ regulatory audit scenarios.<a href="#section-1.2-3" class="pilcrow">¶</a></p>
|
|||||||
<p id="section-1.3-2.2.1">DAG structure for task dependency ordering (<a href="#dag-validation" class="auto internal xref">Section 6</a>)<a href="#section-1.3-2.2.1" class="pilcrow">¶</a></p>
|
<p id="section-1.3-2.2.1">DAG structure for task dependency ordering (<a href="#dag-validation" class="auto internal xref">Section 6</a>)<a href="#section-1.3-2.2.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-1.3-2.3">
|
<li class="normal" id="section-1.3-2.3">
|
||||||
<p id="section-1.3-2.3.1">Policy checkpoint recording (<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>)<a href="#section-1.3-2.3.1" class="pilcrow">¶</a></p>
|
<p id="section-1.3-2.3.1">Policy checkpoint recording via extension keys (<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>)<a href="#section-1.3-2.3.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-1.3-2.4">
|
<li class="normal" id="section-1.3-2.4">
|
||||||
<p id="section-1.3-2.4.1">Integration with the WIMSE identity framework
|
<p id="section-1.3-2.4.1">Integration with the WIMSE identity framework
|
||||||
@@ -2068,63 +2063,55 @@ deployments <span class="bcp14">MAY</span> use other URI schemes (e.g., HTTPS UR
|
|||||||
URN:UUID identifiers).<a href="#section-4.2.1-2.2.1" class="pilcrow">¶</a></p>
|
URN:UUID identifiers).<a href="#section-4.2.1-2.2.1" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
<dt id="section-4.2.1-2.3">sub:</dt>
|
<dt id="section-4.2.1-2.3">aud:</dt>
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.1-2.4">
|
<dd style="margin-left: 1.5em" id="section-4.2.1-2.4">
|
||||||
<p id="section-4.2.1-2.4.1"><span class="bcp14">OPTIONAL</span>. StringOrURI. The subject of the ECT. When present,
|
<p id="section-4.2.1-2.4.1"><span class="bcp14">REQUIRED</span>. StringOrURI or array of StringOrURI. The intended
|
||||||
<span class="bcp14">MUST</span> equal the "iss" claim. This claim is included for
|
|
||||||
compatibility with JWT libraries and frameworks that expect a
|
|
||||||
"sub" claim to be present.<a href="#section-4.2.1-2.4.1" class="pilcrow">¶</a></p>
|
|
||||||
</dd>
|
|
||||||
<dd class="break"></dd>
|
|
||||||
<dt id="section-4.2.1-2.5">aud:</dt>
|
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.1-2.6">
|
|
||||||
<p id="section-4.2.1-2.6.1"><span class="bcp14">REQUIRED</span>. StringOrURI or array of StringOrURI. The intended
|
|
||||||
recipient(s) of the ECT. Because ECTs serve as both inter-agent
|
recipient(s) of the ECT. Because ECTs serve as both inter-agent
|
||||||
messages and audit records, the "aud" claim <span class="bcp14">SHOULD</span> contain the
|
messages and audit records, the "aud" claim <span class="bcp14">SHOULD</span> contain the
|
||||||
identifiers of all entities that will verify the ECT. In
|
identifiers of all entities that will verify the ECT. In
|
||||||
practice this means:<a href="#section-4.2.1-2.6.1" class="pilcrow">¶</a></p>
|
practice this means:<a href="#section-4.2.1-2.4.1" class="pilcrow">¶</a></p>
|
||||||
<ul class="normal">
|
<ul class="normal">
|
||||||
<li class="normal" id="section-4.2.1-2.6.2.1">
|
<li class="normal" id="section-4.2.1-2.4.2.1">
|
||||||
<p id="section-4.2.1-2.6.2.1.1"><strong>Point-to-point delivery</strong>: when an ECT is sent from one
|
<p id="section-4.2.1-2.4.2.1.1"><strong>Point-to-point delivery</strong>: when an ECT is sent from one
|
||||||
agent to a single next agent, "aud" contains that agent's
|
agent to a single next agent, "aud" contains that agent's
|
||||||
workload identity. The receiving agent verifies the ECT and
|
workload identity. The receiving agent verifies the ECT and
|
||||||
forwards it to the ledger on behalf of the issuer.<a href="#section-4.2.1-2.6.2.1.1" class="pilcrow">¶</a></p>
|
forwards it to the ledger on behalf of the issuer.<a href="#section-4.2.1-2.4.2.1.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.1-2.6.2.2">
|
<li class="normal" id="section-4.2.1-2.4.2.2">
|
||||||
<p id="section-4.2.1-2.6.2.2.1"><strong>Direct-to-ledger submission</strong>: when an ECT is submitted
|
<p id="section-4.2.1-2.4.2.2.1"><strong>Direct-to-ledger submission</strong>: when an ECT is submitted
|
||||||
directly to the audit ledger (e.g., after a join or at
|
directly to the audit ledger (e.g., after a join or at
|
||||||
workflow completion), "aud" contains the ledger's identity.<a href="#section-4.2.1-2.6.2.2.1" class="pilcrow">¶</a></p>
|
workflow completion), "aud" contains the ledger's identity.<a href="#section-4.2.1-2.4.2.2.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.1-2.6.2.3">
|
<li class="normal" id="section-4.2.1-2.4.2.3">
|
||||||
<p id="section-4.2.1-2.6.2.3.1"><strong>Multi-audience</strong>: when an ECT must be verified by both the
|
<p id="section-4.2.1-2.4.2.3.1"><strong>Multi-audience</strong>: when an ECT must be verified by both the
|
||||||
next agent and the ledger independently, "aud" <span class="bcp14">MUST</span> be an
|
next agent and the ledger independently, "aud" <span class="bcp14">MUST</span> be an
|
||||||
array containing both identifiers (e.g.,
|
array containing both identifiers (e.g.,
|
||||||
["spiffe://example.com/agent/next",
|
["spiffe://example.com/agent/next",
|
||||||
"spiffe://example.com/system/ledger"]). Each verifier checks
|
"spiffe://example.com/system/ledger"]). Each verifier checks
|
||||||
that its own identity appears in the array.<a href="#section-4.2.1-2.6.2.3.1" class="pilcrow">¶</a></p>
|
that its own identity appears in the array.<a href="#section-4.2.1-2.4.2.3.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p id="section-4.2.1-2.6.3">In multi-parent (join) scenarios where a task depends on ECTs
|
<p id="section-4.2.1-2.4.3">In multi-parent (join) scenarios where a task depends on ECTs
|
||||||
from multiple parent agents, the joining agent creates a new ECT
|
from multiple parent agents, the joining agent creates a new ECT
|
||||||
with the parent task IDs in "par". The "aud" of this new ECT
|
with the parent task IDs in "par". The "aud" of this new ECT
|
||||||
is set according to the rules above based on where the ECT will
|
is set according to the rules above based on where the ECT will
|
||||||
be delivered — it is independent of the "aud" values in the
|
be delivered — it is independent of the "aud" values in the
|
||||||
parent ECTs.<a href="#section-4.2.1-2.6.3" class="pilcrow">¶</a></p>
|
parent ECTs.<a href="#section-4.2.1-2.4.3" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
<dt id="section-4.2.1-2.7">iat:</dt>
|
<dt id="section-4.2.1-2.5">iat:</dt>
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.1-2.8">
|
<dd style="margin-left: 1.5em" id="section-4.2.1-2.6">
|
||||||
<p id="section-4.2.1-2.8.1"><span class="bcp14">REQUIRED</span>. NumericDate. The time at which the ECT was issued.
|
<p id="section-4.2.1-2.6.1"><span class="bcp14">REQUIRED</span>. NumericDate. The time at which the ECT was issued.
|
||||||
The ECT records a completed action, so the "iat" value reflects
|
The ECT records a completed action, so the "iat" value reflects
|
||||||
when the record was created, not when task execution began.<a href="#section-4.2.1-2.8.1" class="pilcrow">¶</a></p>
|
when the record was created, not when task execution began.<a href="#section-4.2.1-2.6.1" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
<dt id="section-4.2.1-2.9">exp:</dt>
|
<dt id="section-4.2.1-2.7">exp:</dt>
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.1-2.10">
|
<dd style="margin-left: 1.5em" id="section-4.2.1-2.8">
|
||||||
<p id="section-4.2.1-2.10.1"><span class="bcp14">REQUIRED</span>. NumericDate. The expiration time of the ECT.
|
<p id="section-4.2.1-2.8.1"><span class="bcp14">REQUIRED</span>. NumericDate. The expiration time of the ECT.
|
||||||
Implementations <span class="bcp14">SHOULD</span> set this to 5 to 15 minutes after "iat"
|
Implementations <span class="bcp14">SHOULD</span> set this to 5 to 15 minutes after "iat"
|
||||||
to limit the replay window while allowing for reasonable clock
|
to limit the replay window while allowing for reasonable clock
|
||||||
skew and processing time.<a href="#section-4.2.1-2.10.1" class="pilcrow">¶</a></p>
|
skew and processing time.<a href="#section-4.2.1-2.8.1" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
</dl>
|
</dl>
|
||||||
@@ -2186,70 +2173,73 @@ multiple root tasks.<a href="#section-4.2.2-2.6.1" class="pilcrow">¶</a></p>
|
|||||||
</div>
|
</div>
|
||||||
<div id="policy-claims">
|
<div id="policy-claims">
|
||||||
<section id="section-4.2.3">
|
<section id="section-4.2.3">
|
||||||
<h4 id="name-policy-evaluation">
|
<h4 id="name-policy-evaluation-extension">
|
||||||
<a href="#section-4.2.3" class="section-number selfRef">4.2.3. </a><a href="#name-policy-evaluation" class="section-name selfRef">Policy Evaluation</a>
|
<a href="#section-4.2.3" class="section-number selfRef">4.2.3. </a><a href="#name-policy-evaluation-extension" class="section-name selfRef">Policy Evaluation Extension Keys</a>
|
||||||
</h4>
|
</h4>
|
||||||
<p id="section-4.2.3-1">The following claims record policy evaluation outcomes:<a href="#section-4.2.3-1" class="pilcrow">¶</a></p>
|
<p id="section-4.2.3-1">Policy evaluation outcomes are recorded as extension keys within
|
||||||
<span class="break"></span><dl class="dlParallel" id="section-4.2.3-2">
|
the "ext" object (<a href="#extension-claims" class="auto internal xref">Section 4.2.6</a>). This keeps the core
|
||||||
<dt id="section-4.2.3-2.1">pol:</dt>
|
registered claims focused on DAG structure and execution context,
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.3-2.2">
|
while allowing deployments to add policy recording as needed.<a href="#section-4.2.3-1" class="pilcrow">¶</a></p>
|
||||||
<p id="section-4.2.3-2.2.1"><span class="bcp14">OPTIONAL</span>. String. The identifier of the policy rule that was
|
<p id="section-4.2.3-2">The following extension keys are defined for policy evaluation:<a href="#section-4.2.3-2" class="pilcrow">¶</a></p>
|
||||||
evaluated for this task (e.g.,
|
<span class="break"></span><dl class="dlParallel" id="section-4.2.3-3">
|
||||||
"clinical_data_access_policy_v1"). <span class="bcp14">MUST</span> be present when
|
<dt id="section-4.2.3-3.1">"pol":</dt>
|
||||||
"pol_decision" is present.<a href="#section-4.2.3-2.2.1" class="pilcrow">¶</a></p>
|
<dd style="margin-left: 1.5em" id="section-4.2.3-3.2">
|
||||||
|
<p id="section-4.2.3-3.2.1">String. The identifier of the policy rule that was evaluated
|
||||||
|
for this task (e.g., "clinical_data_access_policy_v1"). <span class="bcp14">MUST</span>
|
||||||
|
be present when "pol_decision" is present.<a href="#section-4.2.3-3.2.1" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
<dt id="section-4.2.3-2.3">pol_decision:</dt>
|
<dt id="section-4.2.3-3.3">"pol_decision":</dt>
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.3-2.4">
|
<dd style="margin-left: 1.5em" id="section-4.2.3-3.4">
|
||||||
<p id="section-4.2.3-2.4.1"><span class="bcp14">OPTIONAL</span>. String. The result of the policy evaluation. When
|
<p id="section-4.2.3-3.4.1">String. The result of the policy evaluation. When present,
|
||||||
present, <span class="bcp14">MUST</span> be one of the values registered in the ECT Policy
|
<span class="bcp14">MUST</span> be one of the values registered in the ECT Policy Decision
|
||||||
Decision Values registry (<a href="#pol-decision-registry" class="auto internal xref">Section 12.4</a>). <span class="bcp14">MUST</span> be
|
Values registry (<a href="#pol-decision-registry" class="auto internal xref">Section 12.4</a>). <span class="bcp14">MUST</span> be present
|
||||||
present when "pol" is present. Initial values are:<a href="#section-4.2.3-2.4.1" class="pilcrow">¶</a></p>
|
when "pol" is present. Initial values are:<a href="#section-4.2.3-3.4.1" class="pilcrow">¶</a></p>
|
||||||
<ul class="normal">
|
<ul class="normal">
|
||||||
<li class="normal" id="section-4.2.3-2.4.2.1">
|
<li class="normal" id="section-4.2.3-3.4.2.1">
|
||||||
<p id="section-4.2.3-2.4.2.1.1">"approved": The policy evaluation succeeded and the task
|
<p id="section-4.2.3-3.4.2.1.1">"approved": The policy evaluation succeeded and the task
|
||||||
was authorized to proceed.<a href="#section-4.2.3-2.4.2.1.1" class="pilcrow">¶</a></p>
|
was authorized to proceed.<a href="#section-4.2.3-3.4.2.1.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.3-2.4.2.2">
|
<li class="normal" id="section-4.2.3-3.4.2.2">
|
||||||
<p id="section-4.2.3-2.4.2.2.1">"rejected": The policy evaluation failed. A "rejected" ECT
|
<p id="section-4.2.3-3.4.2.2.1">"rejected": The policy evaluation failed. A "rejected" ECT
|
||||||
<span class="bcp14">MUST</span> still be recorded for accountability. An ECT with
|
<span class="bcp14">MUST</span> still be recorded for accountability. An ECT with
|
||||||
"pol_decision" of "rejected" <span class="bcp14">MAY</span> appear as a parent in the
|
"pol_decision" of "rejected" <span class="bcp14">MAY</span> appear as a parent in the
|
||||||
"par" array of a subsequent ECT, but only for compensation,
|
"par" array of a subsequent ECT, but only for compensation,
|
||||||
rollback, or remediation tasks. Agents <span class="bcp14">MUST NOT</span> proceed
|
rollback, or remediation tasks. Agents <span class="bcp14">MUST NOT</span> proceed
|
||||||
with normal workflow execution based on a parent ECT whose
|
with normal workflow execution based on a parent ECT whose
|
||||||
"pol_decision" is "rejected".<a href="#section-4.2.3-2.4.2.2.1" class="pilcrow">¶</a></p>
|
"pol_decision" is "rejected".<a href="#section-4.2.3-3.4.2.2.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.3-2.4.2.3">
|
<li class="normal" id="section-4.2.3-3.4.2.3">
|
||||||
<p id="section-4.2.3-2.4.2.3.1">"pending_human_review": The policy evaluation requires human
|
<p id="section-4.2.3-3.4.2.3.1">"pending_human_review": The policy evaluation requires human
|
||||||
judgment before proceeding. Agents <span class="bcp14">MUST NOT</span> proceed with
|
judgment before proceeding. Agents <span class="bcp14">MUST NOT</span> proceed with
|
||||||
dependent tasks until a subsequent ECT from a human reviewer
|
dependent tasks until a subsequent ECT from a human reviewer
|
||||||
records an "approved" decision referencing this task as a
|
records an "approved" decision referencing this task as a
|
||||||
parent.<a href="#section-4.2.3-2.4.2.3.1" class="pilcrow">¶</a></p>
|
parent.<a href="#section-4.2.3-3.4.2.3.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p id="section-4.2.3-2.4.3">When "pol" and "pol_decision" are absent, the ECT records task
|
<p id="section-4.2.3-3.4.3">When "pol" and "pol_decision" are absent from "ext", the ECT
|
||||||
execution without a policy checkpoint. Regulated deployments
|
records task execution without a policy checkpoint. Regulated
|
||||||
<span class="bcp14">SHOULD</span> include policy claims on all ECTs to maintain complete
|
deployments <span class="bcp14">SHOULD</span> include policy keys on all ECTs to maintain
|
||||||
audit trails.<a href="#section-4.2.3-2.4.3" class="pilcrow">¶</a></p>
|
complete audit trails.<a href="#section-4.2.3-3.4.3" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
<dt id="section-4.2.3-2.5">pol_enforcer:</dt>
|
<dt id="section-4.2.3-3.5">"pol_enforcer":</dt>
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.3-2.6">
|
<dd style="margin-left: 1.5em" id="section-4.2.3-3.6">
|
||||||
<p id="section-4.2.3-2.6.1"><span class="bcp14">OPTIONAL</span>. StringOrURI. The identity of the entity (system or
|
<p id="section-4.2.3-3.6.1">StringOrURI. The identity of the entity (system or person)
|
||||||
person) that evaluated the policy decision. When present,
|
that evaluated the policy decision. When present, <span class="bcp14">SHOULD</span> use
|
||||||
<span class="bcp14">SHOULD</span> use SPIFFE ID format.<a href="#section-4.2.3-2.6.1" class="pilcrow">¶</a></p>
|
SPIFFE ID format.<a href="#section-4.2.3-3.6.1" class="pilcrow">¶</a></p>
|
||||||
</dd>
|
</dd>
|
||||||
<dd class="break"></dd>
|
<dd class="break"></dd>
|
||||||
</dl>
|
</dl>
|
||||||
<p id="section-4.2.3-3">This specification intentionally defines only the recording of
|
<p id="section-4.2.3-4">This specification intentionally defines only the recording of
|
||||||
policy evaluation outcomes. The mechanisms by which policies are
|
policy evaluation outcomes. The mechanisms by which policies are
|
||||||
defined, distributed to agents, and evaluated are out of scope.
|
defined, distributed to agents, and evaluated are out of scope.
|
||||||
The "pol" claim is an opaque identifier referencing an external
|
The "pol" key is an opaque identifier referencing an external
|
||||||
policy; the semantics and enforcement of that policy are
|
policy; the semantics and enforcement of that policy are
|
||||||
determined by the deployment environment. Implementations may
|
determined by the deployment environment. Implementations may
|
||||||
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
|
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
|
||||||
or custom solutions) provided that the evaluation outcome is
|
or custom solutions) provided that the evaluation outcome is
|
||||||
faithfully recorded in the ECT claims defined above.<a href="#section-4.2.3-3" class="pilcrow">¶</a></p>
|
faithfully recorded in the "ext" keys defined above.<a href="#section-4.2.3-4" class="pilcrow">¶</a></p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="data-integrity-claims">
|
<div id="data-integrity-claims">
|
||||||
@@ -2288,31 +2278,12 @@ using the same format and algorithm requirements as "inp_hash".<a href="#section
|
|||||||
<h4 id="name-compensation-and-rollback">
|
<h4 id="name-compensation-and-rollback">
|
||||||
<a href="#section-4.2.5" class="section-number selfRef">4.2.5. </a><a href="#name-compensation-and-rollback" class="section-name selfRef">Compensation and Rollback</a>
|
<a href="#section-4.2.5" class="section-number selfRef">4.2.5. </a><a href="#name-compensation-and-rollback" class="section-name selfRef">Compensation and Rollback</a>
|
||||||
</h4>
|
</h4>
|
||||||
<span class="break"></span><dl class="dlParallel" id="section-4.2.5-1">
|
<p id="section-4.2.5-1">Compensation and rollback actions are recorded using the "par"
|
||||||
<dt id="section-4.2.5-1.1">compensation_required:</dt>
|
claim to reference the original task and the "exec_act" claim to
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.5-1.2">
|
describe the remediation action. The referenced parent ECTs may
|
||||||
<p id="section-4.2.5-1.2.1"><span class="bcp14">OPTIONAL</span>. Boolean. Indicates whether this task is a
|
have passed their own "exp" time; ECT expiration applies to the
|
||||||
compensation or rollback action for a previous task.<a href="#section-4.2.5-1.2.1" class="pilcrow">¶</a></p>
|
verification window of the ECT itself, not to its validity as a
|
||||||
</dd>
|
parent reference in the ECT store.<a href="#section-4.2.5-1" class="pilcrow">¶</a></p>
|
||||||
<dd class="break"></dd>
|
|
||||||
<dt id="section-4.2.5-1.3">compensation_reason:</dt>
|
|
||||||
<dd style="margin-left: 1.5em" id="section-4.2.5-1.4">
|
|
||||||
<p id="section-4.2.5-1.4.1"><span class="bcp14">OPTIONAL</span>. String. A human-readable reason for the compensation
|
|
||||||
action. <span class="bcp14">MUST</span> be present if "compensation_required" is true.
|
|
||||||
Values <span class="bcp14">SHOULD</span> use structured identifiers (e.g.,
|
|
||||||
"policy_violation_in_parent_trade") rather than free-form text
|
|
||||||
to minimize the risk of embedding sensitive information. See
|
|
||||||
<a href="#data-minimization" class="auto internal xref">Section 11.2</a> for privacy guidance.
|
|
||||||
If "compensation_reason" is present, "compensation_required"
|
|
||||||
<span class="bcp14">MUST</span> be true.<a href="#section-4.2.5-1.4.1" class="pilcrow">¶</a></p>
|
|
||||||
</dd>
|
|
||||||
<dd class="break"></dd>
|
|
||||||
</dl>
|
|
||||||
<p id="section-4.2.5-2">Note: compensation ECTs reference historical parent tasks via the
|
|
||||||
"par" claim. The referenced parent ECTs may have passed their own
|
|
||||||
"exp" time; ECT expiration applies to the verification window of
|
|
||||||
the ECT itself, not to its validity as a parent reference in the
|
|
||||||
ledger.<a href="#section-4.2.5-2" class="pilcrow">¶</a></p>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="extension-claims">
|
<div id="extension-claims">
|
||||||
@@ -2340,31 +2311,57 @@ levels. Implementations <span class="bcp14">SHOULD</span> reject ECTs whose "ex
|
|||||||
exceeds these limits.<a href="#section-4.2.6-2" class="pilcrow">¶</a></p>
|
exceeds these limits.<a href="#section-4.2.6-2" class="pilcrow">¶</a></p>
|
||||||
<p id="section-4.2.6-3">The following extension keys are defined by this specification
|
<p id="section-4.2.6-3">The following extension keys are defined by this specification
|
||||||
for common use cases. Because these keys are documented here,
|
for common use cases. Because these keys are documented here,
|
||||||
they use short names without reverse domain prefixes:<a href="#section-4.2.6-3" class="pilcrow">¶</a></p>
|
they use short names without reverse domain prefixes.<a href="#section-4.2.6-3" class="pilcrow">¶</a></p>
|
||||||
|
<p id="section-4.2.6-4">Policy evaluation keys (see <a href="#policy-claims" class="auto internal xref">Section 4.2.3</a> for full
|
||||||
|
definitions and decision value semantics):<a href="#section-4.2.6-4" class="pilcrow">¶</a></p>
|
||||||
<ul class="normal">
|
<ul class="normal">
|
||||||
<li class="normal" id="section-4.2.6-4.1">
|
<li class="normal" id="section-4.2.6-5.1">
|
||||||
<p id="section-4.2.6-4.1.1">"exec_time_ms": Integer. Execution duration in milliseconds.<a href="#section-4.2.6-4.1.1" class="pilcrow">¶</a></p>
|
<p id="section-4.2.6-5.1.1">"pol": String. Policy rule identifier.<a href="#section-4.2.6-5.1.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.6-4.2">
|
<li class="normal" id="section-4.2.6-5.2">
|
||||||
<p id="section-4.2.6-4.2.1">"regulated_domain": String. Regulatory domain (e.g.,
|
<p id="section-4.2.6-5.2.1">"pol_decision": String. Policy evaluation outcome
|
||||||
"medtech", "finance", "military").<a href="#section-4.2.6-4.2.1" class="pilcrow">¶</a></p>
|
("approved", "rejected", or "pending_human_review").<a href="#section-4.2.6-5.2.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.6-4.3">
|
<li class="normal" id="section-4.2.6-5.3">
|
||||||
<p id="section-4.2.6-4.3.1">"model_version": String. AI/ML model version.<a href="#section-4.2.6-4.3.1" class="pilcrow">¶</a></p>
|
<p id="section-4.2.6-5.3.1">"pol_enforcer": StringOrURI. Identity of the policy
|
||||||
|
evaluator.<a href="#section-4.2.6-5.3.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.6-4.4">
|
<li class="normal" id="section-4.2.6-5.4">
|
||||||
<p id="section-4.2.6-4.4.1">"witnessed_by": Array of StringOrURI. Identifiers of
|
<p id="section-4.2.6-5.4.1">"pol_timestamp": NumericDate. Time at which the policy
|
||||||
|
decision was made, if distinct from "iat".<a href="#section-4.2.6-5.4.1" class="pilcrow">¶</a></p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p id="section-4.2.6-6">Operational metadata keys:<a href="#section-4.2.6-6" class="pilcrow">¶</a></p>
|
||||||
|
<ul class="normal">
|
||||||
|
<li class="normal" id="section-4.2.6-7.1">
|
||||||
|
<p id="section-4.2.6-7.1.1">"exec_time_ms": Integer. Execution duration in milliseconds.<a href="#section-4.2.6-7.1.1" class="pilcrow">¶</a></p>
|
||||||
|
</li>
|
||||||
|
<li class="normal" id="section-4.2.6-7.2">
|
||||||
|
<p id="section-4.2.6-7.2.1">"regulated_domain": String. Regulatory domain (e.g.,
|
||||||
|
"medtech", "finance", "military").<a href="#section-4.2.6-7.2.1" class="pilcrow">¶</a></p>
|
||||||
|
</li>
|
||||||
|
<li class="normal" id="section-4.2.6-7.3">
|
||||||
|
<p id="section-4.2.6-7.3.1">"model_version": String. AI/ML model version.<a href="#section-4.2.6-7.3.1" class="pilcrow">¶</a></p>
|
||||||
|
</li>
|
||||||
|
<li class="normal" id="section-4.2.6-7.4">
|
||||||
|
<p id="section-4.2.6-7.4.1">"witnessed_by": Array of StringOrURI. Identifiers of
|
||||||
third-party entities that the issuer claims observed the
|
third-party entities that the issuer claims observed the
|
||||||
task. Note: this is self-asserted; for verifiable witness
|
task. Note: this is self-asserted; for verifiable witness
|
||||||
attestation, witnesses should submit independent signed ECTs.<a href="#section-4.2.6-4.4.1" class="pilcrow">¶</a></p>
|
attestation, witnesses should submit independent signed ECTs.<a href="#section-4.2.6-7.4.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.6-4.5">
|
<li class="normal" id="section-4.2.6-7.5">
|
||||||
<p id="section-4.2.6-4.5.1">"inp_classification": String. Data sensitivity classification
|
<p id="section-4.2.6-7.5.1">"inp_classification": String. Data sensitivity classification
|
||||||
(e.g., "public", "confidential", "restricted").<a href="#section-4.2.6-4.5.1" class="pilcrow">¶</a></p>
|
(e.g., "public", "confidential", "restricted").<a href="#section-4.2.6-7.5.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-4.2.6-4.6">
|
<li class="normal" id="section-4.2.6-7.6">
|
||||||
<p id="section-4.2.6-4.6.1">"pol_timestamp": NumericDate. Time at which the policy
|
<p id="section-4.2.6-7.6.1">"compensation_required": Boolean. Indicates whether this task
|
||||||
decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1" class="pilcrow">¶</a></p>
|
is a compensation or rollback action.<a href="#section-4.2.6-7.6.1" class="pilcrow">¶</a></p>
|
||||||
|
</li>
|
||||||
|
<li class="normal" id="section-4.2.6-7.7">
|
||||||
|
<p id="section-4.2.6-7.7.1">"compensation_reason": String. Structured reason code for the
|
||||||
|
compensation action (e.g., "policy_violation_in_parent_trade").
|
||||||
|
<span class="bcp14">SHOULD</span> use structured identifiers rather than free-form text
|
||||||
|
to minimize information leakage (see <a href="#data-minimization" class="auto internal xref">Section 11.2</a>).<a href="#section-4.2.6-7.7.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
@@ -2383,7 +2380,6 @@ decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1" class="
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/clinical",
|
"iss": "spiffe://example.com/agent/clinical",
|
||||||
"sub": "spiffe://example.com/agent/clinical",
|
|
||||||
"aud": "spiffe://example.com/agent/safety",
|
"aud": "spiffe://example.com/agent/safety",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -2393,14 +2389,13 @@ decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1" class="
|
|||||||
"exec_act": "recommend_treatment",
|
"exec_act": "recommend_treatment",
|
||||||
"par": [],
|
"par": [],
|
||||||
|
|
||||||
"pol": "clinical_reasoning_policy_v2",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
|
|
||||||
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
|
||||||
"ext": {
|
"ext": {
|
||||||
|
"pol": "clinical_reasoning_policy_v2",
|
||||||
|
"pol_decision": "approved",
|
||||||
|
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
|
||||||
"pol_timestamp": 1772064145,
|
"pol_timestamp": 1772064145,
|
||||||
"exec_time_ms": 245,
|
"exec_time_ms": 245,
|
||||||
"regulated_domain": "medtech",
|
"regulated_domain": "medtech",
|
||||||
@@ -2521,15 +2516,14 @@ lead back to the current ECT's "jti". If a cycle is detected,
|
|||||||
the ECT <span class="bcp14">MUST</span> be rejected.<a href="#section-6.2-2.4.1" class="pilcrow">¶</a></p>
|
the ECT <span class="bcp14">MUST</span> be rejected.<a href="#section-6.2-2.4.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="section-6.2-2.5">
|
<li id="section-6.2-2.5">
|
||||||
<p id="section-6.2-2.5.1">Parent Policy Decision: If any parent ECT contains a
|
<p id="section-6.2-2.5.1">Parent Policy Decision: If any parent ECT's "ext" object
|
||||||
"pol_decision" of "rejected" or "pending_human_review", the
|
contains a "pol_decision" of "rejected" or
|
||||||
current ECT's "exec_act" <span class="bcp14">MUST</span> indicate a compensation,
|
"pending_human_review", the current ECT's "exec_act" <span class="bcp14">MUST</span>
|
||||||
rollback, remediation, or human review action.
|
indicate a compensation, rollback, remediation, or human
|
||||||
Implementations <span class="bcp14">MUST NOT</span> accept an ECT representing normal
|
review action. Implementations <span class="bcp14">MUST NOT</span> accept an ECT
|
||||||
workflow continuation when a parent's "pol_decision" is not
|
representing normal workflow continuation when a parent's
|
||||||
"approved", unless the current ECT has "compensation_required"
|
"pol_decision" is not "approved". This rule only applies
|
||||||
set to true. This rule only applies when the parent ECT
|
when the parent ECT's "ext" contains policy keys.<a href="#section-6.2-2.5.1" class="pilcrow">¶</a></p>
|
||||||
contains policy claims.<a href="#section-6.2-2.5.1" class="pilcrow">¶</a></p>
|
|
||||||
</li>
|
</li>
|
||||||
<li id="section-6.2-2.6">
|
<li id="section-6.2-2.6">
|
||||||
<p id="section-6.2-2.6.1">Trust Domain Consistency: Parent tasks <span class="bcp14">SHOULD</span> belong to the
|
<p id="section-6.2-2.6.1">Trust Domain Consistency: Parent tasks <span class="bcp14">SHOULD</span> belong to the
|
||||||
@@ -2678,22 +2672,22 @@ verifier's current time, to account for clock skew).<a href="#section-7.1-2.11.1
|
|||||||
present and well-formed.<a href="#section-7.1-2.12.1" class="pilcrow">¶</a></p>
|
present and well-formed.<a href="#section-7.1-2.12.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="section-7.1-2.13">
|
<li id="section-7.1-2.13">
|
||||||
<p id="section-7.1-2.13.1">If "pol" or "pol_decision" is present, verify that both are
|
<p id="section-7.1-2.13.1">If "ext" is present and contains "pol" or "pol_decision",
|
||||||
present and that "pol_decision" is one of "approved",
|
verify that both are present and that "pol_decision" is one
|
||||||
"rejected", or "pending_human_review".<a href="#section-7.1-2.13.1" class="pilcrow">¶</a></p>
|
of "approved", "rejected", or "pending_human_review".<a href="#section-7.1-2.13.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="section-7.1-2.14">
|
<li id="section-7.1-2.14">
|
||||||
<p id="section-7.1-2.14.1">Perform DAG validation per <a href="#dag-validation" class="auto internal xref">Section 6</a>.<a href="#section-7.1-2.14.1" class="pilcrow">¶</a></p>
|
<p id="section-7.1-2.14.1">Perform DAG validation per <a href="#dag-validation" class="auto internal xref">Section 6</a>.<a href="#section-7.1-2.14.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="section-7.1-2.15">
|
<li id="section-7.1-2.15">
|
||||||
<p id="section-7.1-2.15.1">If all checks pass, the ECT <span class="bcp14">MUST</span> be appended to the audit
|
<p id="section-7.1-2.15.1">If all checks pass and an audit ledger is deployed, the ECT
|
||||||
ledger.<a href="#section-7.1-2.15.1" class="pilcrow">¶</a></p>
|
<span class="bcp14">SHOULD</span> be appended to the ledger.<a href="#section-7.1-2.15.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p id="section-7.1-3">If any verification step fails, the ECT <span class="bcp14">MUST</span> be rejected and the
|
<p id="section-7.1-3">If any verification step fails, the ECT <span class="bcp14">MUST</span> be rejected and the
|
||||||
failure <span class="bcp14">MUST</span> be logged for audit purposes. Error messages
|
failure <span class="bcp14">MUST</span> be logged for audit purposes. Error messages
|
||||||
<span class="bcp14">SHOULD NOT</span> reveal whether specific parent task IDs exist in the
|
<span class="bcp14">SHOULD NOT</span> reveal whether specific parent task IDs exist in the
|
||||||
ledger, to prevent information disclosure.<a href="#section-7.1-3" class="pilcrow">¶</a></p>
|
ECT store, to prevent information disclosure.<a href="#section-7.1-3" class="pilcrow">¶</a></p>
|
||||||
<p id="section-7.1-4">When ECT verification fails during HTTP request processing, the
|
<p id="section-7.1-4">When ECT verification fails during HTTP request processing, the
|
||||||
receiving agent <span class="bcp14">SHOULD</span> respond with HTTP 403 (Forbidden) if the
|
receiving agent <span class="bcp14">SHOULD</span> respond with HTTP 403 (Forbidden) if the
|
||||||
WIT is valid but the ECT is invalid, and HTTP 401
|
WIT is valid but the ECT is invalid, and HTTP 401
|
||||||
@@ -2767,11 +2761,12 @@ function verify_ect(ect_jws, verifier_id,
|
|||||||
if claim not in payload:
|
if claim not in payload:
|
||||||
return reject("Missing required claim: " + claim)
|
return reject("Missing required claim: " + claim)
|
||||||
|
|
||||||
// Validate policy claims (optional, but must be paired)
|
// Validate policy extension keys (optional, but must be paired)
|
||||||
if "pol" in payload or "pol_decision" in payload:
|
ext = payload.ext or {}
|
||||||
if "pol" not in payload or "pol_decision" not in payload:
|
if "pol" in ext or "pol_decision" in ext:
|
||||||
|
if "pol" not in ext or "pol_decision" not in ext:
|
||||||
return reject("pol and pol_decision must both be present")
|
return reject("pol and pol_decision must both be present")
|
||||||
if payload.pol_decision not in
|
if ext.pol_decision not in
|
||||||
["approved", "rejected", "pending_human_review"]:
|
["approved", "rejected", "pending_human_review"]:
|
||||||
return reject("Invalid pol_decision value")
|
return reject("Invalid pol_decision value")
|
||||||
|
|
||||||
@@ -2862,29 +2857,34 @@ software used in medical devices.<a href="#section-9.1-1" class="pilcrow">¶</a>
|
|||||||
Agent A (Spec Reviewer):
|
Agent A (Spec Reviewer):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: review_requirements_spec
|
exec_act: review_requirements_spec
|
||||||
pol: spec_review_policy_v2 pol_decision: approved
|
ext.pol: spec_review_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Code Generator):
|
Agent B (Code Generator):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: implement_module
|
exec_act: implement_module
|
||||||
pol: coding_standards_v3 pol_decision: approved
|
ext.pol: coding_standards_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Test Agent):
|
Agent C (Test Agent):
|
||||||
jti: task-003 par: [task-002]
|
jti: task-003 par: [task-002]
|
||||||
exec_act: execute_test_suite
|
exec_act: execute_test_suite
|
||||||
pol: test_coverage_policy_v1 pol_decision: approved
|
ext.pol: test_coverage_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent D (Build Agent):
|
Agent D (Build Agent):
|
||||||
jti: task-004 par: [task-003]
|
jti: task-004 par: [task-003]
|
||||||
exec_act: build_release_artifact
|
exec_act: build_release_artifact
|
||||||
pol: build_validation_v2 pol_decision: approved
|
ext.pol: build_validation_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Human Release Manager:
|
Human Release Manager:
|
||||||
jti: task-005 par: [task-004]
|
jti: task-005 par: [task-004]
|
||||||
exec_act: approve_release
|
exec_act: approve_release
|
||||||
pol: release_approval_policy pol_decision: approved
|
ext.pol: release_approval_policy
|
||||||
pol_enforcer: spiffe://meddev.example/human/release-mgr-42
|
ext.pol_decision: approved
|
||||||
ext: {witnessed_by: [...]} (extension metadata)
|
ext.pol_enforcer: spiffe://meddev.example/human/release-mgr-42
|
||||||
|
ext.witnessed_by: [...]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<figcaption><a href="#figure-8" class="selfRef">Figure 8</a>:
|
<figcaption><a href="#figure-8" class="selfRef">Figure 8</a>:
|
||||||
@@ -2987,17 +2987,20 @@ execution.<a href="#section-9.2-1" class="pilcrow">¶</a></p>
|
|||||||
Agent A (Risk Assessment):
|
Agent A (Risk Assessment):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: calculate_risk_exposure
|
exec_act: calculate_risk_exposure
|
||||||
pol: risk_limits_policy_v2 pol_decision: approved
|
ext.pol: risk_limits_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Compliance):
|
Agent B (Compliance):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: verify_compliance
|
exec_act: verify_compliance
|
||||||
pol: compliance_check_v1 pol_decision: approved
|
ext.pol: compliance_check_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Execution):
|
Agent C (Execution):
|
||||||
jti: task-003 par: [task-002]
|
jti: task-003 par: [task-002]
|
||||||
exec_act: execute_trade
|
exec_act: execute_trade
|
||||||
pol: execution_policy_v3 pol_decision: approved
|
ext.pol: execution_policy_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<figcaption><a href="#figure-10" class="selfRef">Figure 10</a>:
|
<figcaption><a href="#figure-10" class="selfRef">Figure 10</a>:
|
||||||
@@ -3034,7 +3037,6 @@ a cryptographic link to the original task:<a href="#section-9.3-1" class="pilcro
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://bank.example/agent/operations",
|
"iss": "spiffe://bank.example/agent/operations",
|
||||||
"sub": "spiffe://bank.example/agent/operations",
|
|
||||||
"aud": "spiffe://bank.example/system/ledger",
|
"aud": "spiffe://bank.example/system/ledger",
|
||||||
"iat": 1772150550,
|
"iat": 1772150550,
|
||||||
"exp": 1772151150,
|
"exp": 1772151150,
|
||||||
@@ -3042,11 +3044,13 @@ a cryptographic link to the original task:<a href="#section-9.3-1" class="pilcro
|
|||||||
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
|
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
|
||||||
"exec_act": "initiate_trade_rollback",
|
"exec_act": "initiate_trade_rollback",
|
||||||
"par": ["550e8400-e29b-41d4-a716-446655440003"],
|
"par": ["550e8400-e29b-41d4-a716-446655440003"],
|
||||||
"pol": "compensation_policy_v1",
|
"ext": {
|
||||||
"pol_decision": "approved",
|
"pol": "compensation_policy_v1",
|
||||||
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
|
"pol_decision": "approved",
|
||||||
"compensation_required": true,
|
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
|
||||||
"compensation_reason": "policy_violation_in_parent_trade"
|
"compensation_required": true,
|
||||||
|
"compensation_reason": "policy_violation_in_parent_trade"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
@@ -3074,27 +3078,32 @@ required checks were completed:<a href="#section-9.4-1" class="pilcrow">¶</a></
|
|||||||
Agent A (Route Planning):
|
Agent A (Route Planning):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: plan_route
|
exec_act: plan_route
|
||||||
pol: route_policy_v1 pol_decision: approved
|
ext.pol: route_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Customs):
|
Agent B (Customs):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: validate_customs
|
exec_act: validate_customs
|
||||||
pol: customs_policy_v2 pol_decision: approved
|
ext.pol: customs_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Safety):
|
Agent C (Safety):
|
||||||
jti: task-003 par: [task-001]
|
jti: task-003 par: [task-001]
|
||||||
exec_act: verify_cargo_safety
|
exec_act: verify_cargo_safety
|
||||||
pol: safety_policy_v1 pol_decision: approved
|
ext.pol: safety_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent D (Payment):
|
Agent D (Payment):
|
||||||
jti: task-004 par: [task-002, task-003]
|
jti: task-004 par: [task-002, task-003]
|
||||||
exec_act: authorize_payment
|
exec_act: authorize_payment
|
||||||
pol: payment_policy_v3 pol_decision: approved
|
ext.pol: payment_policy_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
System (Commitment):
|
System (Commitment):
|
||||||
jti: task-005 par: [task-004]
|
jti: task-005 par: [task-004]
|
||||||
exec_act: commit_shipment
|
exec_act: commit_shipment
|
||||||
pol: commitment_policy_v1 pol_decision: approved
|
ext.pol: commitment_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<figcaption><a href="#figure-12" class="selfRef">Figure 12</a>:
|
<figcaption><a href="#figure-12" class="selfRef">Figure 12</a>:
|
||||||
@@ -3149,8 +3158,8 @@ to alter perceived execution ordering.<a href="#section-10.1-2.4.1" class="pilcr
|
|||||||
<p id="section-10.2-1">ECTs are self-asserted by the executing agent. The agent claims
|
<p id="section-10.2-1">ECTs are self-asserted by the executing agent. The agent claims
|
||||||
what it did, and this claim is signed with its private key. A
|
what it did, and this claim is signed with its private key. A
|
||||||
compromised or malicious agent could create ECTs with false claims
|
compromised or malicious agent could create ECTs with false claims
|
||||||
(e.g., setting "pol_decision" to "approved" without actually
|
(e.g., setting "pol_decision" in "ext" to "approved" without
|
||||||
evaluating the policy).<a href="#section-10.2-1" class="pilcrow">¶</a></p>
|
actually evaluating the policy).<a href="#section-10.2-1" class="pilcrow">¶</a></p>
|
||||||
<p id="section-10.2-2">ECTs do not independently verify that:<a href="#section-10.2-2" class="pilcrow">¶</a></p>
|
<p id="section-10.2-2">ECTs do not independently verify that:<a href="#section-10.2-2" class="pilcrow">¶</a></p>
|
||||||
<ul class="normal">
|
<ul class="normal">
|
||||||
<li class="normal" id="section-10.2-3.1">
|
<li class="normal" id="section-10.2-3.1">
|
||||||
@@ -3176,44 +3185,11 @@ witnesses do not co-sign the ECT and there is no cryptographic
|
|||||||
evidence within a single ECT that the witnesses actually
|
evidence within a single ECT that the witnesses actually
|
||||||
observed the task. An issuing agent could list witnesses that
|
observed the task. An issuing agent could list witnesses that
|
||||||
did not participate.<a href="#section-10.2-4" class="pilcrow">¶</a></p>
|
did not participate.<a href="#section-10.2-4" class="pilcrow">¶</a></p>
|
||||||
<div id="witness-attestation-model">
|
<p id="section-10.2-5">To strengthen witness attestation beyond self-assertion, witnesses
|
||||||
<section id="section-10.2.1">
|
<span class="bcp14">SHOULD</span> submit their own independent signed ECTs referencing the
|
||||||
<h4 id="name-witness-attestation-model">
|
observed task's "jti" in the "par" array. Auditors can then
|
||||||
<a href="#section-10.2.1" class="section-number selfRef">10.2.1. </a><a href="#name-witness-attestation-model" class="section-name selfRef">Witness Attestation Model</a>
|
cross-check the "witnessed_by" extension against independent
|
||||||
</h4>
|
witness ECTs in the ECT store.<a href="#section-10.2-5" class="pilcrow">¶</a></p>
|
||||||
<p id="section-10.2.1-1">To address the self-assertion limitation of the
|
|
||||||
"witnessed_by" extension, witnesses <span class="bcp14">SHOULD</span> submit their
|
|
||||||
own independent signed ECTs to the audit ledger attesting to the
|
|
||||||
observed task. A witness attestation ECT:<a href="#section-10.2.1-1" class="pilcrow">¶</a></p>
|
|
||||||
<ul class="normal">
|
|
||||||
<li class="normal" id="section-10.2.1-2.1">
|
|
||||||
<p id="section-10.2.1-2.1.1"><span class="bcp14">MUST</span> set "iss" to the witness's own workload identity.<a href="#section-10.2.1-2.1.1" class="pilcrow">¶</a></p>
|
|
||||||
</li>
|
|
||||||
<li class="normal" id="section-10.2.1-2.2">
|
|
||||||
<p id="section-10.2.1-2.2.1"><span class="bcp14">MUST</span> set "exec_act" to "witness_attestation" (or a domain-
|
|
||||||
specific equivalent).<a href="#section-10.2.1-2.2.1" class="pilcrow">¶</a></p>
|
|
||||||
</li>
|
|
||||||
<li class="normal" id="section-10.2.1-2.3">
|
|
||||||
<p id="section-10.2.1-2.3.1"><span class="bcp14">MUST</span> include the observed task's "jti" in the "par" array,
|
|
||||||
linking the attestation to the original task.<a href="#section-10.2.1-2.3.1" class="pilcrow">¶</a></p>
|
|
||||||
</li>
|
|
||||||
<li class="normal" id="section-10.2.1-2.4">
|
|
||||||
<p id="section-10.2.1-2.4.1"><span class="bcp14">MUST</span> set "pol_decision" to "approved" to indicate the witness
|
|
||||||
confirms the observation.<a href="#section-10.2.1-2.4.1" class="pilcrow">¶</a></p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p id="section-10.2.1-3">When a task's "witnessed_by" extension lists one or more
|
|
||||||
witnesses, auditors <span class="bcp14">SHOULD</span> verify that corresponding witness
|
|
||||||
attestation ECTs exist in the ledger for each listed witness. A
|
|
||||||
mismatch between the extension value and the set of independent
|
|
||||||
witness ECTs in the ledger <span class="bcp14">SHOULD</span> be flagged during audit review.<a href="#section-10.2.1-3" class="pilcrow">¶</a></p>
|
|
||||||
<p id="section-10.2.1-4">This model converts witness attestation from a self-asserted claim
|
|
||||||
to a cryptographically verifiable property of the ledger: the
|
|
||||||
witness independently signs their own ECT using their own key,
|
|
||||||
and the ledger records both the original task ECT and the witness
|
|
||||||
attestation ECTs.<a href="#section-10.2.1-4" class="pilcrow">¶</a></p>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="organizational-prerequisites">
|
<div id="organizational-prerequisites">
|
||||||
@@ -3439,8 +3415,8 @@ serialized as JSON and <span class="bcp14">SHOULD NOT</span> exceed a nesting de
|
|||||||
<p id="section-11.1-2.2.1">Action descriptions ("exec_act") for audit trail completeness<a href="#section-11.1-2.2.1" class="pilcrow">¶</a></p>
|
<p id="section-11.1-2.2.1">Action descriptions ("exec_act") for audit trail completeness<a href="#section-11.1-2.2.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-11.1-2.3">
|
<li class="normal" id="section-11.1-2.3">
|
||||||
<p id="section-11.1-2.3.1">Policy evaluation outcomes ("pol", "pol_decision") for
|
<p id="section-11.1-2.3.1">Policy evaluation outcomes (via "ext" keys "pol",
|
||||||
compliance verification<a href="#section-11.1-2.3.1" class="pilcrow">¶</a></p>
|
"pol_decision") when present, for compliance verification<a href="#section-11.1-2.3.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="normal" id="section-11.1-2.4">
|
<li class="normal" id="section-11.1-2.4">
|
||||||
<p id="section-11.1-2.4.1">Timestamps ("iat", "exp") for temporal ordering<a href="#section-11.1-2.4.1" class="pilcrow">¶</a></p>
|
<p id="section-11.1-2.4.1">Timestamps ("iat", "exp") for temporal ordering<a href="#section-11.1-2.4.1" class="pilcrow">¶</a></p>
|
||||||
@@ -3472,17 +3448,13 @@ hashes via "inp_hash" and "out_hash")<a href="#section-11.1-4.1.1" class="pilcro
|
|||||||
<p id="section-11.2-1">Implementations <span class="bcp14">SHOULD</span> minimize the information included in ECTs.
|
<p id="section-11.2-1">Implementations <span class="bcp14">SHOULD</span> minimize the information included in ECTs.
|
||||||
The "exec_act" claim <span class="bcp14">SHOULD</span> use structured identifiers (e.g.,
|
The "exec_act" claim <span class="bcp14">SHOULD</span> use structured identifiers (e.g.,
|
||||||
"process_payment") rather than natural language descriptions.
|
"process_payment") rather than natural language descriptions.
|
||||||
The "pol" claim <span class="bcp14">SHOULD</span> reference policy identifiers rather than
|
The "pol" extension key <span class="bcp14">SHOULD</span> reference policy identifiers
|
||||||
embedding policy content.<a href="#section-11.2-1" class="pilcrow">¶</a></p>
|
rather than embedding policy content.<a href="#section-11.2-1" class="pilcrow">¶</a></p>
|
||||||
<p id="section-11.2-2">The "compensation_reason" claim (<a href="#compensation-claims" class="auto internal xref">Section 4.2.5</a>)
|
<p id="section-11.2-2">The "compensation_reason" extension key in "ext"
|
||||||
deserves particular attention: because it is human-readable and
|
(<a href="#compensation-claims" class="auto internal xref">Section 4.2.5</a>) deserves particular attention: because
|
||||||
may describe the circumstances of a failure or policy violation,
|
it is human-readable, it risks exposing sensitive operational
|
||||||
it risks exposing sensitive operational details. Implementations
|
details. See <a href="#extension-claims" class="auto internal xref">Section 4.2.6</a> for guidance on using
|
||||||
<span class="bcp14">SHOULD</span> use short, structured reason codes (e.g.,
|
structured identifiers.<a href="#section-11.2-2" class="pilcrow">¶</a></p>
|
||||||
"policy_violation_in_parent_trade") rather than free-form
|
|
||||||
natural language explanations. Implementers <span class="bcp14">SHOULD</span> review
|
|
||||||
"compensation_reason" values for potential information leakage
|
|
||||||
before deploying to production.<a href="#section-11.2-2" class="pilcrow">¶</a></p>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="storage-and-access-control">
|
<div id="storage-and-access-control">
|
||||||
@@ -3680,30 +3652,6 @@ the "JSON Web Token Claims" registry maintained by IANA:<a href="#section-12.3-1
|
|||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
<td class="text-center" rowspan="1" colspan="1">
|
||||||
<a href="#exec-claims" class="auto internal xref">Section 4.2.2</a>
|
<a href="#exec-claims" class="auto internal xref">Section 4.2.2</a>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">pol</td>
|
|
||||||
<td class="text-left" rowspan="1" colspan="1">Policy Rule Identifier</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
|
||||||
<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">pol_decision</td>
|
|
||||||
<td class="text-left" rowspan="1" colspan="1">Policy Decision Result</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
|
||||||
<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">pol_enforcer</td>
|
|
||||||
<td class="text-left" rowspan="1" colspan="1">Policy Enforcer Identity</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
|
||||||
<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -3720,22 +3668,6 @@ the "JSON Web Token Claims" registry maintained by IANA:<a href="#section-12.3-1
|
|||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
<td class="text-center" rowspan="1" colspan="1">
|
||||||
<a href="#data-integrity-claims" class="auto internal xref">Section 4.2.4</a>
|
<a href="#data-integrity-claims" class="auto internal xref">Section 4.2.4</a>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">compensation_required</td>
|
|
||||||
<td class="text-left" rowspan="1" colspan="1">Compensation Flag</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
|
||||||
<a href="#compensation-claims" class="auto internal xref">Section 4.2.5</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">compensation_reason</td>
|
|
||||||
<td class="text-left" rowspan="1" colspan="1">Compensation Reason</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">IETF</td>
|
|
||||||
<td class="text-center" rowspan="1" colspan="1">
|
|
||||||
<a href="#compensation-claims" class="auto internal xref">Section 4.2.5</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -3749,6 +3681,10 @@ the "JSON Web Token Claims" registry maintained by IANA:<a href="#section-12.3-1
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<p id="section-12.3-3">Note: Policy evaluation keys ("pol", "pol_decision",
|
||||||
|
"pol_enforcer") are carried within the "ext" object as
|
||||||
|
spec-defined extension keys (<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>) and do not
|
||||||
|
require separate JWT Claims registration.<a href="#section-12.3-3" class="pilcrow">¶</a></p>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div id="pol-decision-registry">
|
<div id="pol-decision-registry">
|
||||||
@@ -4101,8 +4037,9 @@ use cases are distinct.<a href="#appendix-A.7-1" class="pilcrow">¶</a></p>
|
|||||||
<ol start="1" type="1" class="normal type-1" id="appendix-B.1-2">
|
<ol start="1" type="1" class="normal type-1" id="appendix-B.1-2">
|
||||||
<li id="appendix-B.1-2.1">
|
<li id="appendix-B.1-2.1">
|
||||||
<p id="appendix-B.1-2.1.1">Create JWTs with all required claims ("iss", "aud", "iat",
|
<p id="appendix-B.1-2.1.1">Create JWTs with all required claims ("iss", "aud", "iat",
|
||||||
"exp", "jti", "exec_act", "par") and policy claims ("pol",
|
"exp", "jti", "exec_act", "par") and policy extension keys
|
||||||
"pol_decision") when policy evaluation was performed.<a href="#appendix-B.1-2.1.1" class="pilcrow">¶</a></p>
|
("ext.pol", "ext.pol_decision") when policy evaluation was
|
||||||
|
performed.<a href="#appendix-B.1-2.1.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="appendix-B.1-2.2">
|
<li id="appendix-B.1-2.2">
|
||||||
<p id="appendix-B.1-2.2.1">Sign ECTs with the agent's private key using an algorithm
|
<p id="appendix-B.1-2.2.1">Sign ECTs with the agent's private key using an algorithm
|
||||||
@@ -4116,7 +4053,7 @@ matching the WIT (ES256 recommended).<a href="#appendix-B.1-2.2.1" class="pilcro
|
|||||||
cycle detection).<a href="#appendix-B.1-2.4.1" class="pilcrow">¶</a></p>
|
cycle detection).<a href="#appendix-B.1-2.4.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="appendix-B.1-2.5">
|
<li id="appendix-B.1-2.5">
|
||||||
<p id="appendix-B.1-2.5.1">Append verified ECTs to the audit ledger.<a href="#appendix-B.1-2.5.1" class="pilcrow">¶</a></p>
|
<p id="appendix-B.1-2.5.1">If an audit ledger is deployed, append verified ECTs to it.<a href="#appendix-B.1-2.5.1" class="pilcrow">¶</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</section>
|
</section>
|
||||||
@@ -4269,7 +4206,6 @@ Agent B:<a href="#appendix-D.1-1" class="pilcrow">¶</a></p>
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/data-retrieval",
|
"iss": "spiffe://example.com/agent/data-retrieval",
|
||||||
"sub": "spiffe://example.com/agent/data-retrieval",
|
|
||||||
"aud": "spiffe://example.com/agent/validator",
|
"aud": "spiffe://example.com/agent/validator",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -4277,10 +4213,12 @@ Agent B:<a href="#appendix-D.1-1" class="pilcrow">¶</a></p>
|
|||||||
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
||||||
"exec_act": "fetch_patient_data",
|
"exec_act": "fetch_patient_data",
|
||||||
"par": [],
|
"par": [],
|
||||||
"pol": "clinical_data_access_policy_v1",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
"ext": {
|
||||||
|
"pol": "clinical_data_access_policy_v1",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.1-5" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.1-5" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4290,7 +4228,6 @@ task, and creates its own ECT:<a href="#appendix-D.1-6" class="pilcrow">¶</a></
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/validator",
|
"iss": "spiffe://example.com/agent/validator",
|
||||||
"sub": "spiffe://example.com/agent/validator",
|
|
||||||
"aud": "spiffe://example.com/system/ledger",
|
"aud": "spiffe://example.com/system/ledger",
|
||||||
"iat": 1772064160,
|
"iat": 1772064160,
|
||||||
"exp": 1772064760,
|
"exp": 1772064760,
|
||||||
@@ -4298,8 +4235,10 @@ task, and creates its own ECT:<a href="#appendix-D.1-6" class="pilcrow">¶</a></
|
|||||||
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
||||||
"exec_act": "validate_safety",
|
"exec_act": "validate_safety",
|
||||||
"par": ["550e8400-e29b-41d4-a716-446655440001"],
|
"par": ["550e8400-e29b-41d4-a716-446655440001"],
|
||||||
"pol": "safety_validation_policy_v2",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "safety_validation_policy_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.1-7" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.1-7" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4326,7 +4265,6 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/spec-reviewer",
|
"iss": "spiffe://meddev.example/agent/spec-reviewer",
|
||||||
"sub": "spiffe://meddev.example/agent/spec-reviewer",
|
|
||||||
"aud": "spiffe://meddev.example/agent/code-gen",
|
"aud": "spiffe://meddev.example/agent/code-gen",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -4334,10 +4272,12 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "review_requirements_spec",
|
"exec_act": "review_requirements_spec",
|
||||||
"par": [],
|
"par": [],
|
||||||
"pol": "spec_review_policy_v2",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
"ext": {
|
||||||
|
"pol": "spec_review_policy_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.2-3" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.2-3" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4346,7 +4286,6 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/code-gen",
|
"iss": "spiffe://meddev.example/agent/code-gen",
|
||||||
"sub": "spiffe://meddev.example/agent/code-gen",
|
|
||||||
"aud": "spiffe://meddev.example/agent/test-runner",
|
"aud": "spiffe://meddev.example/agent/test-runner",
|
||||||
"iat": 1772064200,
|
"iat": 1772064200,
|
||||||
"exp": 1772064800,
|
"exp": 1772064800,
|
||||||
@@ -4354,8 +4293,10 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "implement_module",
|
"exec_act": "implement_module",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
|
||||||
"pol": "coding_standards_v3",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "coding_standards_v3",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.2-5" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.2-5" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4364,7 +4305,6 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/test-runner",
|
"iss": "spiffe://meddev.example/agent/test-runner",
|
||||||
"sub": "spiffe://meddev.example/agent/test-runner",
|
|
||||||
"aud": "spiffe://meddev.example/agent/build",
|
"aud": "spiffe://meddev.example/agent/build",
|
||||||
"iat": 1772064260,
|
"iat": 1772064260,
|
||||||
"exp": 1772064860,
|
"exp": 1772064860,
|
||||||
@@ -4372,8 +4312,10 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "execute_test_suite",
|
"exec_act": "execute_test_suite",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
|
||||||
"pol": "test_coverage_policy_v1",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "test_coverage_policy_v1",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.2-7" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.2-7" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4382,7 +4324,6 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/build",
|
"iss": "spiffe://meddev.example/agent/build",
|
||||||
"sub": "spiffe://meddev.example/agent/build",
|
|
||||||
"aud": "spiffe://meddev.example/human/release-mgr-42",
|
"aud": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"iat": 1772064310,
|
"iat": 1772064310,
|
||||||
"exp": 1772064910,
|
"exp": 1772064910,
|
||||||
@@ -4390,9 +4331,11 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "build_release_artifact",
|
"exec_act": "build_release_artifact",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
|
||||||
"pol": "build_validation_v2",
|
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc",
|
||||||
"pol_decision": "approved",
|
"ext": {
|
||||||
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc"
|
"pol": "build_validation_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.2-9" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.2-9" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -4401,7 +4344,6 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/human/release-mgr-42",
|
"iss": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"sub": "spiffe://meddev.example/human/release-mgr-42",
|
|
||||||
"aud": "spiffe://meddev.example/system/ledger",
|
"aud": "spiffe://meddev.example/system/ledger",
|
||||||
"iat": 1772064510,
|
"iat": 1772064510,
|
||||||
"exp": 1772065110,
|
"exp": 1772065110,
|
||||||
@@ -4409,10 +4351,10 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "approve_release",
|
"exec_act": "approve_release",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
|
||||||
"pol": "release_approval_policy",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
|
|
||||||
"ext": {
|
"ext": {
|
||||||
|
"pol": "release_approval_policy",
|
||||||
|
"pol_decision": "approved",
|
||||||
|
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"witnessed_by": [
|
"witnessed_by": [
|
||||||
"spiffe://meddev.example/audit/qa-observer-1"
|
"spiffe://meddev.example/audit/qa-observer-1"
|
||||||
]
|
]
|
||||||
@@ -4474,7 +4416,6 @@ task-...-0004 (execute_trade)
|
|||||||
<pre>
|
<pre>
|
||||||
{
|
{
|
||||||
"iss": "spiffe://bank.example/agent/execution",
|
"iss": "spiffe://bank.example/agent/execution",
|
||||||
"sub": "spiffe://bank.example/agent/execution",
|
|
||||||
"aud": "spiffe://bank.example/system/ledger",
|
"aud": "spiffe://bank.example/system/ledger",
|
||||||
"iat": 1772064250,
|
"iat": 1772064250,
|
||||||
"exp": 1772064850,
|
"exp": 1772064850,
|
||||||
@@ -4485,8 +4426,10 @@ task-...-0004 (execute_trade)
|
|||||||
"f1e2d3c4-0002-0000-0000-000000000002",
|
"f1e2d3c4-0002-0000-0000-000000000002",
|
||||||
"f1e2d3c4-0003-0000-0000-000000000003"
|
"f1e2d3c4-0003-0000-0000-000000000003"
|
||||||
],
|
],
|
||||||
"pol": "trade_execution_policy_v3",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "trade_execution_policy_v3",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre><a href="#appendix-D.3-4" class="pilcrow">¶</a>
|
</pre><a href="#appendix-D.3-4" class="pilcrow">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ This document defines:
|
|||||||
|
|
||||||
- The Execution Context Token (ECT) format ({{ect-format}})
|
- The Execution Context Token (ECT) format ({{ect-format}})
|
||||||
- DAG structure for task dependency ordering ({{dag-validation}})
|
- DAG structure for task dependency ordering ({{dag-validation}})
|
||||||
- Policy checkpoint recording ({{policy-claims}})
|
- Policy checkpoint recording via extension keys ({{policy-claims}})
|
||||||
- Integration with the WIMSE identity framework
|
- Integration with the WIMSE identity framework
|
||||||
({{wimse-integration}})
|
({{wimse-integration}})
|
||||||
- An HTTP header for ECT transport ({{http-header}})
|
- An HTTP header for ECT transport ({{http-header}})
|
||||||
@@ -403,12 +403,6 @@ iss:
|
|||||||
deployments MAY use other URI schemes (e.g., HTTPS URLs or
|
deployments MAY use other URI schemes (e.g., HTTPS URLs or
|
||||||
URN:UUID identifiers).
|
URN:UUID identifiers).
|
||||||
|
|
||||||
sub:
|
|
||||||
: OPTIONAL. StringOrURI. The subject of the ECT. When present,
|
|
||||||
MUST equal the "iss" claim. This claim is included for
|
|
||||||
compatibility with JWT libraries and frameworks that expect a
|
|
||||||
"sub" claim to be present.
|
|
||||||
|
|
||||||
aud:
|
aud:
|
||||||
: REQUIRED. StringOrURI or array of StringOrURI. The intended
|
: REQUIRED. StringOrURI or array of StringOrURI. The intended
|
||||||
recipient(s) of the ECT. Because ECTs serve as both inter-agent
|
recipient(s) of the ECT. Because ECTs serve as both inter-agent
|
||||||
@@ -489,21 +483,25 @@ par:
|
|||||||
a root task with no dependencies. A workflow MAY contain
|
a root task with no dependencies. A workflow MAY contain
|
||||||
multiple root tasks.
|
multiple root tasks.
|
||||||
|
|
||||||
### Policy Evaluation {#policy-claims}
|
### Policy Evaluation Extension Keys {#policy-claims}
|
||||||
|
|
||||||
The following claims record policy evaluation outcomes:
|
Policy evaluation outcomes are recorded as extension keys within
|
||||||
|
the "ext" object ({{extension-claims}}). This keeps the core
|
||||||
|
registered claims focused on DAG structure and execution context,
|
||||||
|
while allowing deployments to add policy recording as needed.
|
||||||
|
|
||||||
pol:
|
The following extension keys are defined for policy evaluation:
|
||||||
: OPTIONAL. String. The identifier of the policy rule that was
|
|
||||||
evaluated for this task (e.g.,
|
|
||||||
"clinical_data_access_policy_v1"). MUST be present when
|
|
||||||
"pol_decision" is present.
|
|
||||||
|
|
||||||
pol_decision:
|
"pol":
|
||||||
: OPTIONAL. String. The result of the policy evaluation. When
|
: String. The identifier of the policy rule that was evaluated
|
||||||
present, MUST be one of the values registered in the ECT Policy
|
for this task (e.g., "clinical_data_access_policy_v1"). MUST
|
||||||
Decision Values registry ({{pol-decision-registry}}). MUST be
|
be present when "pol_decision" is present.
|
||||||
present when "pol" is present. Initial values are:
|
|
||||||
|
"pol_decision":
|
||||||
|
: String. The result of the policy evaluation. When present,
|
||||||
|
MUST be one of the values registered in the ECT Policy Decision
|
||||||
|
Values registry ({{pol-decision-registry}}). MUST be present
|
||||||
|
when "pol" is present. Initial values are:
|
||||||
|
|
||||||
* "approved": The policy evaluation succeeded and the task
|
* "approved": The policy evaluation succeeded and the task
|
||||||
was authorized to proceed.
|
was authorized to proceed.
|
||||||
@@ -522,25 +520,25 @@ pol_decision:
|
|||||||
records an "approved" decision referencing this task as a
|
records an "approved" decision referencing this task as a
|
||||||
parent.
|
parent.
|
||||||
|
|
||||||
When "pol" and "pol_decision" are absent, the ECT records task
|
When "pol" and "pol_decision" are absent from "ext", the ECT
|
||||||
execution without a policy checkpoint. Regulated deployments
|
records task execution without a policy checkpoint. Regulated
|
||||||
SHOULD include policy claims on all ECTs to maintain complete
|
deployments SHOULD include policy keys on all ECTs to maintain
|
||||||
audit trails.
|
complete audit trails.
|
||||||
|
|
||||||
pol_enforcer:
|
"pol_enforcer":
|
||||||
: OPTIONAL. StringOrURI. The identity of the entity (system or
|
: StringOrURI. The identity of the entity (system or person)
|
||||||
person) that evaluated the policy decision. When present,
|
that evaluated the policy decision. When present, SHOULD use
|
||||||
SHOULD use SPIFFE ID format.
|
SPIFFE ID format.
|
||||||
|
|
||||||
This specification intentionally defines only the recording of
|
This specification intentionally defines only the recording of
|
||||||
policy evaluation outcomes. The mechanisms by which policies are
|
policy evaluation outcomes. The mechanisms by which policies are
|
||||||
defined, distributed to agents, and evaluated are out of scope.
|
defined, distributed to agents, and evaluated are out of scope.
|
||||||
The "pol" claim is an opaque identifier referencing an external
|
The "pol" key is an opaque identifier referencing an external
|
||||||
policy; the semantics and enforcement of that policy are
|
policy; the semantics and enforcement of that policy are
|
||||||
determined by the deployment environment. Implementations may
|
determined by the deployment environment. Implementations may
|
||||||
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
|
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
|
||||||
or custom solutions) provided that the evaluation outcome is
|
or custom solutions) provided that the evaluation outcome is
|
||||||
faithfully recorded in the ECT claims defined above.
|
faithfully recorded in the "ext" keys defined above.
|
||||||
|
|
||||||
### Data Integrity {#data-integrity-claims}
|
### Data Integrity {#data-integrity-claims}
|
||||||
|
|
||||||
@@ -565,25 +563,12 @@ out_hash:
|
|||||||
|
|
||||||
### Compensation and Rollback {#compensation-claims}
|
### Compensation and Rollback {#compensation-claims}
|
||||||
|
|
||||||
compensation_required:
|
Compensation and rollback actions are recorded using the "par"
|
||||||
: OPTIONAL. Boolean. Indicates whether this task is a
|
claim to reference the original task and the "exec_act" claim to
|
||||||
compensation or rollback action for a previous task.
|
describe the remediation action. The referenced parent ECTs may
|
||||||
|
have passed their own "exp" time; ECT expiration applies to the
|
||||||
compensation_reason:
|
verification window of the ECT itself, not to its validity as a
|
||||||
: OPTIONAL. String. A human-readable reason for the compensation
|
parent reference in the ECT store.
|
||||||
action. MUST be present if "compensation_required" is true.
|
|
||||||
Values SHOULD use structured identifiers (e.g.,
|
|
||||||
"policy_violation_in_parent_trade") rather than free-form text
|
|
||||||
to minimize the risk of embedding sensitive information. See
|
|
||||||
{{data-minimization}} for privacy guidance.
|
|
||||||
If "compensation_reason" is present, "compensation_required"
|
|
||||||
MUST be true.
|
|
||||||
|
|
||||||
Note: compensation ECTs reference historical parent tasks via the
|
|
||||||
"par" claim. The referenced parent ECTs may have passed their own
|
|
||||||
"exp" time; ECT expiration applies to the verification window of
|
|
||||||
the ECT itself, not to its validity as a parent reference in the
|
|
||||||
ledger.
|
|
||||||
|
|
||||||
### Extensions {#extension-claims}
|
### Extensions {#extension-claims}
|
||||||
|
|
||||||
@@ -604,7 +589,20 @@ exceeds these limits.
|
|||||||
|
|
||||||
The following extension keys are defined by this specification
|
The following extension keys are defined by this specification
|
||||||
for common use cases. Because these keys are documented here,
|
for common use cases. Because these keys are documented here,
|
||||||
they use short names without reverse domain prefixes:
|
they use short names without reverse domain prefixes.
|
||||||
|
|
||||||
|
Policy evaluation keys (see {{policy-claims}} for full
|
||||||
|
definitions and decision value semantics):
|
||||||
|
|
||||||
|
- "pol": String. Policy rule identifier.
|
||||||
|
- "pol\_decision": String. Policy evaluation outcome
|
||||||
|
("approved", "rejected", or "pending\_human\_review").
|
||||||
|
- "pol\_enforcer": StringOrURI. Identity of the policy
|
||||||
|
evaluator.
|
||||||
|
- "pol\_timestamp": NumericDate. Time at which the policy
|
||||||
|
decision was made, if distinct from "iat".
|
||||||
|
|
||||||
|
Operational metadata keys:
|
||||||
|
|
||||||
- "exec\_time\_ms": Integer. Execution duration in milliseconds.
|
- "exec\_time\_ms": Integer. Execution duration in milliseconds.
|
||||||
- "regulated\_domain": String. Regulatory domain (e.g.,
|
- "regulated\_domain": String. Regulatory domain (e.g.,
|
||||||
@@ -616,8 +614,12 @@ they use short names without reverse domain prefixes:
|
|||||||
attestation, witnesses should submit independent signed ECTs.
|
attestation, witnesses should submit independent signed ECTs.
|
||||||
- "inp\_classification": String. Data sensitivity classification
|
- "inp\_classification": String. Data sensitivity classification
|
||||||
(e.g., "public", "confidential", "restricted").
|
(e.g., "public", "confidential", "restricted").
|
||||||
- "pol\_timestamp": NumericDate. Time at which the policy
|
- "compensation\_required": Boolean. Indicates whether this task
|
||||||
decision was made, if distinct from "iat".
|
is a compensation or rollback action.
|
||||||
|
- "compensation\_reason": String. Structured reason code for the
|
||||||
|
compensation action (e.g., "policy\_violation\_in\_parent\_trade").
|
||||||
|
SHOULD use structured identifiers rather than free-form text
|
||||||
|
to minimize information leakage (see {{data-minimization}}).
|
||||||
|
|
||||||
## Complete ECT Example
|
## Complete ECT Example
|
||||||
|
|
||||||
@@ -626,7 +628,6 @@ The following is a complete ECT payload example:
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/clinical",
|
"iss": "spiffe://example.com/agent/clinical",
|
||||||
"sub": "spiffe://example.com/agent/clinical",
|
|
||||||
"aud": "spiffe://example.com/agent/safety",
|
"aud": "spiffe://example.com/agent/safety",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -636,14 +637,13 @@ The following is a complete ECT payload example:
|
|||||||
"exec_act": "recommend_treatment",
|
"exec_act": "recommend_treatment",
|
||||||
"par": [],
|
"par": [],
|
||||||
|
|
||||||
"pol": "clinical_reasoning_policy_v2",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
|
|
||||||
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
|
||||||
"ext": {
|
"ext": {
|
||||||
|
"pol": "clinical_reasoning_policy_v2",
|
||||||
|
"pol_decision": "approved",
|
||||||
|
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
|
||||||
"pol_timestamp": 1772064145,
|
"pol_timestamp": 1772064145,
|
||||||
"exec_time_ms": 245,
|
"exec_time_ms": 245,
|
||||||
"regulated_domain": "medtech",
|
"regulated_domain": "medtech",
|
||||||
@@ -733,15 +733,14 @@ the following DAG validation steps:
|
|||||||
lead back to the current ECT's "jti". If a cycle is detected,
|
lead back to the current ECT's "jti". If a cycle is detected,
|
||||||
the ECT MUST be rejected.
|
the ECT MUST be rejected.
|
||||||
|
|
||||||
5. Parent Policy Decision: If any parent ECT contains a
|
5. Parent Policy Decision: If any parent ECT's "ext" object
|
||||||
"pol_decision" of "rejected" or "pending_human_review", the
|
contains a "pol_decision" of "rejected" or
|
||||||
current ECT's "exec_act" MUST indicate a compensation,
|
"pending_human_review", the current ECT's "exec_act" MUST
|
||||||
rollback, remediation, or human review action.
|
indicate a compensation, rollback, remediation, or human
|
||||||
Implementations MUST NOT accept an ECT representing normal
|
review action. Implementations MUST NOT accept an ECT
|
||||||
workflow continuation when a parent's "pol_decision" is not
|
representing normal workflow continuation when a parent's
|
||||||
"approved", unless the current ECT has "compensation_required"
|
"pol_decision" is not "approved". This rule only applies
|
||||||
set to true. This rule only applies when the parent ECT
|
when the parent ECT's "ext" contains policy keys.
|
||||||
contains policy claims.
|
|
||||||
|
|
||||||
6. Trust Domain Consistency: Parent tasks SHOULD belong to the
|
6. Trust Domain Consistency: Parent tasks SHOULD belong to the
|
||||||
same trust domain or to a trust domain with which a federation
|
same trust domain or to a trust domain with which a federation
|
||||||
@@ -856,19 +855,19 @@ verification steps in order:
|
|||||||
12. Verify all required claims ("jti", "exec_act", "par") are
|
12. Verify all required claims ("jti", "exec_act", "par") are
|
||||||
present and well-formed.
|
present and well-formed.
|
||||||
|
|
||||||
13. If "pol" or "pol_decision" is present, verify that both are
|
13. If "ext" is present and contains "pol" or "pol_decision",
|
||||||
present and that "pol_decision" is one of "approved",
|
verify that both are present and that "pol_decision" is one
|
||||||
"rejected", or "pending_human_review".
|
of "approved", "rejected", or "pending_human_review".
|
||||||
|
|
||||||
14. Perform DAG validation per {{dag-validation}}.
|
14. Perform DAG validation per {{dag-validation}}.
|
||||||
|
|
||||||
15. If all checks pass, the ECT MUST be appended to the audit
|
15. If all checks pass and an audit ledger is deployed, the ECT
|
||||||
ledger.
|
SHOULD be appended to the ledger.
|
||||||
|
|
||||||
If any verification step fails, the ECT MUST be rejected and the
|
If any verification step fails, the ECT MUST be rejected and the
|
||||||
failure MUST be logged for audit purposes. Error messages
|
failure MUST be logged for audit purposes. Error messages
|
||||||
SHOULD NOT reveal whether specific parent task IDs exist in the
|
SHOULD NOT reveal whether specific parent task IDs exist in the
|
||||||
ledger, to prevent information disclosure.
|
ECT store, to prevent information disclosure.
|
||||||
|
|
||||||
When ECT verification fails during HTTP request processing, the
|
When ECT verification fails during HTTP request processing, the
|
||||||
receiving agent SHOULD respond with HTTP 403 (Forbidden) if the
|
receiving agent SHOULD respond with HTTP 403 (Forbidden) if the
|
||||||
@@ -936,11 +935,12 @@ function verify_ect(ect_jws, verifier_id,
|
|||||||
if claim not in payload:
|
if claim not in payload:
|
||||||
return reject("Missing required claim: " + claim)
|
return reject("Missing required claim: " + claim)
|
||||||
|
|
||||||
// Validate policy claims (optional, but must be paired)
|
// Validate policy extension keys (optional, but must be paired)
|
||||||
if "pol" in payload or "pol_decision" in payload:
|
ext = payload.ext or {}
|
||||||
if "pol" not in payload or "pol_decision" not in payload:
|
if "pol" in ext or "pol_decision" in ext:
|
||||||
|
if "pol" not in ext or "pol_decision" not in ext:
|
||||||
return reject("pol and pol_decision must both be present")
|
return reject("pol and pol_decision must both be present")
|
||||||
if payload.pol_decision not in
|
if ext.pol_decision not in
|
||||||
["approved", "rejected", "pending_human_review"]:
|
["approved", "rejected", "pending_human_review"]:
|
||||||
return reject("Invalid pol_decision value")
|
return reject("Invalid pol_decision value")
|
||||||
|
|
||||||
@@ -1010,29 +1010,34 @@ software used in medical devices.
|
|||||||
Agent A (Spec Reviewer):
|
Agent A (Spec Reviewer):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: review_requirements_spec
|
exec_act: review_requirements_spec
|
||||||
pol: spec_review_policy_v2 pol_decision: approved
|
ext.pol: spec_review_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Code Generator):
|
Agent B (Code Generator):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: implement_module
|
exec_act: implement_module
|
||||||
pol: coding_standards_v3 pol_decision: approved
|
ext.pol: coding_standards_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Test Agent):
|
Agent C (Test Agent):
|
||||||
jti: task-003 par: [task-002]
|
jti: task-003 par: [task-002]
|
||||||
exec_act: execute_test_suite
|
exec_act: execute_test_suite
|
||||||
pol: test_coverage_policy_v1 pol_decision: approved
|
ext.pol: test_coverage_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent D (Build Agent):
|
Agent D (Build Agent):
|
||||||
jti: task-004 par: [task-003]
|
jti: task-004 par: [task-003]
|
||||||
exec_act: build_release_artifact
|
exec_act: build_release_artifact
|
||||||
pol: build_validation_v2 pol_decision: approved
|
ext.pol: build_validation_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Human Release Manager:
|
Human Release Manager:
|
||||||
jti: task-005 par: [task-004]
|
jti: task-005 par: [task-004]
|
||||||
exec_act: approve_release
|
exec_act: approve_release
|
||||||
pol: release_approval_policy pol_decision: approved
|
ext.pol: release_approval_policy
|
||||||
pol_enforcer: spiffe://meddev.example/human/release-mgr-42
|
ext.pol_decision: approved
|
||||||
ext: {witnessed_by: [...]} (extension metadata)
|
ext.pol_enforcer: spiffe://meddev.example/human/release-mgr-42
|
||||||
|
ext.witnessed_by: [...]
|
||||||
~~~
|
~~~
|
||||||
{: #fig-medtech-sdlc title="Medical Device SDLC Workflow"}
|
{: #fig-medtech-sdlc title="Medical Device SDLC Workflow"}
|
||||||
|
|
||||||
@@ -1098,17 +1103,20 @@ execution.
|
|||||||
Agent A (Risk Assessment):
|
Agent A (Risk Assessment):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: calculate_risk_exposure
|
exec_act: calculate_risk_exposure
|
||||||
pol: risk_limits_policy_v2 pol_decision: approved
|
ext.pol: risk_limits_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Compliance):
|
Agent B (Compliance):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: verify_compliance
|
exec_act: verify_compliance
|
||||||
pol: compliance_check_v1 pol_decision: approved
|
ext.pol: compliance_check_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Execution):
|
Agent C (Execution):
|
||||||
jti: task-003 par: [task-002]
|
jti: task-003 par: [task-002]
|
||||||
exec_act: execute_trade
|
exec_act: execute_trade
|
||||||
pol: execution_policy_v3 pol_decision: approved
|
ext.pol: execution_policy_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
~~~
|
~~~
|
||||||
{: #fig-finance title="Financial Trading Workflow"}
|
{: #fig-finance title="Financial Trading Workflow"}
|
||||||
|
|
||||||
@@ -1129,7 +1137,6 @@ a cryptographic link to the original task:
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://bank.example/agent/operations",
|
"iss": "spiffe://bank.example/agent/operations",
|
||||||
"sub": "spiffe://bank.example/agent/operations",
|
|
||||||
"aud": "spiffe://bank.example/system/ledger",
|
"aud": "spiffe://bank.example/system/ledger",
|
||||||
"iat": 1772150550,
|
"iat": 1772150550,
|
||||||
"exp": 1772151150,
|
"exp": 1772151150,
|
||||||
@@ -1137,11 +1144,13 @@ a cryptographic link to the original task:
|
|||||||
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
|
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
|
||||||
"exec_act": "initiate_trade_rollback",
|
"exec_act": "initiate_trade_rollback",
|
||||||
"par": ["550e8400-e29b-41d4-a716-446655440003"],
|
"par": ["550e8400-e29b-41d4-a716-446655440003"],
|
||||||
"pol": "compensation_policy_v1",
|
"ext": {
|
||||||
"pol_decision": "approved",
|
"pol": "compensation_policy_v1",
|
||||||
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
|
"pol_decision": "approved",
|
||||||
"compensation_required": true,
|
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
|
||||||
"compensation_reason": "policy_violation_in_parent_trade"
|
"compensation_required": true,
|
||||||
|
"compensation_reason": "policy_violation_in_parent_trade"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
{: #fig-compensation title="Compensation ECT Example"}
|
{: #fig-compensation title="Compensation ECT Example"}
|
||||||
@@ -1160,27 +1169,32 @@ required checks were completed:
|
|||||||
Agent A (Route Planning):
|
Agent A (Route Planning):
|
||||||
jti: task-001 par: []
|
jti: task-001 par: []
|
||||||
exec_act: plan_route
|
exec_act: plan_route
|
||||||
pol: route_policy_v1 pol_decision: approved
|
ext.pol: route_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent B (Customs):
|
Agent B (Customs):
|
||||||
jti: task-002 par: [task-001]
|
jti: task-002 par: [task-001]
|
||||||
exec_act: validate_customs
|
exec_act: validate_customs
|
||||||
pol: customs_policy_v2 pol_decision: approved
|
ext.pol: customs_policy_v2
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent C (Safety):
|
Agent C (Safety):
|
||||||
jti: task-003 par: [task-001]
|
jti: task-003 par: [task-001]
|
||||||
exec_act: verify_cargo_safety
|
exec_act: verify_cargo_safety
|
||||||
pol: safety_policy_v1 pol_decision: approved
|
ext.pol: safety_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
Agent D (Payment):
|
Agent D (Payment):
|
||||||
jti: task-004 par: [task-002, task-003]
|
jti: task-004 par: [task-002, task-003]
|
||||||
exec_act: authorize_payment
|
exec_act: authorize_payment
|
||||||
pol: payment_policy_v3 pol_decision: approved
|
ext.pol: payment_policy_v3
|
||||||
|
ext.pol_decision: approved
|
||||||
|
|
||||||
System (Commitment):
|
System (Commitment):
|
||||||
jti: task-005 par: [task-004]
|
jti: task-005 par: [task-004]
|
||||||
exec_act: commit_shipment
|
exec_act: commit_shipment
|
||||||
pol: commitment_policy_v1 pol_decision: approved
|
ext.pol: commitment_policy_v1
|
||||||
|
ext.pol_decision: approved
|
||||||
~~~
|
~~~
|
||||||
{: #fig-logistics title="Logistics Workflow with Parallel Tasks"}
|
{: #fig-logistics title="Logistics Workflow with Parallel Tasks"}
|
||||||
|
|
||||||
@@ -1211,8 +1225,8 @@ The following threat actors are considered:
|
|||||||
ECTs are self-asserted by the executing agent. The agent claims
|
ECTs are self-asserted by the executing agent. The agent claims
|
||||||
what it did, and this claim is signed with its private key. A
|
what it did, and this claim is signed with its private key. A
|
||||||
compromised or malicious agent could create ECTs with false claims
|
compromised or malicious agent could create ECTs with false claims
|
||||||
(e.g., setting "pol_decision" to "approved" without actually
|
(e.g., setting "pol_decision" in "ext" to "approved" without
|
||||||
evaluating the policy).
|
actually evaluating the policy).
|
||||||
|
|
||||||
ECTs do not independently verify that:
|
ECTs do not independently verify that:
|
||||||
|
|
||||||
@@ -1232,32 +1246,11 @@ evidence within a single ECT that the witnesses actually
|
|||||||
observed the task. An issuing agent could list witnesses that
|
observed the task. An issuing agent could list witnesses that
|
||||||
did not participate.
|
did not participate.
|
||||||
|
|
||||||
### Witness Attestation Model {#witness-attestation-model}
|
To strengthen witness attestation beyond self-assertion, witnesses
|
||||||
|
SHOULD submit their own independent signed ECTs referencing the
|
||||||
To address the self-assertion limitation of the
|
observed task's "jti" in the "par" array. Auditors can then
|
||||||
"witnessed_by" extension, witnesses SHOULD submit their
|
cross-check the "witnessed_by" extension against independent
|
||||||
own independent signed ECTs to the audit ledger attesting to the
|
witness ECTs in the ECT store.
|
||||||
observed task. A witness attestation ECT:
|
|
||||||
|
|
||||||
- MUST set "iss" to the witness's own workload identity.
|
|
||||||
- MUST set "exec_act" to "witness_attestation" (or a domain-
|
|
||||||
specific equivalent).
|
|
||||||
- MUST include the observed task's "jti" in the "par" array,
|
|
||||||
linking the attestation to the original task.
|
|
||||||
- MUST set "pol_decision" to "approved" to indicate the witness
|
|
||||||
confirms the observation.
|
|
||||||
|
|
||||||
When a task's "witnessed_by" extension lists one or more
|
|
||||||
witnesses, auditors SHOULD verify that corresponding witness
|
|
||||||
attestation ECTs exist in the ledger for each listed witness. A
|
|
||||||
mismatch between the extension value and the set of independent
|
|
||||||
witness ECTs in the ledger SHOULD be flagged during audit review.
|
|
||||||
|
|
||||||
This model converts witness attestation from a self-asserted claim
|
|
||||||
to a cryptographically verifiable property of the ledger: the
|
|
||||||
witness independently signs their own ECT using their own key,
|
|
||||||
and the ledger records both the original task ECT and the witness
|
|
||||||
attestation ECTs.
|
|
||||||
|
|
||||||
## Organizational Prerequisites
|
## Organizational Prerequisites
|
||||||
|
|
||||||
@@ -1409,8 +1402,8 @@ ECTs necessarily reveal:
|
|||||||
|
|
||||||
- Agent identities ("iss", "aud") for accountability purposes
|
- Agent identities ("iss", "aud") for accountability purposes
|
||||||
- Action descriptions ("exec_act") for audit trail completeness
|
- Action descriptions ("exec_act") for audit trail completeness
|
||||||
- Policy evaluation outcomes ("pol", "pol_decision") for
|
- Policy evaluation outcomes (via "ext" keys "pol",
|
||||||
compliance verification
|
"pol_decision") when present, for compliance verification
|
||||||
- Timestamps ("iat", "exp") for temporal ordering
|
- Timestamps ("iat", "exp") for temporal ordering
|
||||||
|
|
||||||
ECTs are designed to NOT reveal:
|
ECTs are designed to NOT reveal:
|
||||||
@@ -1426,18 +1419,14 @@ ECTs are designed to NOT reveal:
|
|||||||
Implementations SHOULD minimize the information included in ECTs.
|
Implementations SHOULD minimize the information included in ECTs.
|
||||||
The "exec_act" claim SHOULD use structured identifiers (e.g.,
|
The "exec_act" claim SHOULD use structured identifiers (e.g.,
|
||||||
"process_payment") rather than natural language descriptions.
|
"process_payment") rather than natural language descriptions.
|
||||||
The "pol" claim SHOULD reference policy identifiers rather than
|
The "pol" extension key SHOULD reference policy identifiers
|
||||||
embedding policy content.
|
rather than embedding policy content.
|
||||||
|
|
||||||
The "compensation_reason" claim ({{compensation-claims}})
|
The "compensation_reason" extension key in "ext"
|
||||||
deserves particular attention: because it is human-readable and
|
({{compensation-claims}}) deserves particular attention: because
|
||||||
may describe the circumstances of a failure or policy violation,
|
it is human-readable, it risks exposing sensitive operational
|
||||||
it risks exposing sensitive operational details. Implementations
|
details. See {{extension-claims}} for guidance on using
|
||||||
SHOULD use short, structured reason codes (e.g.,
|
structured identifiers.
|
||||||
"policy_violation_in_parent_trade") rather than free-form
|
|
||||||
natural language explanations. Implementers SHOULD review
|
|
||||||
"compensation_reason" values for potential information leakage
|
|
||||||
before deploying to production.
|
|
||||||
|
|
||||||
## Storage and Access Control
|
## Storage and Access Control
|
||||||
|
|
||||||
@@ -1540,16 +1529,16 @@ the "JSON Web Token Claims" registry maintained by IANA:
|
|||||||
| wid | Workflow Identifier | IETF | {{exec-claims}} |
|
| wid | Workflow Identifier | IETF | {{exec-claims}} |
|
||||||
| exec_act | Action/Task Type | IETF | {{exec-claims}} |
|
| exec_act | Action/Task Type | IETF | {{exec-claims}} |
|
||||||
| par | Parent Task Identifiers | IETF | {{exec-claims}} |
|
| par | Parent Task Identifiers | IETF | {{exec-claims}} |
|
||||||
| pol | Policy Rule Identifier | IETF | {{policy-claims}} |
|
|
||||||
| pol_decision | Policy Decision Result | IETF | {{policy-claims}} |
|
|
||||||
| pol_enforcer | Policy Enforcer Identity | IETF | {{policy-claims}} |
|
|
||||||
| inp_hash | Input Data Hash | IETF | {{data-integrity-claims}} |
|
| inp_hash | Input Data Hash | IETF | {{data-integrity-claims}} |
|
||||||
| out_hash | Output Data Hash | IETF | {{data-integrity-claims}} |
|
| out_hash | Output Data Hash | IETF | {{data-integrity-claims}} |
|
||||||
| compensation_required | Compensation Flag | IETF | {{compensation-claims}} |
|
|
||||||
| compensation_reason | Compensation Reason | IETF | {{compensation-claims}} |
|
|
||||||
| ext | Extension Object | IETF | {{extension-claims}} |
|
| ext | Extension Object | IETF | {{extension-claims}} |
|
||||||
{: #table-claims title="JWT Claims Registrations"}
|
{: #table-claims title="JWT Claims Registrations"}
|
||||||
|
|
||||||
|
Note: Policy evaluation keys ("pol", "pol_decision",
|
||||||
|
"pol_enforcer") are carried within the "ext" object as
|
||||||
|
spec-defined extension keys ({{policy-claims}}) and do not
|
||||||
|
require separate JWT Claims registration.
|
||||||
|
|
||||||
## ECT Policy Decision Values Registry {#pol-decision-registry}
|
## ECT Policy Decision Values Registry {#pol-decision-registry}
|
||||||
|
|
||||||
This document establishes the "ECT Policy Decision Values"
|
This document establishes the "ECT Policy Decision Values"
|
||||||
@@ -1704,14 +1693,15 @@ use cases are distinct.
|
|||||||
A minimal conforming implementation needs to:
|
A minimal conforming implementation needs to:
|
||||||
|
|
||||||
1. Create JWTs with all required claims ("iss", "aud", "iat",
|
1. Create JWTs with all required claims ("iss", "aud", "iat",
|
||||||
"exp", "jti", "exec_act", "par") and policy claims ("pol",
|
"exp", "jti", "exec_act", "par") and policy extension keys
|
||||||
"pol_decision") when policy evaluation was performed.
|
("ext.pol", "ext.pol_decision") when policy evaluation was
|
||||||
|
performed.
|
||||||
2. Sign ECTs with the agent's private key using an algorithm
|
2. Sign ECTs with the agent's private key using an algorithm
|
||||||
matching the WIT (ES256 recommended).
|
matching the WIT (ES256 recommended).
|
||||||
3. Verify ECT signatures against WIT public keys.
|
3. Verify ECT signatures against WIT public keys.
|
||||||
4. Perform DAG validation (parent existence, temporal ordering,
|
4. Perform DAG validation (parent existence, temporal ordering,
|
||||||
cycle detection).
|
cycle detection).
|
||||||
5. Append verified ECTs to the audit ledger.
|
5. If an audit ledger is deployed, append verified ECTs to it.
|
||||||
|
|
||||||
## Storage Recommendations
|
## Storage Recommendations
|
||||||
{:numbered="false"}
|
{:numbered="false"}
|
||||||
@@ -1787,7 +1777,6 @@ ECT Payload:
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/data-retrieval",
|
"iss": "spiffe://example.com/agent/data-retrieval",
|
||||||
"sub": "spiffe://example.com/agent/data-retrieval",
|
|
||||||
"aud": "spiffe://example.com/agent/validator",
|
"aud": "spiffe://example.com/agent/validator",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -1795,10 +1784,12 @@ ECT Payload:
|
|||||||
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
||||||
"exec_act": "fetch_patient_data",
|
"exec_act": "fetch_patient_data",
|
||||||
"par": [],
|
"par": [],
|
||||||
"pol": "clinical_data_access_policy_v1",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
"ext": {
|
||||||
|
"pol": "clinical_data_access_policy_v1",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1808,7 +1799,6 @@ task, and creates its own ECT:
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://example.com/agent/validator",
|
"iss": "spiffe://example.com/agent/validator",
|
||||||
"sub": "spiffe://example.com/agent/validator",
|
|
||||||
"aud": "spiffe://example.com/system/ledger",
|
"aud": "spiffe://example.com/system/ledger",
|
||||||
"iat": 1772064160,
|
"iat": 1772064160,
|
||||||
"exp": 1772064760,
|
"exp": 1772064760,
|
||||||
@@ -1816,8 +1806,10 @@ task, and creates its own ECT:
|
|||||||
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
|
||||||
"exec_act": "validate_safety",
|
"exec_act": "validate_safety",
|
||||||
"par": ["550e8400-e29b-41d4-a716-446655440001"],
|
"par": ["550e8400-e29b-41d4-a716-446655440001"],
|
||||||
"pol": "safety_validation_policy_v2",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "safety_validation_policy_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1841,7 +1833,6 @@ Task 1 (Spec Review Agent):
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/spec-reviewer",
|
"iss": "spiffe://meddev.example/agent/spec-reviewer",
|
||||||
"sub": "spiffe://meddev.example/agent/spec-reviewer",
|
|
||||||
"aud": "spiffe://meddev.example/agent/code-gen",
|
"aud": "spiffe://meddev.example/agent/code-gen",
|
||||||
"iat": 1772064150,
|
"iat": 1772064150,
|
||||||
"exp": 1772064750,
|
"exp": 1772064750,
|
||||||
@@ -1849,10 +1840,12 @@ Task 1 (Spec Review Agent):
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "review_requirements_spec",
|
"exec_act": "review_requirements_spec",
|
||||||
"par": [],
|
"par": [],
|
||||||
"pol": "spec_review_policy_v2",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
|
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||||
|
"ext": {
|
||||||
|
"pol": "spec_review_policy_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1861,7 +1854,6 @@ Task 2 (Code Generation Agent):
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/code-gen",
|
"iss": "spiffe://meddev.example/agent/code-gen",
|
||||||
"sub": "spiffe://meddev.example/agent/code-gen",
|
|
||||||
"aud": "spiffe://meddev.example/agent/test-runner",
|
"aud": "spiffe://meddev.example/agent/test-runner",
|
||||||
"iat": 1772064200,
|
"iat": 1772064200,
|
||||||
"exp": 1772064800,
|
"exp": 1772064800,
|
||||||
@@ -1869,8 +1861,10 @@ Task 2 (Code Generation Agent):
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "implement_module",
|
"exec_act": "implement_module",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
|
||||||
"pol": "coding_standards_v3",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "coding_standards_v3",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1879,7 +1873,6 @@ Task 3 (Autonomous Test Agent):
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/test-runner",
|
"iss": "spiffe://meddev.example/agent/test-runner",
|
||||||
"sub": "spiffe://meddev.example/agent/test-runner",
|
|
||||||
"aud": "spiffe://meddev.example/agent/build",
|
"aud": "spiffe://meddev.example/agent/build",
|
||||||
"iat": 1772064260,
|
"iat": 1772064260,
|
||||||
"exp": 1772064860,
|
"exp": 1772064860,
|
||||||
@@ -1887,8 +1880,10 @@ Task 3 (Autonomous Test Agent):
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "execute_test_suite",
|
"exec_act": "execute_test_suite",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
|
||||||
"pol": "test_coverage_policy_v1",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "test_coverage_policy_v1",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1897,7 +1892,6 @@ Task 4 (Build Agent):
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/agent/build",
|
"iss": "spiffe://meddev.example/agent/build",
|
||||||
"sub": "spiffe://meddev.example/agent/build",
|
|
||||||
"aud": "spiffe://meddev.example/human/release-mgr-42",
|
"aud": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"iat": 1772064310,
|
"iat": 1772064310,
|
||||||
"exp": 1772064910,
|
"exp": 1772064910,
|
||||||
@@ -1905,9 +1899,11 @@ Task 4 (Build Agent):
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "build_release_artifact",
|
"exec_act": "build_release_artifact",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
|
||||||
"pol": "build_validation_v2",
|
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc",
|
||||||
"pol_decision": "approved",
|
"ext": {
|
||||||
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc"
|
"pol": "build_validation_v2",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@@ -1916,7 +1912,6 @@ Task 5 (Human Release Manager Approval):
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://meddev.example/human/release-mgr-42",
|
"iss": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"sub": "spiffe://meddev.example/human/release-mgr-42",
|
|
||||||
"aud": "spiffe://meddev.example/system/ledger",
|
"aud": "spiffe://meddev.example/system/ledger",
|
||||||
"iat": 1772064510,
|
"iat": 1772064510,
|
||||||
"exp": 1772065110,
|
"exp": 1772065110,
|
||||||
@@ -1924,10 +1919,10 @@ Task 5 (Human Release Manager Approval):
|
|||||||
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
|
||||||
"exec_act": "approve_release",
|
"exec_act": "approve_release",
|
||||||
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
|
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
|
||||||
"pol": "release_approval_policy",
|
|
||||||
"pol_decision": "approved",
|
|
||||||
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
|
|
||||||
"ext": {
|
"ext": {
|
||||||
|
"pol": "release_approval_policy",
|
||||||
|
"pol_decision": "approved",
|
||||||
|
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
|
||||||
"witnessed_by": [
|
"witnessed_by": [
|
||||||
"spiffe://meddev.example/audit/qa-observer-1"
|
"spiffe://meddev.example/audit/qa-observer-1"
|
||||||
]
|
]
|
||||||
@@ -1986,7 +1981,6 @@ Task 004 ECT payload:
|
|||||||
~~~json
|
~~~json
|
||||||
{
|
{
|
||||||
"iss": "spiffe://bank.example/agent/execution",
|
"iss": "spiffe://bank.example/agent/execution",
|
||||||
"sub": "spiffe://bank.example/agent/execution",
|
|
||||||
"aud": "spiffe://bank.example/system/ledger",
|
"aud": "spiffe://bank.example/system/ledger",
|
||||||
"iat": 1772064250,
|
"iat": 1772064250,
|
||||||
"exp": 1772064850,
|
"exp": 1772064850,
|
||||||
@@ -1997,8 +1991,10 @@ Task 004 ECT payload:
|
|||||||
"f1e2d3c4-0002-0000-0000-000000000002",
|
"f1e2d3c4-0002-0000-0000-000000000002",
|
||||||
"f1e2d3c4-0003-0000-0000-000000000003"
|
"f1e2d3c4-0003-0000-0000-000000000003"
|
||||||
],
|
],
|
||||||
"pol": "trade_execution_policy_v3",
|
"ext": {
|
||||||
"pol_decision": "approved"
|
"pol": "trade_execution_policy_v3",
|
||||||
|
"pol_decision": "approved"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user