Remove non-protocol claims and make ledger optional

Move 6 metadata claims (pol_timestamp, inp_classification,
exec_time_ms, regulated_domain, model_version, witnessed_by)
from registered JWT claims to recommended ext extension keys.
Use short key names for spec-defined extensions.

Make audit ledger explicitly optional: rename pseudocode
parameter from ledger to ect_store, mark architecture diagram
ledger layer as optional, add conditional append logic, and
soften Audit Ledger Interface language.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 23:35:03 +01:00
parent d8d1524dac
commit 898b0f8747
4 changed files with 782 additions and 777 deletions

View File

@@ -1906,8 +1906,8 @@ between the identity layer and the application layer:<a href="#section-3.2-1" cl
| |
v v
+--------------------------------------------------+ +--------------------------------------------------+
| Ledger Layer (Immutable Record) | | Optional: Audit Ledger (Immutable Record) |
| "All ECTs appended to audit ledger" | | "ECTs MAY be appended to an audit ledger" |
+--------------------------------------------------+ +--------------------------------------------------+
</pre> </pre>
</div> </div>
@@ -1978,7 +1978,8 @@ trust domain. WPT verification, if present, per
evaluated, and what precedent tasks exist.<a href="#section-3.3-7.2.1" class="pilcrow"></a></p> evaluated, and what precedent tasks exist.<a href="#section-3.3-7.2.1" class="pilcrow"></a></p>
</li> </li>
<li id="section-3.3-7.3"> <li id="section-3.3-7.3">
<p id="section-3.3-7.3.1">Ledger: Appends the verified ECT to the audit ledger.<a href="#section-3.3-7.3.1" class="pilcrow"></a></p> <p id="section-3.3-7.3.1">Ledger (if deployed): Appends the verified ECT to the audit
ledger.<a href="#section-3.3-7.3.1" class="pilcrow"></a></p>
</li> </li>
</ol> </ol>
</section> </section>
@@ -2329,42 +2330,41 @@ that do not understand extension claims <span class="bcp14">MUST</span> ignore t
<dd class="break"></dd> <dd class="break"></dd>
</dl> </dl>
<p id="section-4.2.6-2">To avoid key collisions between different domains, extension <p id="section-4.2.6-2">To avoid key collisions between different domains, extension
key names <span class="bcp14">MUST</span> use reverse domain notation (e.g., key names <span class="bcp14">SHOULD</span> use reverse domain notation (e.g.,
"com.example.custom_field"). Implementations <span class="bcp14">MUST NOT</span> use "com.example.custom_field") to avoid collisions between
unqualified key names within the "ext" object. To prevent independently developed extensions. To prevent abuse and
abuse and excessive token size, the serialized JSON excessive token size, the serialized JSON representation of
representation of the "ext" object <span class="bcp14">SHOULD NOT</span> exceed 4096 the "ext" object <span class="bcp14">SHOULD NOT</span> exceed 4096 bytes, and the JSON
bytes, and the JSON nesting depth within the "ext" object nesting depth within the "ext" object <span class="bcp14">SHOULD NOT</span> exceed 5
<span class="bcp14">SHOULD NOT</span> exceed 5 levels. Implementations <span class="bcp14">SHOULD</span> reject levels. Implementations <span class="bcp14">SHOULD</span> reject ECTs whose "ext" claim
ECTs whose "ext" claim 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 <span class="bcp14">RECOMMENDED</span> for common use <p id="section-4.2.6-3">The following extension keys are defined by this specification
cases. These are not registered claims; they are carried for common use cases. Because these keys are documented here,
within the "ext" object:<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>
<ul class="normal"> <ul class="normal">
<li class="normal" id="section-4.2.6-4.1"> <li class="normal" id="section-4.2.6-4.1">
<p id="section-4.2.6-4.1.1">"org.ietf.wimse.exec_time_ms": Integer. Execution duration in <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>
milliseconds.<a href="#section-4.2.6-4.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-4.2">
<p id="section-4.2.6-4.2.1">"org.ietf.wimse.regulated_domain": String. Regulatory domain <p id="section-4.2.6-4.2.1">"regulated_domain": String. Regulatory domain (e.g.,
(e.g., "medtech", "finance", "military").<a href="#section-4.2.6-4.2.1" class="pilcrow"></a></p> "medtech", "finance", "military").<a href="#section-4.2.6-4.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-4.3">
<p id="section-4.2.6-4.3.1">"org.ietf.wimse.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-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>
<li class="normal" id="section-4.2.6-4.4"> <li class="normal" id="section-4.2.6-4.4">
<p id="section-4.2.6-4.4.1">"org.ietf.wimse.witnessed_by": Array of StringOrURI. Identifiers <p id="section-4.2.6-4.4.1">"witnessed_by": Array of StringOrURI. Identifiers of
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-4.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-4.5">
<p id="section-4.2.6-4.5.1">"org.ietf.wimse.inp_classification": String. Data sensitivity <p id="section-4.2.6-4.5.1">"inp_classification": String. Data sensitivity classification
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-4.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-4.6">
<p id="section-4.2.6-4.6.1">"org.ietf.wimse.pol_timestamp": NumericDate. Time at which the <p id="section-4.2.6-4.6.1">"pol_timestamp": NumericDate. Time at which the policy
policy decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1" class="pilcrow"></a></p> decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1" class="pilcrow"></a></p>
</li> </li>
</ul> </ul>
</section> </section>
@@ -2401,10 +2401,10 @@ policy decision was made, if distinct from "iat".<a href="#section-4.2.6-4.6.1"
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564", "out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": { "ext": {
"org.ietf.wimse.pol_timestamp": 1772064145, "pol_timestamp": 1772064145,
"org.ietf.wimse.exec_time_ms": 245, "exec_time_ms": 245,
"org.ietf.wimse.regulated_domain": "medtech", "regulated_domain": "medtech",
"org.ietf.wimse.model_version": "clinical-reasoning-v4.2" "model_version": "clinical-reasoning-v4.2"
} }
} }
</pre> </pre>
@@ -2479,8 +2479,8 @@ provides a cryptographically signed record of execution ordering,
enabling auditors to reconstruct the complete workflow and verify enabling auditors to reconstruct the complete workflow and verify
that required predecessor tasks were recorded before dependent that required predecessor tasks were recorded before dependent
tasks.<a href="#section-6.1-1" class="pilcrow"></a></p> tasks.<a href="#section-6.1-1" class="pilcrow"></a></p>
<p id="section-6.1-2">DAG validation is performed against the audit ledger, which <p id="section-6.1-2">DAG validation is performed against the ECT store — either an
serves as the authoritative store of previously verified ECTs.<a href="#section-6.1-2" class="pilcrow"></a></p> audit ledger or the set of parent ECTs received inline.<a href="#section-6.1-2" class="pilcrow"></a></p>
</section> </section>
</div> </div>
<div id="validation-rules"> <div id="validation-rules">
@@ -2549,14 +2549,14 @@ relationship has been established.<a href="#section-6.2-2.6.1" class="pilcrow">
<figure id="figure-6"> <figure id="figure-6">
<div class="lang-pseudocode sourcecode" id="section-6.3-2.1"> <div class="lang-pseudocode sourcecode" id="section-6.3-2.1">
<pre> <pre>
function validate_dag(ect, ledger, clock_skew_tolerance): function validate_dag(ect, ect_store, clock_skew_tolerance):
// Step 1: Uniqueness check // Step 1: Uniqueness check
if ledger.contains(ect.jti, ect.wid): if ect_store.contains(ect.jti, ect.wid):
return error("ECT ID already exists") return error("ECT ID already exists")
// Step 2: Parent existence and temporal ordering // Step 2: Parent existence and temporal ordering
for parent_id in ect.par: for parent_id in ect.par:
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is null: if parent is null:
return error("Parent task not found: " + parent_id) return error("Parent task not found: " + parent_id)
if parent.iat &gt;= ect.iat + clock_skew_tolerance: if parent.iat &gt;= ect.iat + clock_skew_tolerance:
@@ -2564,14 +2564,14 @@ function validate_dag(ect, ledger, clock_skew_tolerance):
// Step 3: Cycle detection (with traversal limit) // Step 3: Cycle detection (with traversal limit)
visited = set() visited = set()
result = has_cycle(ect.jti, ect.par, ledger, visited, result = has_cycle(ect.jti, ect.par, ect_store, visited,
max_ancestor_limit) max_ancestor_limit)
if result is error or result is true: if result is error or result is true:
return error("Circular dependency or depth limit exceeded") return error("Circular dependency or depth limit exceeded")
return success return success
function has_cycle(target_jti, parent_ids, ledger, function has_cycle(target_jti, parent_ids, ect_store,
visited, max_depth): visited, max_depth):
if visited.size() &gt;= max_depth: if visited.size() &gt;= max_depth:
return error("Maximum ancestor traversal limit exceeded") return error("Maximum ancestor traversal limit exceeded")
@@ -2581,9 +2581,9 @@ function has_cycle(target_jti, parent_ids, ledger,
if parent_id in visited: if parent_id in visited:
continue continue
visited.add(parent_id) visited.add(parent_id)
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is not null: if parent is not null:
result = has_cycle(target_jti, parent.par, ledger, result = has_cycle(target_jti, parent.par, ect_store,
visited, max_depth) visited, max_depth)
if result is error or result is true: if result is error or result is true:
return result return result
@@ -2714,7 +2714,7 @@ fails.<a href="#section-7.1-4" class="pilcrow">¶</a></p>
<div class="breakable lang-pseudocode sourcecode" id="section-7.2-1.1"> <div class="breakable lang-pseudocode sourcecode" id="section-7.2-1.1">
<pre> <pre>
function verify_ect(ect_jws, verifier_id, function verify_ect(ect_jws, verifier_id,
trust_domain_keys, ledger): trust_domain_keys, ect_store):
// Parse JWS // Parse JWS
(header, payload, signature) = parse_jws(ect_jws) (header, payload, signature) = parse_jws(ect_jws)
@@ -2775,14 +2775,15 @@ function verify_ect(ect_jws, verifier_id,
["approved", "rejected", "pending_human_review"]: ["approved", "rejected", "pending_human_review"]:
return reject("Invalid pol_decision value") return reject("Invalid pol_decision value")
// Validate DAG (against ledger or inline parent ECTs) // Validate DAG (against ECT store or inline parent ECTs)
result = validate_dag(payload, ledger, result = validate_dag(payload, ect_store,
clock_skew_tolerance) clock_skew_tolerance)
if result is error: if result is error:
return reject("DAG validation failed") return reject("DAG validation failed")
// All checks passed; append to ledger // All checks passed; record if store is available
ledger.append(payload) if ect_store is not null:
ect_store.append(payload)
return accept return accept
</pre> </pre>
</div> </div>
@@ -2799,14 +2800,14 @@ function verify_ect(ect_jws, verifier_id,
<h2 id="name-audit-ledger-interface"> <h2 id="name-audit-ledger-interface">
<a href="#section-8" class="section-number selfRef">8. </a><a href="#name-audit-ledger-interface" class="section-name selfRef">Audit Ledger Interface</a> <a href="#section-8" class="section-number selfRef">8. </a><a href="#name-audit-ledger-interface" class="section-name selfRef">Audit Ledger Interface</a>
</h2> </h2>
<p id="section-8-1">ECTs are designed to be recorded in an immutable audit ledger for <p id="section-8-1">ECTs <span class="bcp14">MAY</span> be recorded in an immutable audit ledger for compliance
compliance verification and post-hoc analysis. This specification verification and post-hoc analysis. A ledger is <span class="bcp14">RECOMMENDED</span> for
defines required properties for the ledger but does not mandate regulated environments but is not required for point-to-point
a specific storage technology. Implementations <span class="bcp14">MAY</span> use operation. This specification does not mandate a specific storage
append-only logs, databases with cryptographic commitment schemes, technology. Implementations <span class="bcp14">MAY</span> use append-only logs, databases
distributed ledgers, or any storage mechanism that provides the with cryptographic commitment schemes, distributed ledgers, or
required properties.<a href="#section-8-1" class="pilcrow"></a></p> any storage mechanism that provides the required properties.<a href="#section-8-1" class="pilcrow"></a></p>
<p id="section-8-2">An audit ledger implementation <span class="bcp14">MUST</span> provide:<a href="#section-8-2" class="pilcrow"></a></p> <p id="section-8-2">When an audit ledger is deployed, the implementation <span class="bcp14">MUST</span> provide:<a href="#section-8-2" class="pilcrow"></a></p>
<ol start="1" type="1" class="normal type-1" id="section-8-3"> <ol start="1" type="1" class="normal type-1" id="section-8-3">
<li id="section-8-3.1"> <li id="section-8-3.1">
<p id="section-8-3.1.1">Append-only semantics: Once an ECT is recorded, it <span class="bcp14">MUST NOT</span> be <p id="section-8-3.1.1">Append-only semantics: Once an ECT is recorded, it <span class="bcp14">MUST NOT</span> be
@@ -2883,7 +2884,7 @@ Human Release Manager:
exec_act: approve_release exec_act: approve_release
pol: release_approval_policy pol_decision: approved pol: release_approval_policy pol_decision: approved
pol_enforcer: spiffe://meddev.example/human/release-mgr-42 pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext: {org.ietf.wimse.witnessed_by: [...]} (extension metadata) ext: {witnessed_by: [...]} (extension metadata)
</pre> </pre>
</div> </div>
<figcaption><a href="#figure-8" class="selfRef">Figure 8</a>: <figcaption><a href="#figure-8" class="selfRef">Figure 8</a>:
@@ -3167,7 +3168,7 @@ evaluating the policy).<a href="#section-10.2-1" class="pilcrow">¶</a></p>
</ul> </ul>
<p id="section-10.2-4">The trustworthiness of ECT claims depends on the trustworthiness <p id="section-10.2-4">The trustworthiness of ECT claims depends on the trustworthiness
of the signing agent. To mitigate single-agent false claims, of the signing agent. To mitigate single-agent false claims,
regulated environments <span class="bcp14">SHOULD</span> use the "org.ietf.wimse.witnessed_by" regulated environments <span class="bcp14">SHOULD</span> use the "witnessed_by"
extension key (carried in "ext") to include independent extension key (carried in "ext") to include independent
third-party observers at critical decision points. However, third-party observers at critical decision points. However,
this value is self-asserted by the ECT issuer: the listed this value is self-asserted by the ECT issuer: the listed
@@ -3181,7 +3182,7 @@ did not participate.<a href="#section-10.2-4" class="pilcrow">¶</a></p>
<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> <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>
</h4> </h4>
<p id="section-10.2.1-1">To address the self-assertion limitation of the <p id="section-10.2.1-1">To address the self-assertion limitation of the
"org.ietf.wimse.witnessed_by" extension, witnesses <span class="bcp14">SHOULD</span> submit their "witnessed_by" extension, witnesses <span class="bcp14">SHOULD</span> submit their
own independent signed ECTs to the audit ledger attesting to the 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> observed task. A witness attestation ECT:<a href="#section-10.2.1-1" class="pilcrow"></a></p>
<ul class="normal"> <ul class="normal">
@@ -3201,7 +3202,7 @@ linking the attestation to the original task.<a href="#section-10.2.1-2.3.1" cla
confirms the observation.<a href="#section-10.2.1-2.4.1" class="pilcrow"></a></p> confirms the observation.<a href="#section-10.2.1-2.4.1" class="pilcrow"></a></p>
</li> </li>
</ul> </ul>
<p id="section-10.2.1-3">When a task's "org.ietf.wimse.witnessed_by" extension lists one or more <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 witnesses, auditors <span class="bcp14">SHOULD</span> verify that corresponding witness
attestation ECTs exist in the ledger for each listed witness. A attestation ECTs exist in the ledger for each listed witness. A
mismatch between the extension value and the set of independent mismatch between the extension value and the set of independent
@@ -3353,7 +3354,7 @@ create a false execution history if they control the ledger.<a href="#section-10
by an entity independent of the workflow agents.<a href="#section-10.8-3.1.1" class="pilcrow"></a></p> by an entity independent of the workflow agents.<a href="#section-10.8-3.1.1" class="pilcrow"></a></p>
</li> </li>
<li class="normal" id="section-10.8-3.2"> <li class="normal" id="section-10.8-3.2">
<p id="section-10.8-3.2.1">Witness attestation: Using the "org.ietf.wimse.witnessed_by" extension <p id="section-10.8-3.2.1">Witness attestation: Using the "witnessed_by" extension
key in "ext" to include independent third-party observers.<a href="#section-10.8-3.2.1" class="pilcrow"></a></p> key in "ext" to include independent third-party observers.<a href="#section-10.8-3.2.1" class="pilcrow"></a></p>
</li> </li>
<li class="normal" id="section-10.8-3.3"> <li class="normal" id="section-10.8-3.3">
@@ -4412,7 +4413,7 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
"pol_decision": "approved", "pol_decision": "approved",
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42", "pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
"ext": { "ext": {
"org.ietf.wimse.witnessed_by": [ "witnessed_by": [
"spiffe://meddev.example/audit/qa-observer-1" "spiffe://meddev.example/audit/qa-observer-1"
] ]
} }
@@ -4423,7 +4424,7 @@ autonomous agents and human release approval:<a href="#appendix-D.2-1" class="pi
implementation, implementation preceded testing, testing preceded implementation, implementation preceded testing, testing preceded
build, and a human release manager approved the final release. build, and a human release manager approved the final release.
The "ext" object in task 5 carries witness metadata via The "ext" object in task 5 carries witness metadata via
the "org.ietf.wimse.witnessed_by" extension key.<a href="#appendix-D.2-12" class="pilcrow"></a></p> the "witnessed_by" extension key.<a href="#appendix-D.2-12" class="pilcrow"></a></p>
<div class="alignLeft art-text artwork" id="appendix-D.2-13"> <div class="alignLeft art-text artwork" id="appendix-D.2-13">
<pre> <pre>
task-...-0001 (review_requirements_spec) task-...-0001 (review_requirements_spec)

View File

@@ -292,8 +292,8 @@ between the identity layer and the application layer:
| |
v v
+--------------------------------------------------+ +--------------------------------------------------+
| Ledger Layer (Immutable Record) | | Optional: Audit Ledger (Immutable Record) |
| "All ECTs appended to audit ledger" | | "ECTs MAY be appended to an audit ledger" |
+--------------------------------------------------+ +--------------------------------------------------+
~~~ ~~~
{: #fig-layers title="WIMSE Extension Architecture Layers"} {: #fig-layers title="WIMSE Extension Architecture Layers"}
@@ -345,7 +345,8 @@ The receiving agent (Agent B) verifies in order:
2. ECT (this extension): Records what Agent A did, what policy was 2. ECT (this extension): Records what Agent A did, what policy was
evaluated, and what precedent tasks exist. evaluated, and what precedent tasks exist.
3. Ledger: Appends the verified ECT to the audit ledger. 3. Ledger (if deployed): Appends the verified ECT to the audit
ledger.
# Execution Context Token Format {#ect-format} # Execution Context Token Format {#ect-format}
@@ -592,32 +593,31 @@ ext:
that do not understand extension claims MUST ignore them. that do not understand extension claims MUST ignore them.
To avoid key collisions between different domains, extension To avoid key collisions between different domains, extension
key names MUST use reverse domain notation (e.g., key names SHOULD use reverse domain notation (e.g.,
"com.example.custom_field"). Implementations MUST NOT use "com.example.custom_field") to avoid collisions between
unqualified key names within the "ext" object. To prevent independently developed extensions. To prevent abuse and
abuse and excessive token size, the serialized JSON excessive token size, the serialized JSON representation of
representation of the "ext" object SHOULD NOT exceed 4096 the "ext" object SHOULD NOT exceed 4096 bytes, and the JSON
bytes, and the JSON nesting depth within the "ext" object nesting depth within the "ext" object SHOULD NOT exceed 5
SHOULD NOT exceed 5 levels. Implementations SHOULD reject levels. Implementations SHOULD reject ECTs whose "ext" claim
ECTs whose "ext" claim exceeds these limits. exceeds these limits.
The following extension keys are RECOMMENDED for common use The following extension keys are defined by this specification
cases. These are not registered claims; they are carried for common use cases. Because these keys are documented here,
within the "ext" object: they use short names without reverse domain prefixes:
- "org.ietf.wimse.exec\_time\_ms": Integer. Execution duration in - "exec\_time\_ms": Integer. Execution duration in milliseconds.
milliseconds. - "regulated\_domain": String. Regulatory domain (e.g.,
- "org.ietf.wimse.regulated\_domain": String. Regulatory domain "medtech", "finance", "military").
(e.g., "medtech", "finance", "military"). - "model\_version": String. AI/ML model version.
- "org.ietf.wimse.model\_version": String. AI/ML model version. - "witnessed\_by": Array of StringOrURI. Identifiers of
- "org.ietf.wimse.witnessed\_by": Array of StringOrURI. Identifiers third-party entities that the issuer claims observed the
of 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. attestation, witnesses should submit independent signed ECTs.
- "org.ietf.wimse.inp\_classification": String. Data sensitivity - "inp\_classification": String. Data sensitivity classification
classification (e.g., "public", "confidential", "restricted"). (e.g., "public", "confidential", "restricted").
- "org.ietf.wimse.pol\_timestamp": NumericDate. Time at which the - "pol\_timestamp": NumericDate. Time at which the policy
policy decision was made, if distinct from "iat". decision was made, if distinct from "iat".
## Complete ECT Example ## Complete ECT Example
@@ -644,10 +644,10 @@ The following is a complete ECT payload example:
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564", "out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": { "ext": {
"org.ietf.wimse.pol_timestamp": 1772064145, "pol_timestamp": 1772064145,
"org.ietf.wimse.exec_time_ms": 245, "exec_time_ms": 245,
"org.ietf.wimse.regulated_domain": "medtech", "regulated_domain": "medtech",
"org.ietf.wimse.model_version": "clinical-reasoning-v4.2" "model_version": "clinical-reasoning-v4.2"
} }
} }
~~~ ~~~
@@ -699,8 +699,8 @@ enabling auditors to reconstruct the complete workflow and verify
that required predecessor tasks were recorded before dependent that required predecessor tasks were recorded before dependent
tasks. tasks.
DAG validation is performed against the audit ledger, which DAG validation is performed against the ECT store — either an
serves as the authoritative store of previously verified ECTs. audit ledger or the set of parent ECTs received inline.
## Validation Rules ## Validation Rules
@@ -752,14 +752,14 @@ the following DAG validation steps:
The following pseudocode describes the DAG validation procedure: The following pseudocode describes the DAG validation procedure:
~~~ pseudocode ~~~ pseudocode
function validate_dag(ect, ledger, clock_skew_tolerance): function validate_dag(ect, ect_store, clock_skew_tolerance):
// Step 1: Uniqueness check // Step 1: Uniqueness check
if ledger.contains(ect.jti, ect.wid): if ect_store.contains(ect.jti, ect.wid):
return error("ECT ID already exists") return error("ECT ID already exists")
// Step 2: Parent existence and temporal ordering // Step 2: Parent existence and temporal ordering
for parent_id in ect.par: for parent_id in ect.par:
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is null: if parent is null:
return error("Parent task not found: " + parent_id) return error("Parent task not found: " + parent_id)
if parent.iat >= ect.iat + clock_skew_tolerance: if parent.iat >= ect.iat + clock_skew_tolerance:
@@ -767,14 +767,14 @@ function validate_dag(ect, ledger, clock_skew_tolerance):
// Step 3: Cycle detection (with traversal limit) // Step 3: Cycle detection (with traversal limit)
visited = set() visited = set()
result = has_cycle(ect.jti, ect.par, ledger, visited, result = has_cycle(ect.jti, ect.par, ect_store, visited,
max_ancestor_limit) max_ancestor_limit)
if result is error or result is true: if result is error or result is true:
return error("Circular dependency or depth limit exceeded") return error("Circular dependency or depth limit exceeded")
return success return success
function has_cycle(target_jti, parent_ids, ledger, function has_cycle(target_jti, parent_ids, ect_store,
visited, max_depth): visited, max_depth):
if visited.size() >= max_depth: if visited.size() >= max_depth:
return error("Maximum ancestor traversal limit exceeded") return error("Maximum ancestor traversal limit exceeded")
@@ -784,9 +784,9 @@ function has_cycle(target_jti, parent_ids, ledger,
if parent_id in visited: if parent_id in visited:
continue continue
visited.add(parent_id) visited.add(parent_id)
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is not null: if parent is not null:
result = has_cycle(target_jti, parent.par, ledger, result = has_cycle(target_jti, parent.par, ect_store,
visited, max_depth) visited, max_depth)
if result is error or result is true: if result is error or result is true:
return result return result
@@ -883,7 +883,7 @@ fails.
~~~ pseudocode ~~~ pseudocode
function verify_ect(ect_jws, verifier_id, function verify_ect(ect_jws, verifier_id,
trust_domain_keys, ledger): trust_domain_keys, ect_store):
// Parse JWS // Parse JWS
(header, payload, signature) = parse_jws(ect_jws) (header, payload, signature) = parse_jws(ect_jws)
@@ -944,29 +944,30 @@ function verify_ect(ect_jws, verifier_id,
["approved", "rejected", "pending_human_review"]: ["approved", "rejected", "pending_human_review"]:
return reject("Invalid pol_decision value") return reject("Invalid pol_decision value")
// Validate DAG (against ledger or inline parent ECTs) // Validate DAG (against ECT store or inline parent ECTs)
result = validate_dag(payload, ledger, result = validate_dag(payload, ect_store,
clock_skew_tolerance) clock_skew_tolerance)
if result is error: if result is error:
return reject("DAG validation failed") return reject("DAG validation failed")
// All checks passed; append to ledger // All checks passed; record if store is available
ledger.append(payload) if ect_store is not null:
ect_store.append(payload)
return accept return accept
~~~ ~~~
{: #fig-verification title="ECT Verification Pseudocode"} {: #fig-verification title="ECT Verification Pseudocode"}
# Audit Ledger Interface {#ledger-interface} # Audit Ledger Interface {#ledger-interface}
ECTs are designed to be recorded in an immutable audit ledger for ECTs MAY be recorded in an immutable audit ledger for compliance
compliance verification and post-hoc analysis. This specification verification and post-hoc analysis. A ledger is RECOMMENDED for
defines required properties for the ledger but does not mandate regulated environments but is not required for point-to-point
a specific storage technology. Implementations MAY use operation. This specification does not mandate a specific storage
append-only logs, databases with cryptographic commitment schemes, technology. Implementations MAY use append-only logs, databases
distributed ledgers, or any storage mechanism that provides the with cryptographic commitment schemes, distributed ledgers, or
required properties. any storage mechanism that provides the required properties.
An audit ledger implementation MUST provide: When an audit ledger is deployed, the implementation MUST provide:
1. Append-only semantics: Once an ECT is recorded, it MUST NOT be 1. Append-only semantics: Once an ECT is recorded, it MUST NOT be
modified or deleted. modified or deleted.
@@ -1031,7 +1032,7 @@ Human Release Manager:
exec_act: approve_release exec_act: approve_release
pol: release_approval_policy pol_decision: approved pol: release_approval_policy pol_decision: approved
pol_enforcer: spiffe://meddev.example/human/release-mgr-42 pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext: {org.ietf.wimse.witnessed_by: [...]} (extension metadata) ext: {witnessed_by: [...]} (extension metadata)
~~~ ~~~
{: #fig-medtech-sdlc title="Medical Device SDLC Workflow"} {: #fig-medtech-sdlc title="Medical Device SDLC Workflow"}
@@ -1222,7 +1223,7 @@ ECTs do not independently verify that:
The trustworthiness of ECT claims depends on the trustworthiness The trustworthiness of ECT claims depends on the trustworthiness
of the signing agent. To mitigate single-agent false claims, of the signing agent. To mitigate single-agent false claims,
regulated environments SHOULD use the "org.ietf.wimse.witnessed_by" regulated environments SHOULD use the "witnessed_by"
extension key (carried in "ext") to include independent extension key (carried in "ext") to include independent
third-party observers at critical decision points. However, third-party observers at critical decision points. However,
this value is self-asserted by the ECT issuer: the listed this value is self-asserted by the ECT issuer: the listed
@@ -1234,7 +1235,7 @@ did not participate.
### Witness Attestation Model {#witness-attestation-model} ### Witness Attestation Model {#witness-attestation-model}
To address the self-assertion limitation of the To address the self-assertion limitation of the
"org.ietf.wimse.witnessed_by" extension, witnesses SHOULD submit their "witnessed_by" extension, witnesses SHOULD submit their
own independent signed ECTs to the audit ledger attesting to the own independent signed ECTs to the audit ledger attesting to the
observed task. A witness attestation ECT: observed task. A witness attestation ECT:
@@ -1246,7 +1247,7 @@ observed task. A witness attestation ECT:
- MUST set "pol_decision" to "approved" to indicate the witness - MUST set "pol_decision" to "approved" to indicate the witness
confirms the observation. confirms the observation.
When a task's "org.ietf.wimse.witnessed_by" extension lists one or more When a task's "witnessed_by" extension lists one or more
witnesses, auditors SHOULD verify that corresponding witness witnesses, auditors SHOULD verify that corresponding witness
attestation ECTs exist in the ledger for each listed witness. A attestation ECTs exist in the ledger for each listed witness. A
mismatch between the extension value and the set of independent mismatch between the extension value and the set of independent
@@ -1352,7 +1353,7 @@ Mitigations include:
- Independent ledger maintenance: The ledger SHOULD be maintained - Independent ledger maintenance: The ledger SHOULD be maintained
by an entity independent of the workflow agents. by an entity independent of the workflow agents.
- Witness attestation: Using the "org.ietf.wimse.witnessed_by" extension - Witness attestation: Using the "witnessed_by" extension
key in "ext" to include independent third-party observers. key in "ext" to include independent third-party observers.
- Cross-verification: Multiple independent ledger replicas can be - Cross-verification: Multiple independent ledger replicas can be
compared for consistency. compared for consistency.
@@ -1927,7 +1928,7 @@ Task 5 (Human Release Manager Approval):
"pol_decision": "approved", "pol_decision": "approved",
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42", "pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
"ext": { "ext": {
"org.ietf.wimse.witnessed_by": [ "witnessed_by": [
"spiffe://meddev.example/audit/qa-observer-1" "spiffe://meddev.example/audit/qa-observer-1"
] ]
} }
@@ -1938,7 +1939,7 @@ The resulting DAG records the complete SDLC: spec review preceded
implementation, implementation preceded testing, testing preceded implementation, implementation preceded testing, testing preceded
build, and a human release manager approved the final release. build, and a human release manager approved the final release.
The "ext" object in task 5 carries witness metadata via The "ext" object in task 5 carries witness metadata via
the "org.ietf.wimse.witnessed_by" extension key. the "witnessed_by" extension key.
~~~ ~~~
task-...-0001 (review_requirements_spec) task-...-0001 (review_requirements_spec)

View File

@@ -409,8 +409,8 @@ Internet-Draft WIMSE Execution Context February 2026
| |
v v
+--------------------------------------------------+ +--------------------------------------------------+
| Ledger Layer (Immutable Record) | | Optional: Audit Ledger (Immutable Record) |
| "All ECTs appended to audit ledger" | | "ECTs MAY be appended to an audit ledger" |
+--------------------------------------------------+ +--------------------------------------------------+
Figure 1: WIMSE Extension Architecture Layers Figure 1: WIMSE Extension Architecture Layers
@@ -466,7 +466,8 @@ Internet-Draft WIMSE Execution Context February 2026
2. ECT (this extension): Records what Agent A did, what policy was 2. ECT (this extension): Records what Agent A did, what policy was
evaluated, and what precedent tasks exist. evaluated, and what precedent tasks exist.
3. Ledger: Appends the verified ECT to the audit ledger. 3. Ledger (if deployed): Appends the verified ECT to the audit
ledger.
4. Execution Context Token Format 4. Execution Context Token Format
@@ -497,7 +498,6 @@ Internet-Draft WIMSE Execution Context February 2026
from other JWT types, consistent with the WIMSE convention for from other JWT types, consistent with the WIMSE convention for
type parameter values. type parameter values.
kid: REQUIRED. The key identifier referencing the public key from
@@ -506,6 +506,7 @@ Nennemann Expires 28 August 2026 [Page 9]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
kid: REQUIRED. The key identifier referencing the public key from
the agent's WIT [RFC7517]. Used by verifiers to look up the the agent's WIT [RFC7517]. Used by verifiers to look up the
correct public key for signature verification. correct public key for signature verification.
@@ -556,7 +557,6 @@ Internet-Draft WIMSE Execution Context February 2026
Nennemann Expires 28 August 2026 [Page 10] Nennemann Expires 28 August 2026 [Page 10]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
@@ -734,36 +734,35 @@ Internet-Draft WIMSE Execution Context February 2026
not understand extension claims MUST ignore them. not understand extension claims MUST ignore them.
To avoid key collisions between different domains, extension key To avoid key collisions between different domains, extension key
names MUST use reverse domain notation (e.g., names SHOULD use reverse domain notation (e.g.,
"com.example.custom_field"). Implementations MUST NOT use "com.example.custom_field") to avoid collisions between independently
unqualified key names within the "ext" object. To prevent abuse and developed extensions. To prevent abuse and excessive token size, the
excessive token size, the serialized JSON representation of the "ext" serialized JSON representation of the "ext" object SHOULD NOT exceed
object SHOULD NOT exceed 4096 bytes, and the JSON nesting depth 4096 bytes, and the JSON nesting depth within the "ext" object SHOULD
within the "ext" object SHOULD NOT exceed 5 levels. Implementations NOT exceed 5 levels. Implementations SHOULD reject ECTs whose "ext"
SHOULD reject ECTs whose "ext" claim exceeds these limits. claim exceeds these limits.
The following extension keys are RECOMMENDED for common use cases. The following extension keys are defined by this specification for
These are not registered claims; they are carried within the "ext" common use cases. Because these keys are documented here, they use
object: short names without reverse domain prefixes:
* "org.ietf.wimse.exec_time_ms": Integer. Execution duration in * "exec_time_ms": Integer. Execution duration in milliseconds.
milliseconds.
* "org.ietf.wimse.regulated_domain": String. Regulatory domain * "regulated_domain": String. Regulatory domain (e.g., "medtech",
(e.g., "medtech", "finance", "military"). "finance", "military").
* "org.ietf.wimse.model_version": String. AI/ML model version. * "model_version": String. AI/ML model version.
* "org.ietf.wimse.witnessed_by": Array of StringOrURI. Identifiers * "witnessed_by": Array of StringOrURI. Identifiers of third-party
of third-party entities that the issuer claims observed the task. entities that the issuer claims observed the task. Note: this is
Note: this is self-asserted; for verifiable witness attestation, self-asserted; for verifiable witness attestation, witnesses
witnesses should submit independent signed ECTs. should submit independent signed ECTs.
* "org.ietf.wimse.inp_classification": String. Data sensitivity * "inp_classification": String. Data sensitivity classification
classification (e.g., "public", "confidential", "restricted"). (e.g., "public", "confidential", "restricted").
* "org.ietf.wimse.pol_timestamp": NumericDate. Time at which the * "pol_timestamp": NumericDate. Time at which the policy decision
policy decision was made, if distinct from "iat". was made, if distinct from "iat".
4.3. Complete ECT Example 4.3. Complete ECT Example
@@ -781,6 +780,7 @@ Internet-Draft WIMSE Execution Context February 2026
Nennemann Expires 28 August 2026 [Page 14] Nennemann Expires 28 August 2026 [Page 14]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
@@ -806,10 +806,10 @@ Internet-Draft WIMSE Execution Context February 2026
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564", "out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
"ext": { "ext": {
"org.ietf.wimse.pol_timestamp": 1772064145, "pol_timestamp": 1772064145,
"org.ietf.wimse.exec_time_ms": 245, "exec_time_ms": 245,
"org.ietf.wimse.regulated_domain": "medtech", "regulated_domain": "medtech",
"org.ietf.wimse.model_version": "clinical-reasoning-v4.2" "model_version": "clinical-reasoning-v4.2"
} }
} }
@@ -865,8 +865,8 @@ Internet-Draft WIMSE Execution Context February 2026
auditors to reconstruct the complete workflow and verify that auditors to reconstruct the complete workflow and verify that
required predecessor tasks were recorded before dependent tasks. required predecessor tasks were recorded before dependent tasks.
DAG validation is performed against the audit ledger, which serves as DAG validation is performed against the ECT store — either an audit
the authoritative store of previously verified ECTs. ledger or the set of parent ECTs received inline.
6.2. Validation Rules 6.2. Validation Rules
@@ -954,14 +954,14 @@ Nennemann Expires 28 August 2026 [Page 17]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
function validate_dag(ect, ledger, clock_skew_tolerance): function validate_dag(ect, ect_store, clock_skew_tolerance):
// Step 1: Uniqueness check // Step 1: Uniqueness check
if ledger.contains(ect.jti, ect.wid): if ect_store.contains(ect.jti, ect.wid):
return error("ECT ID already exists") return error("ECT ID already exists")
// Step 2: Parent existence and temporal ordering // Step 2: Parent existence and temporal ordering
for parent_id in ect.par: for parent_id in ect.par:
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is null: if parent is null:
return error("Parent task not found: " + parent_id) return error("Parent task not found: " + parent_id)
if parent.iat >= ect.iat + clock_skew_tolerance: if parent.iat >= ect.iat + clock_skew_tolerance:
@@ -969,14 +969,14 @@ Internet-Draft WIMSE Execution Context February 2026
// Step 3: Cycle detection (with traversal limit) // Step 3: Cycle detection (with traversal limit)
visited = set() visited = set()
result = has_cycle(ect.jti, ect.par, ledger, visited, result = has_cycle(ect.jti, ect.par, ect_store, visited,
max_ancestor_limit) max_ancestor_limit)
if result is error or result is true: if result is error or result is true:
return error("Circular dependency or depth limit exceeded") return error("Circular dependency or depth limit exceeded")
return success return success
function has_cycle(target_jti, parent_ids, ledger, function has_cycle(target_jti, parent_ids, ect_store,
visited, max_depth): visited, max_depth):
if visited.size() >= max_depth: if visited.size() >= max_depth:
return error("Maximum ancestor traversal limit exceeded") return error("Maximum ancestor traversal limit exceeded")
@@ -986,9 +986,9 @@ Internet-Draft WIMSE Execution Context February 2026
if parent_id in visited: if parent_id in visited:
continue continue
visited.add(parent_id) visited.add(parent_id)
parent = ledger.get(parent_id) parent = ect_store.get(parent_id)
if parent is not null: if parent is not null:
result = has_cycle(target_jti, parent.par, ledger, result = has_cycle(target_jti, parent.par, ect_store,
visited, max_depth) visited, max_depth)
if result is error or result is true: if result is error or result is true:
return result return result
@@ -1100,7 +1100,7 @@ Internet-Draft WIMSE Execution Context February 2026
7.2. Verification Pseudocode 7.2. Verification Pseudocode
function verify_ect(ect_jws, verifier_id, function verify_ect(ect_jws, verifier_id,
trust_domain_keys, ledger): trust_domain_keys, ect_store):
// Parse JWS // Parse JWS
(header, payload, signature) = parse_jws(ect_jws) (header, payload, signature) = parse_jws(ect_jws)
@@ -1169,7 +1169,7 @@ Internet-Draft WIMSE Execution Context February 2026
["approved", "rejected", "pending_human_review"]: ["approved", "rejected", "pending_human_review"]:
return reject("Invalid pol_decision value") return reject("Invalid pol_decision value")
// Validate DAG (against ledger or inline parent ECTs) // Validate DAG (against ECT store or inline parent ECTs)
@@ -1178,28 +1178,29 @@ Nennemann Expires 28 August 2026 [Page 21]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
result = validate_dag(payload, ledger, result = validate_dag(payload, ect_store,
clock_skew_tolerance) clock_skew_tolerance)
if result is error: if result is error:
return reject("DAG validation failed") return reject("DAG validation failed")
// All checks passed; append to ledger // All checks passed; record if store is available
ledger.append(payload) if ect_store is not null:
ect_store.append(payload)
return accept return accept
Figure 7: ECT Verification Pseudocode Figure 7: ECT Verification Pseudocode
8. Audit Ledger Interface 8. Audit Ledger Interface
ECTs are designed to be recorded in an immutable audit ledger for ECTs MAY be recorded in an immutable audit ledger for compliance
compliance verification and post-hoc analysis. This specification verification and post-hoc analysis. A ledger is RECOMMENDED for
defines required properties for the ledger but does not mandate a regulated environments but is not required for point-to-point
specific storage technology. Implementations MAY use append-only operation. This specification does not mandate a specific storage
logs, databases with cryptographic commitment schemes, distributed technology. Implementations MAY use append-only logs, databases with
ledgers, or any storage mechanism that provides the required cryptographic commitment schemes, distributed ledgers, or any storage
properties. mechanism that provides the required properties.
An audit ledger implementation MUST provide: When an audit ledger is deployed, the implementation MUST provide:
1. Append-only semantics: Once an ECT is recorded, it MUST NOT be 1. Append-only semantics: Once an ECT is recorded, it MUST NOT be
modified or deleted. modified or deleted.
@@ -1228,7 +1229,6 @@ Internet-Draft WIMSE Execution Context February 2026
Nennemann Expires 28 August 2026 [Page 22] Nennemann Expires 28 August 2026 [Page 22]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
@@ -1271,7 +1271,7 @@ Internet-Draft WIMSE Execution Context February 2026
exec_act: approve_release exec_act: approve_release
pol: release_approval_policy pol_decision: approved pol: release_approval_policy pol_decision: approved
pol_enforcer: spiffe://meddev.example/human/release-mgr-42 pol_enforcer: spiffe://meddev.example/human/release-mgr-42
ext: {org.ietf.wimse.witnessed_by: [...]} (extension metadata) ext: {witnessed_by: [...]} (extension metadata)
Figure 8: Medical Device SDLC Workflow Figure 8: Medical Device SDLC Workflow
@@ -1536,20 +1536,20 @@ Internet-Draft WIMSE Execution Context February 2026
The trustworthiness of ECT claims depends on the trustworthiness of The trustworthiness of ECT claims depends on the trustworthiness of
the signing agent. To mitigate single-agent false claims, regulated the signing agent. To mitigate single-agent false claims, regulated
environments SHOULD use the "org.ietf.wimse.witnessed_by" extension environments SHOULD use the "witnessed_by" extension key (carried in
key (carried in "ext") to include independent third-party observers "ext") to include independent third-party observers at critical
at critical decision points. However, this value is self-asserted by decision points. However, this value is self-asserted by the ECT
the ECT issuer: the listed witnesses do not co-sign the ECT and there issuer: the listed witnesses do not co-sign the ECT and there is no
is no cryptographic evidence within a single ECT that the witnesses cryptographic evidence within a single ECT that the witnesses
actually observed the task. An issuing agent could list witnesses actually observed the task. An issuing agent could list witnesses
that did not participate. that did not participate.
10.2.1. Witness Attestation Model 10.2.1. Witness Attestation Model
To address the self-assertion limitation of the To address the self-assertion limitation of the "witnessed_by"
"org.ietf.wimse.witnessed_by" extension, witnesses SHOULD submit extension, witnesses SHOULD submit their own independent signed ECTs
their own independent signed ECTs to the audit ledger attesting to to the audit ledger attesting to the observed task. A witness
the observed task. A witness attestation ECT: attestation ECT:
* MUST set "iss" to the witness's own workload identity. * MUST set "iss" to the witness's own workload identity.
@@ -1570,11 +1570,11 @@ Nennemann Expires 28 August 2026 [Page 28]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
When a task's "org.ietf.wimse.witnessed_by" extension lists one or When a task's "witnessed_by" extension lists one or more witnesses,
more witnesses, auditors SHOULD verify that corresponding witness auditors SHOULD verify that corresponding witness attestation ECTs
attestation ECTs exist in the ledger for each listed witness. A exist in the ledger for each listed witness. A mismatch between the
mismatch between the extension value and the set of independent extension value and the set of independent witness ECTs in the ledger
witness ECTs in the ledger SHOULD be flagged during audit review. SHOULD be flagged during audit review.
This model converts witness attestation from a self-asserted claim to This model converts witness attestation from a self-asserted claim to
a cryptographically verifiable property of the ledger: the witness a cryptographically verifiable property of the ledger: the witness
@@ -1702,9 +1702,8 @@ Internet-Draft WIMSE Execution Context February 2026
* Independent ledger maintenance: The ledger SHOULD be maintained by * Independent ledger maintenance: The ledger SHOULD be maintained by
an entity independent of the workflow agents. an entity independent of the workflow agents.
* Witness attestation: Using the "org.ietf.wimse.witnessed_by" * Witness attestation: Using the "witnessed_by" extension key in
extension key in "ext" to include independent third-party "ext" to include independent third-party observers.
observers.
* Cross-verification: Multiple independent ledger replicas can be * Cross-verification: Multiple independent ledger replicas can be
compared for consistency. compared for consistency.
@@ -1733,6 +1732,7 @@ Internet-Draft WIMSE Execution Context February 2026
Nennemann Expires 28 August 2026 [Page 31] Nennemann Expires 28 August 2026 [Page 31]
Internet-Draft WIMSE Execution Context February 2026 Internet-Draft WIMSE Execution Context February 2026
@@ -2611,7 +2611,7 @@ Internet-Draft WIMSE Execution Context February 2026
"pol_decision": "approved", "pol_decision": "approved",
"pol_enforcer": "spiffe://meddev.example/human/release-mgr-42", "pol_enforcer": "spiffe://meddev.example/human/release-mgr-42",
"ext": { "ext": {
"org.ietf.wimse.witnessed_by": [ "witnessed_by": [
"spiffe://meddev.example/audit/qa-observer-1" "spiffe://meddev.example/audit/qa-observer-1"
] ]
} }
@@ -2621,7 +2621,7 @@ Internet-Draft WIMSE Execution Context February 2026
implementation, implementation preceded testing, testing preceded implementation, implementation preceded testing, testing preceded
build, and a human release manager approved the final release. The build, and a human release manager approved the final release. The
"ext" object in task 5 carries witness metadata via the "ext" object in task 5 carries witness metadata via the
"org.ietf.wimse.witnessed_by" extension key. "witnessed_by" extension key.

File diff suppressed because it is too large Load Diff