Simplify spec: remove sub, move compensation to ext, add RFC 8126

Restore from pre-linter base (898b0f8) and re-apply targeted
changes to avoid unintended structural rewrites:

- Remove sub claim (always equals iss, adds no information)
- Move compensation_required and compensation_reason to ext keys
- Trim witness attestation section to concise guidance
- Fix ledger-mandatory language in verification step 15 and
  minimal implementation step 5
- Add RFC 8126 to normative references

Policy evaluation claims (pol, pol_decision, pol_enforcer) remain
as registered JWT claims in this spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 14:26:13 +01:00
parent 0a38226b32
commit a0a3369113
4 changed files with 1177 additions and 1302 deletions

View File

@@ -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>
</li>
<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-extension" class="internal xref">Policy Evaluation Extension Keys</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" class="internal xref">Policy Evaluation</a></p>
</li>
<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>
@@ -1700,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>
</li>
<li class="normal" id="section-1.3-2.3">
<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>
<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>
</li>
<li class="normal" id="section-1.3-2.4">
<p id="section-1.3-2.4.1">Integration with the WIMSE identity framework
@@ -2173,73 +2173,70 @@ multiple root tasks.<a href="#section-4.2.2-2.6.1" class="pilcrow">¶</a></p>
</div>
<div id="policy-claims">
<section id="section-4.2.3">
<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-extension" class="section-name selfRef">Policy Evaluation Extension Keys</a>
<h4 id="name-policy-evaluation">
<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>
</h4>
<p id="section-4.2.3-1">Policy evaluation outcomes are recorded as extension keys within
the "ext" object (<a href="#extension-claims" class="auto internal xref">Section 4.2.6</a>). This keeps the core
registered claims focused on DAG structure and execution context,
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">The following extension keys are defined for policy evaluation:<a href="#section-4.2.3-2" class="pilcrow"></a></p>
<span class="break"></span><dl class="dlParallel" id="section-4.2.3-3">
<dt id="section-4.2.3-3.1">"pol":</dt>
<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>
<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>
<span class="break"></span><dl class="dlParallel" id="section-4.2.3-2">
<dt id="section-4.2.3-2.1">pol:</dt>
<dd style="margin-left: 1.5em" id="section-4.2.3-2.2">
<p id="section-4.2.3-2.2.1"><span class="bcp14">OPTIONAL</span>. 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-2.2.1" class="pilcrow"></a></p>
</dd>
<dd class="break"></dd>
<dt id="section-4.2.3-3.3">"pol_decision":</dt>
<dd style="margin-left: 1.5em" id="section-4.2.3-3.4">
<p id="section-4.2.3-3.4.1">String. The result of the policy evaluation. When present,
<span class="bcp14">MUST</span> be one of the values registered in the ECT Policy Decision
Values registry (<a href="#pol-decision-registry" class="auto internal xref">Section 12.4</a>). <span class="bcp14">MUST</span> be present
when "pol" is present. Initial values are:<a href="#section-4.2.3-3.4.1" class="pilcrow"></a></p>
<dt id="section-4.2.3-2.3">pol_decision:</dt>
<dd style="margin-left: 1.5em" id="section-4.2.3-2.4">
<p id="section-4.2.3-2.4.1"><span class="bcp14">OPTIONAL</span>. String. The result of the policy evaluation. When
present, <span class="bcp14">MUST</span> be one of the values registered in the ECT Policy
Decision Values registry (<a href="#pol-decision-registry" class="auto internal xref">Section 12.4</a>). <span class="bcp14">MUST</span> be
present when "pol" is present. Initial values are:<a href="#section-4.2.3-2.4.1" class="pilcrow"></a></p>
<ul class="normal">
<li class="normal" id="section-4.2.3-3.4.2.1">
<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-3.4.2.1.1" class="pilcrow"></a></p>
<li class="normal" id="section-4.2.3-2.4.2.1">
<p id="section-4.2.3-2.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>
</li>
<li class="normal" id="section-4.2.3-3.4.2.2">
<p id="section-4.2.3-3.4.2.2.1">"rejected": The policy evaluation failed. A "rejected" ECT
<li class="normal" id="section-4.2.3-2.4.2.2">
<p id="section-4.2.3-2.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
"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,
rollback, or remediation tasks. Agents <span class="bcp14">MUST NOT</span> proceed
with normal workflow execution based on a parent ECT whose
"pol_decision" is "rejected".<a href="#section-4.2.3-3.4.2.2.1" class="pilcrow"></a></p>
"pol_decision" is "rejected".<a href="#section-4.2.3-2.4.2.2.1" class="pilcrow"></a></p>
</li>
<li class="normal" id="section-4.2.3-3.4.2.3">
<p id="section-4.2.3-3.4.2.3.1">"pending_human_review": The policy evaluation requires human
<li class="normal" id="section-4.2.3-2.4.2.3">
<p id="section-4.2.3-2.4.2.3.1">"pending_human_review": The policy evaluation requires human
judgment before proceeding. Agents <span class="bcp14">MUST NOT</span> proceed with
dependent tasks until a subsequent ECT from a human reviewer
records an "approved" decision referencing this task as a
parent.<a href="#section-4.2.3-3.4.2.3.1" class="pilcrow"></a></p>
parent.<a href="#section-4.2.3-2.4.2.3.1" class="pilcrow"></a></p>
</li>
</ul>
<p id="section-4.2.3-3.4.3">When "pol" and "pol_decision" are absent from "ext", the ECT
records task execution without a policy checkpoint. Regulated
deployments <span class="bcp14">SHOULD</span> include policy keys on all ECTs to maintain
complete audit trails.<a href="#section-4.2.3-3.4.3" class="pilcrow"></a></p>
<p id="section-4.2.3-2.4.3">When "pol" and "pol_decision" are absent, the ECT records task
execution without a policy checkpoint. Regulated deployments
<span class="bcp14">SHOULD</span> include policy claims on all ECTs to maintain complete
audit trails.<a href="#section-4.2.3-2.4.3" class="pilcrow"></a></p>
</dd>
<dd class="break"></dd>
<dt id="section-4.2.3-3.5">"pol_enforcer":</dt>
<dd style="margin-left: 1.5em" id="section-4.2.3-3.6">
<p id="section-4.2.3-3.6.1">StringOrURI. The identity of the entity (system or person)
that evaluated the policy decision. When present, <span class="bcp14">SHOULD</span> use
SPIFFE ID format.<a href="#section-4.2.3-3.6.1" class="pilcrow"></a></p>
<dt id="section-4.2.3-2.5">pol_enforcer:</dt>
<dd style="margin-left: 1.5em" id="section-4.2.3-2.6">
<p id="section-4.2.3-2.6.1"><span class="bcp14">OPTIONAL</span>. StringOrURI. The identity of the entity (system or
person) that evaluated the policy decision. When present,
<span class="bcp14">SHOULD</span> use SPIFFE ID format.<a href="#section-4.2.3-2.6.1" class="pilcrow"></a></p>
</dd>
<dd class="break"></dd>
</dl>
<p id="section-4.2.3-4">This specification intentionally defines only the recording of
<p id="section-4.2.3-3">This specification intentionally defines only the recording of
policy evaluation outcomes. The mechanisms by which policies are
defined, distributed to agents, and evaluated are out of scope.
The "pol" key is an opaque identifier referencing an external
The "pol" claim is an opaque identifier referencing an external
policy; the semantics and enforcement of that policy are
determined by the deployment environment. Implementations may
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
or custom solutions) provided that the evaluation outcome is
faithfully recorded in the "ext" keys defined above.<a href="#section-4.2.3-4" class="pilcrow"></a></p>
faithfully recorded in the ECT claims defined above.<a href="#section-4.2.3-3" class="pilcrow"></a></p>
</section>
</div>
<div id="data-integrity-claims">
@@ -2294,12 +2291,9 @@ parent reference in the ECT store.<a href="#section-4.2.5-1" class="pilcrow">¶<
<span class="break"></span><dl class="dlParallel" id="section-4.2.6-1">
<dt id="section-4.2.6-1.1">ext:</dt>
<dd style="margin-left: 1.5em" id="section-4.2.6-1.2">
<p id="section-4.2.6-1.2.1"><span class="bcp14">OPTIONAL</span>. Object. An extension object for claims beyond the
core registered claims. This specification defines several
extension keys for policy evaluation (<a href="#policy-claims" class="auto internal xref">Section 4.2.3</a>) and
operational metadata; deployments <span class="bcp14">MAY</span> also include
domain-specific keys. Implementations <span class="bcp14">MUST</span> ignore extension
keys they do not recognize.<a href="#section-4.2.6-1.2.1" class="pilcrow"></a></p>
<p id="section-4.2.6-1.2.1"><span class="bcp14">OPTIONAL</span>. Object. An extension object for domain-specific
claims not defined by this specification. Implementations
that do not understand extension claims <span class="bcp14">MUST</span> ignore them.<a href="#section-4.2.6-1.2.1" class="pilcrow"></a></p>
</dd>
<dd class="break"></dd>
</dl>
@@ -2314,57 +2308,41 @@ 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>
<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,
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>
they use short names without reverse domain prefixes:<a href="#section-4.2.6-3" class="pilcrow"></a></p>
<ul class="normal">
<li class="normal" id="section-4.2.6-5.1">
<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 class="normal" id="section-4.2.6-4.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>
</li>
<li class="normal" id="section-4.2.6-5.2">
<p id="section-4.2.6-5.2.1">"pol_decision": String. Policy evaluation outcome
("approved", "rejected", or "pending_human_review").<a href="#section-4.2.6-5.2.1" class="pilcrow"></a></p>
<li class="normal" id="section-4.2.6-4.2">
<p id="section-4.2.6-4.2.1">"regulated_domain": String. Regulatory domain (e.g.,
"medtech", "finance", "military").<a href="#section-4.2.6-4.2.1" class="pilcrow"></a></p>
</li>
<li class="normal" id="section-4.2.6-5.3">
<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 class="normal" id="section-4.2.6-4.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>
</li>
<li class="normal" id="section-4.2.6-5.4">
<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
<li class="normal" id="section-4.2.6-4.4">
<p id="section-4.2.6-4.4.1">"witnessed_by": Array of StringOrURI. Identifiers of
third-party entities that the issuer claims observed the
task. Note: this is self-asserted; for verifiable witness
attestation, witnesses should submit independent signed ECTs.<a href="#section-4.2.6-7.4.1" class="pilcrow"></a></p>
attestation, witnesses should submit independent signed ECTs.<a href="#section-4.2.6-4.4.1" class="pilcrow"></a></p>
</li>
<li class="normal" id="section-4.2.6-7.5">
<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-7.5.1" class="pilcrow"></a></p>
<li class="normal" id="section-4.2.6-4.5">
<p id="section-4.2.6-4.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>
</li>
<li class="normal" id="section-4.2.6-7.6">
<p id="section-4.2.6-7.6.1">"compensation_required": Boolean. Indicates whether this task
is a compensation or rollback action.<a href="#section-4.2.6-7.6.1" class="pilcrow"></a></p>
<li class="normal" id="section-4.2.6-4.6">
<p id="section-4.2.6-4.6.1">"pol_timestamp": NumericDate. Time at which the policy
decision was made, if distinct from "iat".<a href="#section-4.2.6-4.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
<li class="normal" id="section-4.2.6-4.7">
<p id="section-4.2.6-4.7.1">"compensation_required": Boolean. Indicates whether this task
is a compensation or rollback action.<a href="#section-4.2.6-4.7.1" class="pilcrow"></a></p>
</li>
<li class="normal" id="section-4.2.6-4.8">
<p id="section-4.2.6-4.8.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>
to minimize information leakage (see <a href="#data-minimization" class="auto internal xref">Section 11.2</a>).<a href="#section-4.2.6-4.8.1" class="pilcrow"></a></p>
</li>
</ul>
</section>
@@ -2392,13 +2370,14 @@ to minimize information leakage (see <a href="#data-minimization" class="auto in
"exec_act": "recommend_treatment",
"par": [],
"pol": "clinical_reasoning_policy_v2",
"pol_decision": "approved",
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "clinical_reasoning_policy_v2",
"pol_decision": "approved",
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
"pol_timestamp": 1772064145,
"exec_time_ms": 245,
"regulated_domain": "medtech",
@@ -2519,14 +2498,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>
</li>
<li id="section-6.2-2.5">
<p id="section-6.2-2.5.1">Parent Policy Decision: If any parent ECT's "ext" object
contains a "pol_decision" of "rejected" or
"pending_human_review", the current ECT's "exec_act" <span class="bcp14">MUST</span>
indicate a compensation, rollback, remediation, or human
review action. Implementations <span class="bcp14">MUST NOT</span> accept an ECT
representing normal workflow continuation when a parent's
"pol_decision" is not "approved". This rule only applies
when the parent ECT's "ext" contains policy keys.<a href="#section-6.2-2.5.1" class="pilcrow"></a></p>
<p id="section-6.2-2.5.1">Parent Policy Decision: If any parent ECT contains a
"pol_decision" of "rejected" or "pending_human_review", the
current ECT's "exec_act" <span class="bcp14">MUST</span> indicate a compensation,
rollback, remediation, or human review action.
Implementations <span class="bcp14">MUST NOT</span> accept an ECT representing normal
workflow continuation when a parent's "pol_decision" is not
"approved". This rule only applies when the parent ECT
contains policy claims.<a href="#section-6.2-2.5.1" class="pilcrow"></a></p>
</li>
<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
@@ -2675,9 +2654,9 @@ 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>
</li>
<li id="section-7.1-2.13">
<p id="section-7.1-2.13.1">If "ext" is present and contains "pol" or "pol_decision",
verify that both are present and that "pol_decision" is one
of "approved", "rejected", or "pending_human_review".<a href="#section-7.1-2.13.1" class="pilcrow"></a></p>
<p id="section-7.1-2.13.1">If "pol" or "pol_decision" is present, verify that both are
present and that "pol_decision" is one of "approved",
"rejected", or "pending_human_review".<a href="#section-7.1-2.13.1" class="pilcrow"></a></p>
</li>
<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>
@@ -2764,12 +2743,11 @@ function verify_ect(ect_jws, verifier_id,
if claim not in payload:
return reject("Missing required claim: " + claim)
// Validate policy extension keys (optional, but must be paired)
ext = payload.ext or {}
if "pol" in ext or "pol_decision" in ext:
if "pol" not in ext or "pol_decision" not in ext:
// Validate policy claims (optional, but must be paired)
if "pol" in payload or "pol_decision" in payload:
if "pol" not in payload or "pol_decision" not in payload:
return reject("pol and pol_decision must both be present")
if ext.pol_decision not in
if payload.pol_decision not in
["approved", "rejected", "pending_human_review"]:
return reject("Invalid pol_decision value")
@@ -2860,34 +2838,29 @@ software used in medical devices.<a href="#section-9.1-1" class="pilcrow">¶</a>
Agent A (Spec Reviewer):
jti: task-001 par: []
exec_act: review_requirements_spec
ext.pol: spec_review_policy_v2
ext.pol_decision: approved
pol: spec_review_policy_v2 pol_decision: approved
Agent B (Code Generator):
jti: task-002 par: [task-001]
exec_act: implement_module
ext.pol: coding_standards_v3
ext.pol_decision: approved
pol: coding_standards_v3 pol_decision: approved
Agent C (Test Agent):
jti: task-003 par: [task-002]
exec_act: execute_test_suite
ext.pol: test_coverage_policy_v1
ext.pol_decision: approved
pol: test_coverage_policy_v1 pol_decision: approved
Agent D (Build Agent):
jti: task-004 par: [task-003]
exec_act: build_release_artifact
ext.pol: build_validation_v2
ext.pol_decision: approved
pol: build_validation_v2 pol_decision: approved
Human Release Manager:
jti: task-005 par: [task-004]
exec_act: approve_release
ext.pol: release_approval_policy
ext.pol_decision: approved
ext.pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext.witnessed_by: [...]
pol: release_approval_policy pol_decision: approved
pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext: {witnessed_by: [...]} (extension metadata)
</pre>
</div>
<figcaption><a href="#figure-8" class="selfRef">Figure 8</a>:
@@ -2990,20 +2963,17 @@ execution.<a href="#section-9.2-1" class="pilcrow">¶</a></p>
Agent A (Risk Assessment):
jti: task-001 par: []
exec_act: calculate_risk_exposure
ext.pol: risk_limits_policy_v2
ext.pol_decision: approved
pol: risk_limits_policy_v2 pol_decision: approved
Agent B (Compliance):
jti: task-002 par: [task-001]
exec_act: verify_compliance
ext.pol: compliance_check_v1
ext.pol_decision: approved
pol: compliance_check_v1 pol_decision: approved
Agent C (Execution):
jti: task-003 par: [task-002]
exec_act: execute_trade
ext.pol: execution_policy_v3
ext.pol_decision: approved
pol: execution_policy_v3 pol_decision: approved
</pre>
</div>
<figcaption><a href="#figure-10" class="selfRef">Figure 10</a>:
@@ -3047,10 +3017,10 @@ a cryptographic link to the original task:<a href="#section-9.3-1" class="pilcro
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
"exec_act": "initiate_trade_rollback",
"par": ["550e8400-e29b-41d4-a716-446655440003"],
"ext": {
"pol": "compensation_policy_v1",
"pol_decision": "approved",
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
"ext": {
"compensation_required": true,
"compensation_reason": "policy_violation_in_parent_trade"
}
@@ -3081,32 +3051,27 @@ required checks were completed:<a href="#section-9.4-1" class="pilcrow">¶</a></
Agent A (Route Planning):
jti: task-001 par: []
exec_act: plan_route
ext.pol: route_policy_v1
ext.pol_decision: approved
pol: route_policy_v1 pol_decision: approved
Agent B (Customs):
jti: task-002 par: [task-001]
exec_act: validate_customs
ext.pol: customs_policy_v2
ext.pol_decision: approved
pol: customs_policy_v2 pol_decision: approved
Agent C (Safety):
jti: task-003 par: [task-001]
exec_act: verify_cargo_safety
ext.pol: safety_policy_v1
ext.pol_decision: approved
pol: safety_policy_v1 pol_decision: approved
Agent D (Payment):
jti: task-004 par: [task-002, task-003]
exec_act: authorize_payment
ext.pol: payment_policy_v3
ext.pol_decision: approved
pol: payment_policy_v3 pol_decision: approved
System (Commitment):
jti: task-005 par: [task-004]
exec_act: commit_shipment
ext.pol: commitment_policy_v1
ext.pol_decision: approved
pol: commitment_policy_v1 pol_decision: approved
</pre>
</div>
<figcaption><a href="#figure-12" class="selfRef">Figure 12</a>:
@@ -3161,8 +3126,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
what it did, and this claim is signed with its private key. A
compromised or malicious agent could create ECTs with false claims
(e.g., setting "pol_decision" in "ext" to "approved" without
actually evaluating the policy).<a href="#section-10.2-1" class="pilcrow"></a></p>
(e.g., setting "pol_decision" to "approved" without 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>
<ul class="normal">
<li class="normal" id="section-10.2-3.1">
@@ -3418,8 +3383,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>
</li>
<li class="normal" id="section-11.1-2.3">
<p id="section-11.1-2.3.1">Policy evaluation outcomes (via "ext" keys "pol",
"pol_decision") when present, for compliance verification<a href="#section-11.1-2.3.1" class="pilcrow"></a></p>
<p id="section-11.1-2.3.1">Policy evaluation outcomes ("pol", "pol_decision") for
compliance verification<a href="#section-11.1-2.3.1" class="pilcrow"></a></p>
</li>
<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>
@@ -3451,8 +3416,8 @@ 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.
The "exec_act" claim <span class="bcp14">SHOULD</span> use structured identifiers (e.g.,
"process_payment") rather than natural language descriptions.
The "pol" extension key <span class="bcp14">SHOULD</span> reference policy identifiers
rather than embedding policy content.<a href="#section-11.2-1" class="pilcrow"></a></p>
The "pol" claim <span class="bcp14">SHOULD</span> reference policy identifiers rather than
embedding policy content.<a href="#section-11.2-1" class="pilcrow"></a></p>
<p id="section-11.2-2">The "compensation_reason" extension key in "ext"
(<a href="#compensation-claims" class="auto internal xref">Section 4.2.5</a>) deserves particular attention: because
it is human-readable, it risks exposing sensitive operational
@@ -3655,6 +3620,30 @@ 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">
<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>
</tr>
<tr>
@@ -3684,10 +3673,6 @@ the "JSON Web Token Claims" registry maintained by IANA:<a href="#section-12.3-1
</tbody>
</table>
</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>
</div>
<div id="pol-decision-registry">
@@ -4007,7 +3992,7 @@ registered as a SCITT Signed Statement on a Transparency Service.
This enables auditors to verify both the individual execution
steps (via ECT DAG validation) and the end-to-end supply chain
integrity (via SCITT Receipts) using the "wid" as the shared
correlation point. The "ext" claim in ECTs (<a href="#extension-claims" class="auto internal xref">Section 4.2.6</a>)
correlation point. The "ext" claim in ECTs (<a href="#exec-claims" class="auto internal xref">Section 4.2.2</a>)
can carry SCITT-specific metadata such as Transparency Service
identifiers or Receipt references for tighter integration.<a href="#appendix-A.6-1" class="pilcrow"></a></p>
</section>
@@ -4040,9 +4025,8 @@ 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">
<li id="appendix-B.1-2.1">
<p id="appendix-B.1-2.1.1">Create JWTs with all required claims ("iss", "aud", "iat",
"exp", "jti", "exec_act", "par") and policy extension keys
("ext.pol", "ext.pol_decision") when policy evaluation was
performed.<a href="#appendix-B.1-2.1.1" class="pilcrow"></a></p>
"exp", "jti", "exec_act", "par") and policy claims ("pol",
"pol_decision") when policy evaluation was performed.<a href="#appendix-B.1-2.1.1" class="pilcrow"></a></p>
</li>
<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
@@ -4216,12 +4200,10 @@ Agent B:<a href="#appendix-D.1-1" class="pilcrow">¶</a></p>
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"exec_act": "fetch_patient_data",
"par": [],
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "clinical_data_access_policy_v1",
"pol_decision": "approved"
}
"pol_decision": "approved",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
}
</pre><a href="#appendix-D.1-5" class="pilcrow"></a>
</div>
@@ -4238,10 +4220,8 @@ task, and creates its own ECT:<a href="#appendix-D.1-6" class="pilcrow">¶</a></
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"exec_act": "validate_safety",
"par": ["550e8400-e29b-41d4-a716-446655440001"],
"ext": {
"pol": "safety_validation_policy_v2",
"pol_decision": "approved"
}
}
</pre><a href="#appendix-D.1-7" class="pilcrow"></a>
</div>
@@ -4275,12 +4255,10 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "review_requirements_spec",
"par": [],
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "spec_review_policy_v2",
"pol_decision": "approved"
}
"pol_decision": "approved",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
}
</pre><a href="#appendix-D.2-3" class="pilcrow"></a>
</div>
@@ -4296,10 +4274,8 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "implement_module",
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
"ext": {
"pol": "coding_standards_v3",
"pol_decision": "approved"
}
}
</pre><a href="#appendix-D.2-5" class="pilcrow"></a>
</div>
@@ -4315,10 +4291,8 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "execute_test_suite",
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
"ext": {
"pol": "test_coverage_policy_v1",
"pol_decision": "approved"
}
}
</pre><a href="#appendix-D.2-7" class="pilcrow"></a>
</div>
@@ -4334,11 +4308,9 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "build_release_artifact",
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc",
"ext": {
"pol": "build_validation_v2",
"pol_decision": "approved"
}
"pol_decision": "approved",
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc"
}
</pre><a href="#appendix-D.2-9" class="pilcrow"></a>
</div>
@@ -4354,10 +4326,10 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "approve_release",
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
"ext": {
"pol": "release_approval_policy",
"pol_decision": "approved",
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
"ext": {
"witnessed_by": [
"spiffe://meddev.example/audit/qa-observer-1"
]
@@ -4429,10 +4401,8 @@ task-...-0004 (execute_trade)
"f1e2d3c4-0002-0000-0000-000000000002",
"f1e2d3c4-0003-0000-0000-000000000003"
],
"ext": {
"pol": "trade_execution_policy_v3",
"pol_decision": "approved"
}
}
</pre><a href="#appendix-D.3-4" class="pilcrow"></a>
</div>

