Implement peer review feedback for draft-nennemann-wimse-ect-00
Address 11 items from peer review: - Fix area designation from Security to ART (WIMSE is in ART area) - Switch inp_hash/out_hash to fixed SHA-256 without algorithm prefix, matching DPoP (RFC 9449) and WIMSE WPT tth claim patterns - Add partial DAG verification guidance for unavailable parents - Add DAG integrity attacks subsection (false parents, pruning, shadow DAGs) - Add privilege escalation subsection (ECTs are not authorization) - Add revocation propagation semantics through the DAG - Add W3C PROV Data Model to Related Work - Strengthen Txn-Token differentiation with fan-in/convergence bullet - Add explicit token binding paragraph to replay prevention - Switch verification step 3 to algorithm allowlist model - Add par/ext claim naming justification notes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ submissiontype: IETF
|
||||
number:
|
||||
date:
|
||||
v: 3
|
||||
area: "Security"
|
||||
area: "ART"
|
||||
workgroup: "WIMSE"
|
||||
keyword:
|
||||
- execution context
|
||||
@@ -47,6 +47,7 @@ informative:
|
||||
author:
|
||||
- org: Cloud Native Computing Foundation
|
||||
I-D.ietf-scitt-architecture:
|
||||
RFC9449:
|
||||
I-D.ietf-oauth-transaction-tokens:
|
||||
I-D.oauth-transaction-tokens-for-agents:
|
||||
|
||||
@@ -413,7 +414,9 @@ par:
|
||||
multiple root tasks. Parent ECTs may have passed their own
|
||||
"exp" time; ECT expiration applies to the verification window
|
||||
of the ECT itself, not to its validity as a parent reference
|
||||
in the ECT store.
|
||||
in the ECT store. Note: "par" is not a registered JWT claim
|
||||
and does not conflict with OAuth Pushed Authorization Requests
|
||||
(RFC 9126), which defines an endpoint, not a token claim.
|
||||
|
||||
### Data Integrity {#data-integrity-claims}
|
||||
|
||||
@@ -421,27 +424,27 @@ The following claims provide integrity verification for task
|
||||
inputs and outputs without revealing the data itself:
|
||||
|
||||
inp_hash:
|
||||
: OPTIONAL. String. A cryptographic hash of the input data,
|
||||
formatted as "hash-algorithm:base64url-encoded-hash" (e.g.,
|
||||
"sha-256:n4bQgYhMfWWaL-qgxVrQFaO\_TxsrC4Is0V1sFbDwCgg"). The
|
||||
hash algorithm identifier MUST be a lowercase value from the
|
||||
IANA Named Information Hash Algorithm Registry (e.g., "sha-256",
|
||||
"sha-384", "sha-512"). Implementations MUST support "sha-256"
|
||||
and SHOULD use "sha-256" unless a stronger algorithm is
|
||||
required. Implementations MUST NOT accept hash algorithms
|
||||
weaker than SHA-256 (e.g., MD5, SHA-1). The hash MUST be
|
||||
computed over the raw octets of the input data.
|
||||
: OPTIONAL. String. The base64url encoding (without padding) of
|
||||
the SHA-256 hash of the input data, computed over the raw octets
|
||||
of the input. This follows the same fixed-algorithm pattern
|
||||
used by the DPoP "ath" claim {{RFC9449}} and the WIMSE WPT
|
||||
"tth" claim {{I-D.ietf-wimse-s2s-protocol}}: SHA-256 is the
|
||||
mandatory algorithm with no algorithm prefix in the value.
|
||||
|
||||
out_hash:
|
||||
: OPTIONAL. String. A cryptographic hash of the output data,
|
||||
using the same format and algorithm requirements as "inp_hash".
|
||||
: OPTIONAL. String. The base64url encoding (without padding) of
|
||||
the SHA-256 hash of the output data, using the same format as
|
||||
"inp_hash".
|
||||
|
||||
### Extensions {#extension-claims}
|
||||
|
||||
ext:
|
||||
: OPTIONAL. Object. An extension object for domain-specific
|
||||
claims not defined by this specification. Implementations
|
||||
that do not understand extension claims MUST ignore them.
|
||||
: OPTIONAL. Object. A general-purpose extension object for
|
||||
domain-specific claims not defined by this specification. The
|
||||
short name "ext" follows the JWT convention of concise claim
|
||||
names and is chosen over alternatives like "extensions" for
|
||||
compactness. 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.,
|
||||
@@ -472,8 +475,12 @@ The following is a complete ECT payload example:
|
||||
"exec_act": "recommend_treatment",
|
||||
"par": [],
|
||||
|
||||
"inp_hash": "sha-256:n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||
"out_hash": "sha-256:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
|
||||
"inp_hash": "n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
|
||||
"out_hash": "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||
|
||||
"ext": {
|
||||
"com.example.trace_id": "abc123"
|
||||
}
|
||||
}
|
||||
~~~
|
||||
{: #fig-full-ect title="Complete ECT Payload Example"}
|
||||
@@ -567,6 +574,29 @@ implementations SHOULD enforce a maximum ancestor traversal limit
|
||||
(RECOMMENDED: 10000 nodes). If the limit is reached before cycle
|
||||
detection completes, the ECT SHOULD be rejected.
|
||||
|
||||
## Handling Unavailable Parent ECTs
|
||||
|
||||
In distributed deployments, a parent ECT referenced in the "par"
|
||||
array may not yet be available in the local ECT store at the time
|
||||
of validation — for example, due to replication lag in a
|
||||
distributed ledger or out-of-order message delivery.
|
||||
|
||||
Implementations MUST distinguish between two cases:
|
||||
|
||||
1. Parent not found and definitively absent: The parent "jti"
|
||||
does not exist in any accessible ECT store. The ECT MUST be
|
||||
rejected.
|
||||
|
||||
2. Parent not yet available: The parent "jti" is not present
|
||||
locally but may arrive due to known replication delays.
|
||||
Implementations MAY defer validation for a bounded period
|
||||
(RECOMMENDED: no more than 60 seconds).
|
||||
|
||||
Deferred ECTs MUST NOT be treated as verified until all parent
|
||||
references are resolved. If any parent reference remains
|
||||
unresolved after the deferral period or after the ECT's own "exp"
|
||||
time (whichever comes first), the ECT MUST be rejected.
|
||||
|
||||
# Signature and Token Verification {#verification}
|
||||
|
||||
## Verification Procedure
|
||||
@@ -579,8 +609,12 @@ verification steps in order:
|
||||
|
||||
2. Verify that the "typ" header parameter is "wimse-exec+jwt".
|
||||
|
||||
3. Verify that the "alg" header parameter is not "none" and is
|
||||
not a symmetric algorithm.
|
||||
3. Verify that the "alg" header parameter appears in the
|
||||
verifier's configured allowlist of accepted signing algorithms.
|
||||
The allowlist MUST NOT include "none" or any symmetric
|
||||
algorithm (e.g., HS256, HS384, HS512). Implementations MUST
|
||||
include ES256 in the allowlist; additional asymmetric algorithms
|
||||
MAY be included per deployment policy.
|
||||
|
||||
4. Verify the "kid" header parameter references a known, valid
|
||||
public key from a WIT within the trust domain.
|
||||
@@ -746,6 +780,12 @@ Implementations MUST maintain a cache of recently-seen "jti"
|
||||
values to detect replayed ECTs within the expiration window.
|
||||
An ECT with a duplicate "jti" value MUST be rejected.
|
||||
|
||||
Additionally, each ECT is cryptographically bound to the issuing
|
||||
agent via the JOSE "kid" parameter, which references the agent's
|
||||
WIT public key. Verifiers MUST confirm that the "kid" resolves
|
||||
to the "iss" agent's key (step 8 in {{verification}}), preventing
|
||||
one agent from replaying another agent's ECT as its own.
|
||||
|
||||
## Man-in-the-Middle Protection
|
||||
|
||||
ECTs do not replace transport-layer security. ECTs MUST be
|
||||
@@ -780,7 +820,17 @@ ledger before revocation remain valid historical records but SHOULD
|
||||
be flagged in the ledger as "signed with subsequently revoked key"
|
||||
for audit purposes.
|
||||
|
||||
## Collusion and False Claims
|
||||
ECT revocation does not propagate through the DAG. If a parent
|
||||
ECT's signing key is later revoked, child ECTs that were verified
|
||||
and recorded before that revocation remain valid — they captured
|
||||
a legitimate execution record at the time of issuance. However,
|
||||
auditors reviewing a workflow SHOULD flag any ECT in the DAG
|
||||
whose signing key was subsequently revoked, so that the scope of
|
||||
a potential compromise can be assessed. New ECTs MUST NOT be
|
||||
created with a "par" reference to an ECT whose signing key is
|
||||
known to be revoked at creation time.
|
||||
|
||||
## Collusion and False Claims {#collusion-and-false-claims}
|
||||
|
||||
A single malicious agent cannot forge parent task references
|
||||
because DAG validation requires parent tasks to exist in the
|
||||
@@ -796,6 +846,48 @@ Mitigations include:
|
||||
- Out-of-band audit: External auditors periodically verify ledger
|
||||
contents against expected workflow patterns.
|
||||
|
||||
## DAG Integrity Attacks
|
||||
|
||||
Because the DAG structure is the primary mechanism for establishing
|
||||
execution ordering, attackers may attempt to manipulate it:
|
||||
|
||||
- False parent references: A malicious agent creates an ECT that
|
||||
references parent tasks from an unrelated workflow, inserting
|
||||
itself into a legitimate execution history. DAG validation
|
||||
({{dag-validation}}) mitigates this by requiring parent existence
|
||||
in the ECT store, and the "wid" claim scopes parent references
|
||||
to a single workflow when present.
|
||||
- Parent omission (pruning): An agent deliberately omits one or
|
||||
more actual parent dependencies from the "par" array to hide
|
||||
that certain tasks influenced its output. Because ECTs are
|
||||
self-asserted ({{self-assertion-limitation}}), no mechanism can
|
||||
force an agent to declare all dependencies. External auditors
|
||||
can detect omission by comparing the declared DAG against
|
||||
expected workflow patterns.
|
||||
- Shadow DAGs: Multiple colluding agents fabricate an entire
|
||||
execution history by creating a sequence of ECTs with mutual
|
||||
parent references. Independent ledger maintenance and
|
||||
cross-verification (see {{collusion-and-false-claims}} above)
|
||||
are the primary mitigations.
|
||||
|
||||
Verifiers SHOULD validate that the declared "wid" of parent ECTs
|
||||
matches the "wid" of the child ECT, rejecting cross-workflow
|
||||
parent references unless explicitly permitted by deployment
|
||||
policy.
|
||||
|
||||
## Privilege Escalation via ECTs
|
||||
|
||||
ECTs record execution history; they do not convey authorization.
|
||||
Verifiers MUST NOT interpret the presence of an ECT, or a
|
||||
particular set of parent references in "par", as an authorization
|
||||
grant. The "par" claim demonstrates that predecessor tasks were
|
||||
recorded, not that the current agent is authorized to act on
|
||||
their outputs. Authorization decisions MUST remain with the
|
||||
identity and authorization layer (WIT, WPT, and deployment
|
||||
policy). As noted in {{I-D.ni-wimse-ai-agent-identity}},
|
||||
AI intermediaries introduce novel escalation vectors; ECTs
|
||||
MUST NOT be used to circumvent authorization boundaries.
|
||||
|
||||
## Denial of Service
|
||||
|
||||
ECT signature verification is computationally inexpensive
|
||||
@@ -1087,6 +1179,9 @@ However, "req_wl" cannot form a DAG because:
|
||||
workloads that forward the token unchanged are not recorded.
|
||||
- It carries no task-level granularity, no parent references,
|
||||
and no execution content.
|
||||
- It cannot represent convergence (fan-in): when two independent
|
||||
paths must both complete before a dependent task proceeds, a
|
||||
linear "req_wl" string cannot express that relationship.
|
||||
|
||||
Extensions for agentic use cases
|
||||
({{I-D.oauth-transaction-tokens-for-agents}}) add agent
|
||||
@@ -1120,6 +1215,19 @@ provide observability while ECTs provide signed execution records.
|
||||
ECTs may reference OpenTelemetry trace identifiers in the "ext"
|
||||
claim for correlation.
|
||||
|
||||
## W3C Provenance Data Model (PROV)
|
||||
{:numbered="false"}
|
||||
|
||||
The W3C PROV Data Model defines an Entity-Activity-Agent ontology
|
||||
for representing provenance information. PROV's concepts map
|
||||
closely to ECT structures: PROV Activities correspond to ECT
|
||||
tasks, PROV Agents correspond to WIMSE workloads, and PROV's
|
||||
"wasInformedBy" relation corresponds to ECT "par" references.
|
||||
However, PROV uses RDF/OWL ontologies designed for post-hoc
|
||||
documentation, while ECTs are runtime-embeddable JWT tokens with
|
||||
cryptographic signatures. ECT audit data could be exported to
|
||||
PROV format for interoperability with provenance-aware systems.
|
||||
|
||||
## SCITT (Supply Chain Integrity, Transparency, and Trust)
|
||||
{:numbered="false"}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user