View File

@@ -168,7 +168,7 @@ This document defines:
- The Execution Context Token (ECT) format ({{ect-format}})
- DAG structure for task dependency ordering ({{dag-validation}})
- Policy checkpoint recording via extension keys ({{policy-claims}})
- Policy checkpoint recording ({{policy-claims}})
- Integration with the WIMSE identity framework
({{wimse-integration}})
- An HTTP header for ECT transport ({{http-header}})
@@ -484,25 +484,21 @@ par:
a root task with no dependencies. A workflow MAY contain
multiple root tasks.
### Policy Evaluation Extension Keys {#policy-claims}
### Policy Evaluation {#policy-claims}
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.
The following claims record policy evaluation outcomes:
The following extension keys are defined for policy evaluation:
pol:
: 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":
: 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":
: 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:
pol_decision:
: OPTIONAL. 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
was authorized to proceed.
@@ -521,25 +517,25 @@ The following extension keys are defined for policy evaluation:
records an "approved" decision referencing this task as a
parent.
When "pol" and "pol_decision" are absent from "ext", the ECT
records task execution without a policy checkpoint. Regulated
deployments SHOULD include policy keys on all ECTs to maintain
complete audit trails.
When "pol" and "pol_decision" are absent, the ECT records task
execution without a policy checkpoint. Regulated deployments
SHOULD include policy claims on all ECTs to maintain complete
audit trails.
"pol_enforcer":
: StringOrURI. The identity of the entity (system or person)
that evaluated the policy decision. When present, SHOULD use
SPIFFE ID format.
pol_enforcer:
: OPTIONAL. StringOrURI. The identity of the entity (system or
person) that evaluated the policy decision. When present,
SHOULD use SPIFFE ID format.
This specification intentionally defines only the recording of
policy evaluation outcomes. The mechanisms by which policies are
defined, distributed to agents, and evaluated are out of scope.
The "pol" key is an opaque identifier referencing an external
The "pol" claim is an opaque identifier referencing an external
policy; the semantics and enforcement of that policy are
determined by the deployment environment. Implementations may
use any policy engine or framework (e.g., OPA/Rego, Cedar, XACML,
or custom solutions) provided that the evaluation outcome is
faithfully recorded in the "ext" keys defined above.
faithfully recorded in the ECT claims defined above.
### Data Integrity {#data-integrity-claims}
@@ -574,12 +570,9 @@ parent reference in the ECT store.
### Extensions {#extension-claims}
ext:
: OPTIONAL. Object. An extension object for claims beyond the
core registered claims. This specification defines several
extension keys for policy evaluation ({{policy-claims}}) and
operational metadata; deployments MAY also include
domain-specific keys. Implementations MUST ignore extension
keys they do not recognize.
: OPTIONAL. Object. An extension object for domain-specific
claims not defined by this specification. Implementations
that do not understand extension claims MUST ignore them.
To avoid key collisions between different domains, extension
key names SHOULD use reverse domain notation (e.g.,
@@ -593,20 +586,7 @@ exceeds these limits.
The following extension keys are defined by this specification
for common use cases. Because these keys are documented here,
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:
they use short names without reverse domain prefixes:
- "exec\_time\_ms": Integer. Execution duration in milliseconds.
- "regulated\_domain": String. Regulatory domain (e.g.,
@@ -618,6 +598,8 @@ Operational metadata keys:
attestation, witnesses should submit independent signed ECTs.
- "inp\_classification": String. Data sensitivity classification
(e.g., "public", "confidential", "restricted").
- "pol\_timestamp": NumericDate. Time at which the policy
decision was made, if distinct from "iat".
- "compensation\_required": Boolean. Indicates whether this task
is a compensation or rollback action.
- "compensation\_reason": String. Structured reason code for the
@@ -641,13 +623,14 @@ The following is a complete ECT payload example:
"exec_act": "recommend_treatment",
"par": [],
"pol": "clinical_reasoning_policy_v2",
"pol_decision": "approved",
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "clinical_reasoning_policy_v2",
"pol_decision": "approved",
"pol_enforcer": "spiffe://example.com/policy/clinical-engine",
"pol_timestamp": 1772064145,
"exec_time_ms": 245,
"regulated_domain": "medtech",
@@ -737,14 +720,14 @@ the following DAG validation steps:
lead back to the current ECT's "jti". If a cycle is detected,
the ECT MUST be rejected.
5. Parent Policy Decision: If any parent ECT's "ext" object
contains a "pol_decision" of "rejected" or
"pending_human_review", the current ECT's "exec_act" MUST
indicate a compensation, rollback, remediation, or human
review action. Implementations MUST NOT accept an ECT
representing normal workflow continuation when a parent's
"pol_decision" is not "approved". This rule only applies
when the parent ECT's "ext" contains policy keys.
5. Parent Policy Decision: If any parent ECT contains a
"pol_decision" of "rejected" or "pending_human_review", the
current ECT's "exec_act" MUST indicate a compensation,
rollback, remediation, or human review action.
Implementations MUST NOT accept an ECT representing normal
workflow continuation when a parent's "pol_decision" is not
"approved". This rule only applies when the parent ECT
contains policy claims.
6. Trust Domain Consistency: Parent tasks SHOULD belong to the
same trust domain or to a trust domain with which a federation
@@ -859,9 +842,9 @@ verification steps in order:
12. Verify all required claims ("jti", "exec_act", "par") are
present and well-formed.
13. If "ext" is present and contains "pol" or "pol_decision",
verify that both are present and that "pol_decision" is one
of "approved", "rejected", or "pending_human_review".
13. If "pol" or "pol_decision" is present, verify that both are
present and that "pol_decision" is one of "approved",
"rejected", or "pending_human_review".
14. Perform DAG validation per {{dag-validation}}.
@@ -939,12 +922,11 @@ function verify_ect(ect_jws, verifier_id,
if claim not in payload:
return reject("Missing required claim: " + claim)
// Validate policy extension keys (optional, but must be paired)
ext = payload.ext or {}
if "pol" in ext or "pol_decision" in ext:
if "pol" not in ext or "pol_decision" not in ext:
// Validate policy claims (optional, but must be paired)
if "pol" in payload or "pol_decision" in payload:
if "pol" not in payload or "pol_decision" not in payload:
return reject("pol and pol_decision must both be present")
if ext.pol_decision not in
if payload.pol_decision not in
["approved", "rejected", "pending_human_review"]:
return reject("Invalid pol_decision value")
@@ -1014,34 +996,29 @@ software used in medical devices.
Agent A (Spec Reviewer):
jti: task-001 par: []
exec_act: review_requirements_spec
ext.pol: spec_review_policy_v2
ext.pol_decision: approved
pol: spec_review_policy_v2 pol_decision: approved
Agent B (Code Generator):
jti: task-002 par: [task-001]
exec_act: implement_module
ext.pol: coding_standards_v3
ext.pol_decision: approved
pol: coding_standards_v3 pol_decision: approved
Agent C (Test Agent):
jti: task-003 par: [task-002]
exec_act: execute_test_suite
ext.pol: test_coverage_policy_v1
ext.pol_decision: approved
pol: test_coverage_policy_v1 pol_decision: approved
Agent D (Build Agent):
jti: task-004 par: [task-003]
exec_act: build_release_artifact
ext.pol: build_validation_v2
ext.pol_decision: approved
pol: build_validation_v2 pol_decision: approved
Human Release Manager:
jti: task-005 par: [task-004]
exec_act: approve_release
ext.pol: release_approval_policy
ext.pol_decision: approved
ext.pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext.witnessed_by: [...]
pol: release_approval_policy pol_decision: approved
pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext: {witnessed_by: [...]} (extension metadata)
~~~
{: #fig-medtech-sdlc title="Medical Device SDLC Workflow"}
@@ -1107,20 +1084,17 @@ execution.
Agent A (Risk Assessment):
jti: task-001 par: []
exec_act: calculate_risk_exposure
ext.pol: risk_limits_policy_v2
ext.pol_decision: approved
pol: risk_limits_policy_v2 pol_decision: approved
Agent B (Compliance):
jti: task-002 par: [task-001]
exec_act: verify_compliance
ext.pol: compliance_check_v1
ext.pol_decision: approved
pol: compliance_check_v1 pol_decision: approved
Agent C (Execution):
jti: task-003 par: [task-002]
exec_act: execute_trade
ext.pol: execution_policy_v3
ext.pol_decision: approved
pol: execution_policy_v3 pol_decision: approved
~~~
{: #fig-finance title="Financial Trading Workflow"}
@@ -1148,10 +1122,10 @@ a cryptographic link to the original task:
"wid": "d3e4f5a6-b7c8-9012-def0-123456789012",
"exec_act": "initiate_trade_rollback",
"par": ["550e8400-e29b-41d4-a716-446655440003"],
"ext": {
"pol": "compensation_policy_v1",
"pol_decision": "approved",
"pol_enforcer": "spiffe://bank.example/human/compliance-officer",
"ext": {
"compensation_required": true,
"compensation_reason": "policy_violation_in_parent_trade"
}
@@ -1173,32 +1147,27 @@ required checks were completed:
Agent A (Route Planning):
jti: task-001 par: []
exec_act: plan_route
ext.pol: route_policy_v1
ext.pol_decision: approved
pol: route_policy_v1 pol_decision: approved
Agent B (Customs):
jti: task-002 par: [task-001]
exec_act: validate_customs
ext.pol: customs_policy_v2
ext.pol_decision: approved
pol: customs_policy_v2 pol_decision: approved
Agent C (Safety):
jti: task-003 par: [task-001]
exec_act: verify_cargo_safety
ext.pol: safety_policy_v1
ext.pol_decision: approved
pol: safety_policy_v1 pol_decision: approved
Agent D (Payment):
jti: task-004 par: [task-002, task-003]
exec_act: authorize_payment
ext.pol: payment_policy_v3
ext.pol_decision: approved
pol: payment_policy_v3 pol_decision: approved
System (Commitment):
jti: task-005 par: [task-004]
exec_act: commit_shipment
ext.pol: commitment_policy_v1
ext.pol_decision: approved
pol: commitment_policy_v1 pol_decision: approved
~~~
{: #fig-logistics title="Logistics Workflow with Parallel Tasks"}
@@ -1229,8 +1198,8 @@ The following threat actors are considered:
ECTs are self-asserted by the executing agent. The agent claims
what it did, and this claim is signed with its private key. A
compromised or malicious agent could create ECTs with false claims
(e.g., setting "pol_decision" in "ext" to "approved" without
actually evaluating the policy).
(e.g., setting "pol_decision" to "approved" without actually
evaluating the policy).
ECTs do not independently verify that:
@@ -1406,8 +1375,8 @@ ECTs necessarily reveal:
- Agent identities ("iss", "aud") for accountability purposes
- Action descriptions ("exec_act") for audit trail completeness
- Policy evaluation outcomes (via "ext" keys "pol",
"pol_decision") when present, for compliance verification
- Policy evaluation outcomes ("pol", "pol_decision") for
compliance verification
- Timestamps ("iat", "exp") for temporal ordering
ECTs are designed to NOT reveal:
@@ -1423,8 +1392,8 @@ ECTs are designed to NOT reveal:
Implementations SHOULD minimize the information included in ECTs.
The "exec_act" claim SHOULD use structured identifiers (e.g.,
"process_payment") rather than natural language descriptions.
The "pol" extension key SHOULD reference policy identifiers
rather than embedding policy content.
The "pol" claim SHOULD reference policy identifiers rather than
embedding policy content.
The "compensation_reason" extension key in "ext"
({{compensation-claims}}) deserves particular attention: because
@@ -1533,16 +1502,14 @@ the "JSON Web Token Claims" registry maintained by IANA:
| wid | Workflow Identifier | IETF | {{exec-claims}} |
| exec_act | Action/Task Type | 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}} |
| out_hash | Output Data Hash | IETF | {{data-integrity-claims}} |
| ext | Extension Object | IETF | {{extension-claims}} |
{: #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}
This document establishes the "ECT Policy Decision Values"
@@ -1675,7 +1642,7 @@ registered as a SCITT Signed Statement on a Transparency Service.
This enables auditors to verify both the individual execution
steps (via ECT DAG validation) and the end-to-end supply chain
integrity (via SCITT Receipts) using the "wid" as the shared
correlation point. The "ext" claim in ECTs ({{extension-claims}})
correlation point. The "ext" claim in ECTs ({{exec-claims}})
can carry SCITT-specific metadata such as Transparency Service
identifiers or Receipt references for tighter integration.
@@ -1697,9 +1664,8 @@ use cases are distinct.
A minimal conforming implementation needs to:
1. Create JWTs with all required claims ("iss", "aud", "iat",
"exp", "jti", "exec_act", "par") and policy extension keys
("ext.pol", "ext.pol_decision") when policy evaluation was
performed.
"exp", "jti", "exec_act", "par") and policy claims ("pol",
"pol_decision") when policy evaluation was performed.
2. Sign ECTs with the agent's private key using an algorithm
matching the WIT (ES256 recommended).
3. Verify ECT signatures against WIT public keys.
@@ -1788,12 +1754,10 @@ ECT Payload:
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"exec_act": "fetch_patient_data",
"par": [],
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "clinical_data_access_policy_v1",
"pol_decision": "approved"
}
"pol_decision": "approved",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
}
~~~
@@ -1810,10 +1774,8 @@ task, and creates its own ECT:
"wid": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"exec_act": "validate_safety",
"par": ["550e8400-e29b-41d4-a716-446655440001"],
"ext": {
"pol": "safety_validation_policy_v2",
"pol_decision": "approved"
}
}
~~~
@@ -1844,12 +1806,10 @@ Task 1 (Spec Review Agent):
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "review_requirements_spec",
"par": [],
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": {
"pol": "spec_review_policy_v2",
"pol_decision": "approved"
}
"pol_decision": "approved",
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
}
~~~
@@ -1865,10 +1825,8 @@ Task 2 (Code Generation Agent):
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "implement_module",
"par": ["a1b2c3d4-0001-0000-0000-000000000001"],
"ext": {
"pol": "coding_standards_v3",
"pol_decision": "approved"
}
}
~~~
@@ -1884,10 +1842,8 @@ Task 3 (Autonomous Test Agent):
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "execute_test_suite",
"par": ["a1b2c3d4-0001-0000-0000-000000000002"],
"ext": {
"pol": "test_coverage_policy_v1",
"pol_decision": "approved"
}
}
~~~
@@ -1903,11 +1859,9 @@ Task 4 (Build Agent):
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "build_release_artifact",
"par": ["a1b2c3d4-0001-0000-0000-000000000003"],
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc",
"ext": {
"pol": "build_validation_v2",
"pol_decision": "approved"
}
"pol_decision": "approved",
"out_hash": "sha-256:Ry1YfOoW2XpC5Mq8HkGzNx3dL9vBa4sUjE7iKt0wPZc"
}
~~~
@@ -1923,10 +1877,10 @@ Task 5 (Human Release Manager Approval):
"wid": "c2d3e4f5-a6b7-8901-cdef-012345678901",
"exec_act": "approve_release",
"par": ["a1b2c3d4-0001-0000-0000-000000000004"],
"ext": {
"pol": "release_approval_policy",
"pol_decision": "approved",
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
"ext": {
"witnessed_by": [
"spiffe://meddev.example/audit/qa-observer-1"
]
@@ -1995,10 +1949,8 @@ Task 004 ECT payload:
"f1e2d3c4-0002-0000-0000-000000000002",
"f1e2d3c4-0003-0000-0000-000000000003"
],
"ext": {
"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