Drop versioned directories and archive/ in favor of git tags (draft-00, draft-01) for frozen submissions. Rename source to draft-nennemann-wimse-ect.md (version comes from docname in front matter). Update build.sh to extract docname automatically. Ignore generated outputs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1478 lines
54 KiB
Markdown
1478 lines
54 KiB
Markdown
---
|
|
title: "Execution Context Tokens for Distributed Agentic Workflows"
|
|
abbrev: "WIMSE Execution Context"
|
|
category: std
|
|
docname: draft-nennemann-wimse-ect-01
|
|
submissiontype: IETF
|
|
number:
|
|
date:
|
|
v: 3
|
|
area: "ART"
|
|
workgroup: "WIMSE"
|
|
keyword:
|
|
- execution context
|
|
- workload identity
|
|
- agentic workflows
|
|
- audit trail
|
|
- assurance levels
|
|
|
|
author:
|
|
-
|
|
fullname: Christian Nennemann
|
|
organization: Independent Researcher
|
|
email: ietf@nennemann.de
|
|
|
|
normative:
|
|
RFC7515:
|
|
RFC7517:
|
|
RFC7519:
|
|
RFC7518:
|
|
RFC9562:
|
|
RFC9110:
|
|
|
|
informative:
|
|
RFC8693:
|
|
I-D.ietf-wimse-arch:
|
|
I-D.ietf-wimse-s2s-protocol:
|
|
SPIFFE:
|
|
title: "Secure Production Identity Framework for Everyone (SPIFFE)"
|
|
target: https://spiffe.io/docs/latest/spiffe-about/overview/
|
|
date: false
|
|
OPENTELEMETRY:
|
|
title: "OpenTelemetry Specification"
|
|
target: https://opentelemetry.io/docs/specs/otel/
|
|
date: false
|
|
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:
|
|
|
|
--- abstract
|
|
|
|
This document defines Execution Context Tokens (ECTs), a JWT-based
|
|
mechanism for recording task execution across distributed agentic
|
|
workflows. Each ECT captures a single task, linked to predecessor
|
|
tasks through a directed acyclic graph (DAG). ECTs are transported
|
|
in a new Execution-Context HTTP header field. While designed for
|
|
use with the WIMSE architecture, ECTs are identity-framework
|
|
agnostic and can operate with any asymmetric key infrastructure
|
|
including WIMSE WIT/WPT, X.509 certificates, OAuth-based
|
|
credentials, or plain JWK sets.
|
|
|
|
This revision introduces three assurance levels — Level 1
|
|
(unsigned JSON), Level 2 (JOSE asymmetric signing), and Level 3
|
|
(JOSE signing with audit ledger) — allowing deployments to choose
|
|
the appropriate trade-off between simplicity and regulatory
|
|
compliance.
|
|
|
|
--- middle
|
|
|
|
# Introduction
|
|
|
|
Frameworks such as WIMSE {{I-D.ietf-wimse-arch}} authenticate
|
|
workloads across call chains but do not record what those workloads
|
|
actually did. This document defines Execution Context Tokens
|
|
(ECTs), a JWT-based mechanism that fills the gap between workload
|
|
identity and execution accountability. Each ECT captures a single
|
|
task, linked to predecessor tasks through a directed acyclic graph
|
|
(DAG). ECTs are designed for use with the WIMSE signing model but
|
|
can operate with any identity framework that provides asymmetric
|
|
key pairs with verifiable binding to agent identity.
|
|
|
|
## Scope and Applicability
|
|
|
|
This document defines:
|
|
|
|
- The Execution Context Token (ECT) format ({{ect-format}})
|
|
- Three assurance levels for ECT production and verification
|
|
({{level-1}}, {{level-2}}, {{level-3}})
|
|
- DAG structure for task dependency ordering ({{dag-validation}})
|
|
- An HTTP header for ECT transport ({{http-header}})
|
|
- Audit ledger interface requirements ({{ledger-interface}})
|
|
|
|
The following are out of scope and are handled by the deployment's
|
|
identity framework (e.g., WIMSE, X.509 PKI, OAuth):
|
|
|
|
- Workload authentication and identity provisioning
|
|
- Key distribution and management
|
|
- Trust domain establishment and management
|
|
- Credential lifecycle management
|
|
|
|
## Assurance Levels and Applicability {#assurance-levels}
|
|
|
|
ECTs support three assurance levels that govern how tokens are
|
|
produced, transported, and verified. Each level builds on the
|
|
payload structure defined in {{ect-payload}}.
|
|
|
|
Level 1 (L1) — Unsigned JSON:
|
|
: ECTs are plain JSON objects with no cryptographic signature.
|
|
Integrity depends on transport security (TLS). L1 is intended
|
|
for internal deployments within a single trust domain where
|
|
non-repudiation is not required, such as development
|
|
environments or internal microservice meshes.
|
|
|
|
Level 2 (L2) — JOSE Asymmetric Signing:
|
|
: ECTs are signed as JWS Compact Serialization tokens using
|
|
asymmetric keys bound to the agent's identity credential.
|
|
L2 provides non-repudiation and tamper detection. This is
|
|
the baseline assurance level for cross-organization and
|
|
peer-to-peer deployments. L2 corresponds to the behavior
|
|
defined in draft-nennemann-wimse-ect-00.
|
|
|
|
Level 3 (L3) — JOSE Signing with Audit Ledger:
|
|
: L3 extends L2 by requiring that every ECT be recorded in an
|
|
audit ledger with cryptographic commitment (hash chain, Merkle
|
|
tree, or equivalent). L3 is intended for regulated environments
|
|
that require hash-committed audit trails with tamper-evident
|
|
history.
|
|
|
|
Assurance level selection is orthogonal to human-in-the-loop
|
|
(HITL) policy: any level may be combined with HITL requirements.
|
|
Level selection guidance is provided in {{level-selection}}.
|
|
|
|
# Conventions and Definitions
|
|
|
|
{::boilerplate bcp14-tagged}
|
|
|
|
The following terms are used in this document:
|
|
|
|
Agent:
|
|
: An autonomous workload that executes tasks within a workflow.
|
|
In WIMSE deployments, this corresponds to a WIMSE workload
|
|
{{I-D.ietf-wimse-arch}}.
|
|
|
|
Task:
|
|
: A discrete unit of agent work that consumes inputs and produces
|
|
outputs.
|
|
|
|
Directed Acyclic Graph (DAG):
|
|
: A graph structure representing task dependency ordering where
|
|
edges are directed and no cycles exist.
|
|
|
|
Execution Context Token (ECT):
|
|
: A token defined by this specification that records task execution
|
|
details. At Level 2 and Level 3, an ECT is a signed JSON Web
|
|
Token {{RFC7519}}. At Level 1, an ECT is an unsigned JSON
|
|
object with the same payload structure.
|
|
|
|
Identity Credential:
|
|
: A credential that proves an agent's identity, such as a WIMSE
|
|
Workload Identity Token (WIT), an X.509 certificate, an OAuth
|
|
client credential, or a JWK with out-of-band binding. See
|
|
{{identity-binding}}.
|
|
|
|
Assurance Level:
|
|
: One of three tiers (L1, L2, L3) governing how an ECT is
|
|
produced, transported, and verified. See {{assurance-levels}}.
|
|
|
|
Audit Ledger:
|
|
: An append-only, immutable log of all ECTs within a workflow or
|
|
set of workflows, used for audit and verification.
|
|
|
|
Trust Domain:
|
|
: An administrative boundary within which agents share a common
|
|
identity authority. In WIMSE deployments, this corresponds to
|
|
a SPIFFE {{SPIFFE}} trust domain.
|
|
|
|
# Execution Context Token Format {#ect-format}
|
|
|
|
An Execution Context Token records a single task in a distributed
|
|
workflow. The ECT payload structure is common across all assurance
|
|
levels; only the envelope and verification requirements differ.
|
|
|
|
## ECT Payload Structure {#ect-payload}
|
|
|
|
The ECT payload is a JSON object containing the claims defined in
|
|
this section.
|
|
|
|
### Standard Claims
|
|
|
|
The following standard JWT claims {{RFC7519}} are defined for ECTs:
|
|
|
|
iss:
|
|
: RECOMMENDED. StringOrURI. A URI identifying the issuer of the
|
|
ECT. The value MUST correspond to the agent's identity as
|
|
asserted by its identity credential (see {{identity-binding}}).
|
|
In WIMSE deployments, this SHOULD be the workload's SPIFFE ID
|
|
in the format `spiffe://<trust-domain>/<path>`. Other
|
|
deployments MAY use HTTPS URLs, URN:UUID identifiers, or other
|
|
URI schemes appropriate to the identity framework in use. The
|
|
"iss" claim is REQUIRED for L2 and L3 deployments (see
|
|
{{l2-verification}} and {{l3-verification}}).
|
|
|
|
aud:
|
|
: RECOMMENDED. StringOrURI or array of StringOrURI. The intended
|
|
recipient(s) of the ECT. The "aud" claim SHOULD contain the
|
|
identifiers of all entities that will verify the ECT. When
|
|
an ECT must be verified by both the next agent and the audit
|
|
ledger independently, "aud" MUST be an array containing both
|
|
identifiers. Each verifier checks that its own identity
|
|
appears in "aud". The "aud" claim is REQUIRED for L2 and L3
|
|
deployments (see {{l2-verification}} and {{l3-verification}}).
|
|
|
|
iat:
|
|
: REQUIRED. NumericDate. The time at which the ECT was issued.
|
|
|
|
exp:
|
|
: REQUIRED. NumericDate. The expiration time of the ECT.
|
|
Implementations SHOULD set this to 5 to 15 minutes after "iat".
|
|
|
|
jti:
|
|
: REQUIRED. String. A unique identifier for both the ECT and
|
|
the task it records, in UUID format {{RFC9562}}. The "jti"
|
|
serves as both the token identifier (for replay detection) and
|
|
the task identifier (for DAG parent references in "par").
|
|
Receivers MUST reject ECTs whose "jti" has already been seen
|
|
within the expiration window. When "wid" is present,
|
|
uniqueness is scoped to the workflow; when "wid" is absent,
|
|
uniqueness MUST be enforced globally across the ECT store.
|
|
|
|
### Execution Context Claims {#exec-claims}
|
|
|
|
The following claims are defined by this specification:
|
|
|
|
wid:
|
|
: OPTIONAL. String. A workflow identifier that groups related
|
|
ECTs into a single workflow. When present, MUST be a UUID
|
|
{{RFC9562}}.
|
|
|
|
exec_act:
|
|
: REQUIRED. String. The action or task type identifier describing
|
|
what the agent performed (e.g., "process_payment",
|
|
"validate_safety"). This claim name avoids collision with the
|
|
"act" (Actor) claim registered by {{RFC8693}}.
|
|
|
|
par:
|
|
: REQUIRED. Array of strings. Parent task identifiers
|
|
representing DAG dependencies. Each element MUST be the "jti"
|
|
value of a previously verified ECT. An empty array indicates
|
|
a root task with no dependencies. A workflow MAY contain
|
|
multiple root tasks.
|
|
|
|
### Data Integrity Claims {#data-integrity-claims}
|
|
|
|
The following claims provide integrity verification for task
|
|
inputs and outputs without revealing the data itself:
|
|
|
|
inp_hash:
|
|
: OPTIONAL. String. The base64url encoding (without padding) of
|
|
the SHA-256 hash of the input data, computed over the raw octets
|
|
of the input. SHA-256 is the mandatory algorithm with no
|
|
algorithm prefix in the value, consistent with {{RFC9449}} and
|
|
{{I-D.ietf-wimse-s2s-protocol}}.
|
|
|
|
out_hash:
|
|
: OPTIONAL. String. The base64url encoding (without padding) of
|
|
the SHA-256 hash of the output data, using the same format as
|
|
"inp_hash".
|
|
|
|
### Extension Claims {#extension-claims}
|
|
|
|
ext:
|
|
: OPTIONAL. Object. A general-purpose extension object for
|
|
domain-specific claims not defined by this specification.
|
|
Implementations that do not understand extension claims MUST
|
|
ignore them. Extension key names SHOULD use reverse domain
|
|
notation (e.g., "com.example.custom_field") to avoid
|
|
collisions. The serialized "ext" object SHOULD NOT exceed
|
|
4096 bytes and SHOULD NOT exceed a nesting depth of 5 levels.
|
|
|
|
## Complete ECT Payload Example
|
|
|
|
The following is a complete ECT payload example. This payload
|
|
structure is the same at all assurance levels; only the transport
|
|
envelope differs.
|
|
|
|
~~~json
|
|
{
|
|
"iss": "spiffe://example.com/agent/clinical",
|
|
"aud": "spiffe://example.com/agent/safety",
|
|
"iat": 1772064150,
|
|
"exp": 1772064750,
|
|
"jti": "550e8400-e29b-41d4-a716-446655440001",
|
|
|
|
"wid": "a0b1c2d3-e4f5-6789-abcd-ef0123456789",
|
|
"exec_act": "recommend_treatment",
|
|
"par": [],
|
|
|
|
"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"}
|
|
|
|
## Level 1: Unsigned JSON {#level-1}
|
|
|
|
At Level 1, an ECT is a plain JSON object carrying the payload
|
|
defined in {{ect-payload}}. No cryptographic signature is applied.
|
|
|
|
### L1 Transport {#l1-transport}
|
|
|
|
L1 ECTs are transported as serialized JSON. Two mechanisms are
|
|
defined:
|
|
|
|
HTTP Header:
|
|
: The Execution-Context header field ({{http-header}}) carries
|
|
the base64url-encoded JSON payload (without padding).
|
|
|
|
HTTP Body:
|
|
: When the ECT is the primary request payload, the ECT MAY be
|
|
carried in the HTTP request body with Content-Type
|
|
`application/json`.
|
|
|
|
L1 ECTs MUST be transmitted over TLS or mTLS connections.
|
|
Transport security is the sole integrity mechanism at this level.
|
|
|
|
### L1 Verification {#l1-verification}
|
|
|
|
When an agent receives an L1 ECT, it MUST perform the following
|
|
verification steps:
|
|
|
|
1. Parse the JSON object.
|
|
|
|
2. Verify that all required claims ("jti", "iat", "exp",
|
|
"exec_act", "par") are present and well-formed.
|
|
|
|
3. Verify the "exp" claim indicates the ECT has not expired.
|
|
|
|
4. Verify the "iat" claim is not unreasonably far in the past
|
|
(RECOMMENDED maximum: 15 minutes) and is not unreasonably
|
|
far in the future (RECOMMENDED: no more than 30 seconds
|
|
ahead of the verifier's current time).
|
|
|
|
5. Perform DAG validation per {{dag-validation}}.
|
|
|
|
If any verification step fails, the ECT MUST be rejected and the
|
|
failure MUST be logged.
|
|
|
|
### L1 Security Properties and Applicability {#l1-security}
|
|
|
|
L1 provides the following security properties:
|
|
|
|
- Structural integrity via JSON schema validation
|
|
- Temporal ordering via "iat" and "exp" claims
|
|
- DAG integrity via parent reference validation
|
|
- Transport integrity via TLS
|
|
|
|
L1 does NOT provide:
|
|
|
|
- Non-repudiation (no signature binds the ECT to its issuer)
|
|
- Tamper detection after delivery (the recipient cannot prove
|
|
the ECT was not modified after receipt)
|
|
- Issuer authentication at the ECT layer (identity depends
|
|
entirely on the transport layer)
|
|
|
|
L1 MUST NOT be used across trust domain boundaries.
|
|
Deployments using L1 SHOULD restrict it to internal environments
|
|
where all agents are operated by the same organization and
|
|
transport security is considered sufficient.
|
|
|
|
## Level 2: JOSE Asymmetric Signing {#level-2}
|
|
|
|
At Level 2, an ECT is a JSON Web Token (JWT) {{RFC7519}} signed
|
|
as a JSON Web Signature (JWS) {{RFC7515}}. L2 corresponds to the
|
|
signing behavior defined in draft-nennemann-wimse-ect-00.
|
|
|
|
ECTs MUST use JWS Compact Serialization (the base64url-encoded
|
|
`header.payload.signature` format) so that they can be carried in
|
|
a single HTTP header value.
|
|
|
|
The ECT MUST be signed with a private key that is verifiably
|
|
bound to the agent's identity credential (see
|
|
{{identity-binding}}). The JOSE header "kid" parameter MUST
|
|
reference the public key identifier from the agent's identity
|
|
credential, and the "alg" parameter MUST match the algorithm
|
|
associated with that credential.
|
|
|
|
### L2 JOSE Header {#jose-header}
|
|
|
|
The ECT JOSE header MUST contain the following parameters:
|
|
|
|
~~~json
|
|
{
|
|
"alg": "ES256",
|
|
"typ": "exec+jwt",
|
|
"kid": "agent-a-key-id-123"
|
|
}
|
|
~~~
|
|
{: #fig-header title="ECT JOSE Header Example"}
|
|
|
|
alg:
|
|
: REQUIRED. The digital signature algorithm used to sign the ECT.
|
|
MUST match the algorithm associated with the agent's identity
|
|
credential. Implementations MUST support ES256 {{RFC7518}}.
|
|
The "alg" value MUST NOT be "none". Symmetric algorithms
|
|
(e.g., HS256, HS384, HS512) MUST NOT be used, as ECTs require
|
|
asymmetric signatures for non-repudiation.
|
|
|
|
typ:
|
|
: REQUIRED. MUST be set to "exec+jwt" to distinguish ECTs from
|
|
other JWT types. WIMSE deployments MAY use "wimse-exec+jwt"
|
|
for backward compatibility with draft-nennemann-wimse-ect-00.
|
|
Verifiers MUST accept both values.
|
|
|
|
kid:
|
|
: REQUIRED. The key identifier referencing the public key from
|
|
the agent's identity credential {{RFC7517}}. Used by verifiers
|
|
to look up the correct public key for signature verification.
|
|
In WIMSE deployments, this references the WIT public key. In
|
|
X.509 deployments, this MAY be the certificate thumbprint or
|
|
subject key identifier.
|
|
|
|
### L2 Transport {#l2-transport}
|
|
|
|
L2 ECTs are transported in the Execution-Context HTTP header
|
|
field ({{http-header}}) as JWS Compact Serialization. The header
|
|
field value consists of three Base64url-encoded parts separated by
|
|
period (".") characters.
|
|
|
|
L2 ECTs MUST be transmitted over TLS or mTLS connections.
|
|
|
|
### L2 Verification {#l2-verification}
|
|
|
|
When an agent receives an L2 ECT, it MUST perform the following
|
|
verification steps in order:
|
|
|
|
1. Parse the JWS Compact Serialization to extract the JOSE header,
|
|
payload, and signature components per {{RFC7515}}.
|
|
|
|
2. Verify that the "typ" header parameter is "exec+jwt" or
|
|
"wimse-exec+jwt".
|
|
|
|
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 an identity credential within the trust domain
|
|
(see {{identity-binding}}).
|
|
|
|
5. Retrieve the public key identified by "kid" and verify the JWS
|
|
signature per {{RFC7515}} Section 5.2.
|
|
|
|
6. Verify that the signing key identified by "kid" has not been
|
|
revoked within the trust domain. Implementations MUST check
|
|
the key's revocation status using the identity framework's key
|
|
lifecycle mechanism (e.g., certificate revocation list, OCSP,
|
|
SPIFFE trust bundle updates, or JWK set rotation).
|
|
|
|
7. Verify the "alg" header parameter matches the algorithm
|
|
associated with the agent's identity credential.
|
|
|
|
8. Verify the "iss" claim is present and matches the agent
|
|
identity asserted by the identity credential associated with
|
|
the "kid" public key (see {{identity-binding}}).
|
|
|
|
9. Verify the "aud" claim is present and contains the verifier's
|
|
own identity. When "aud" is an array, it is sufficient that
|
|
the verifier's identity appears as one element; the presence
|
|
of other audience values does not cause verification failure.
|
|
When the verifier is the audit ledger, the ledger's own
|
|
identity MUST appear in "aud".
|
|
|
|
10. Verify the "exp" claim indicates the ECT has not expired.
|
|
|
|
11. Verify the "iat" claim is not unreasonably far in the past
|
|
(implementation-specific threshold, RECOMMENDED maximum of
|
|
15 minutes) and is not unreasonably far in the future
|
|
(RECOMMENDED: no more than 30 seconds ahead of the
|
|
verifier's current time, to account for clock skew).
|
|
|
|
12. Verify all required claims ("jti", "exec_act", "par") are
|
|
present and well-formed.
|
|
|
|
13. Perform DAG validation per {{dag-validation}}.
|
|
|
|
14. If all checks pass and an audit ledger is deployed, the ECT
|
|
SHOULD be appended to the ledger.
|
|
|
|
If any verification step fails, the ECT MUST be rejected and the
|
|
failure MUST be logged for audit purposes. Error messages
|
|
SHOULD NOT reveal whether specific parent task IDs exist in the
|
|
ECT store, to prevent information disclosure.
|
|
|
|
### L2 Security Properties and Applicability {#l2-security}
|
|
|
|
L2 provides the following security properties:
|
|
|
|
- Non-repudiation (the ECT is cryptographically bound to the
|
|
issuing agent via asymmetric signature)
|
|
- Tamper detection (any modification invalidates the signature)
|
|
- Issuer authentication (the "kid" links to the agent's identity
|
|
credential)
|
|
- Audience restriction (the "aud" claim limits valid verifiers)
|
|
- All L1 properties (structural, temporal, DAG, transport
|
|
integrity)
|
|
|
|
L2 is suitable for cross-organization deployments, peer-to-peer
|
|
agent communication, and any deployment requiring cryptographic
|
|
non-repudiation. L2 is the RECOMMENDED default for production
|
|
deployments.
|
|
|
|
## Level 3: JOSE Signing with Audit Ledger {#level-3}
|
|
|
|
Level 3 extends Level 2 by requiring that every ECT be recorded
|
|
in an audit ledger that provides cryptographic commitment. L3
|
|
transport and JWS signing are identical to L2; the additional
|
|
requirements apply to ledger recording and verification.
|
|
|
|
### L3 Transport {#l3-transport}
|
|
|
|
L3 ECTs use the same JWS Compact Serialization transport as L2
|
|
(see {{l2-transport}}).
|
|
|
|
### L3 Audit Ledger Requirements {#l3-ledger}
|
|
|
|
At Level 3, the audit ledger MUST satisfy the baseline
|
|
requirements defined in {{ledger-interface}} and the following
|
|
additional requirements:
|
|
|
|
1. Hash Chain: Each ledger entry MUST include a cryptographic
|
|
hash of the previous entry, forming a hash chain. The hash
|
|
algorithm MUST be SHA-256 or stronger.
|
|
|
|
2. Cryptographic Commitment: The ledger MUST provide a
|
|
mechanism for verifiable cryptographic commitment over its
|
|
entries, such as Merkle tree proofs, hash chains with signed
|
|
roots, or equivalent constructions. The commitment MUST
|
|
allow a verifier to confirm that a specific ECT is included
|
|
in the ledger at a specific position without trusting the
|
|
ledger operator.
|
|
|
|
3. Receipts: Upon successful append, the ledger MUST return a
|
|
receipt to the submitting agent. The receipt MUST contain
|
|
the ledger sequence number, the hash of the appended ECT
|
|
entry, and the cryptographic commitment proof (e.g., Merkle
|
|
inclusion proof) at the time of recording.
|
|
|
|
4. Availability: The ledger MUST be accessible for verification
|
|
queries by authorized entities within the trust domain.
|
|
|
|
### L3 Recording Semantics {#l3-recording}
|
|
|
|
An agent producing an L3 ECT MUST attempt to record the ECT in
|
|
the audit ledger. Two recording modes are defined:
|
|
|
|
Synchronous Recording:
|
|
: The agent submits the ECT to the ledger and waits for a receipt
|
|
before transmitting the ECT to the next agent. Synchronous
|
|
recording provides the strongest guarantee: the ECT is
|
|
committed to the ledger before any downstream processing
|
|
occurs.
|
|
|
|
Asynchronous Recording:
|
|
: The agent submits the ECT to the ledger and transmits the ECT
|
|
to the next agent without waiting for a receipt. The agent
|
|
MUST subsequently verify that the ledger accepted the ECT and
|
|
MUST retain the receipt. If the ledger rejects the ECT, the
|
|
agent MUST alert the workflow coordinator or log a critical
|
|
error.
|
|
|
|
Deployments SHOULD use synchronous recording unless latency
|
|
constraints make it impractical. The recording mode SHOULD be
|
|
documented in the deployment's security policy.
|
|
|
|
### L3 Verification {#l3-verification}
|
|
|
|
L3 verification consists of L2 verification ({{l2-verification}})
|
|
followed by ledger verification:
|
|
|
|
1. Perform all L2 verification steps (steps 1 through 14 of
|
|
{{l2-verification}}).
|
|
|
|
2. Verify the "iss" claim is present (REQUIRED at L3).
|
|
|
|
3. Verify the "aud" claim is present (REQUIRED at L3).
|
|
|
|
4. Submit the ECT to the audit ledger for recording per
|
|
{{l3-recording}}.
|
|
|
|
5. Verify that the ledger returned a valid receipt containing
|
|
the sequence number, ECT hash, and cryptographic commitment
|
|
proof.
|
|
|
|
6. If synchronous recording is required by deployment policy and
|
|
the ledger does not return a receipt within the configured
|
|
timeout, the ECT MUST be treated as unverified.
|
|
|
|
If any L3-specific verification step fails, the ECT MUST be
|
|
rejected even if L2 verification succeeded.
|
|
|
|
### L3 Security Properties and Applicability {#l3-security}
|
|
|
|
L3 provides the following security properties beyond L2:
|
|
|
|
- Tamper-evident history (the hash chain detects any
|
|
modification, insertion, or deletion of ledger entries)
|
|
- Cryptographic commitment (Merkle proofs or equivalent allow
|
|
independent verification of ledger inclusion)
|
|
- Non-repudiation of recording (the receipt proves the ECT was
|
|
committed at a specific time and position)
|
|
- All L2 properties
|
|
|
|
L3 is intended for regulated environments requiring auditable,
|
|
tamper-evident execution records, such as healthcare (FDA 21 CFR
|
|
Part 11), financial services (MiFID II), and environments subject
|
|
to the EU AI Act.
|
|
|
|
## Level Selection {#level-selection}
|
|
|
|
Deployments SHOULD select the assurance level based on the
|
|
following criteria:
|
|
|
|
- Use L1 when all agents operate within a single trust domain,
|
|
non-repudiation is not required, and transport security (TLS)
|
|
is considered sufficient. Typical environments: development,
|
|
testing, internal microservice meshes.
|
|
|
|
- Use L2 when agents cross trust domain boundaries, when
|
|
non-repudiation is required, or when agents communicate
|
|
peer-to-peer across organizations. L2 is the RECOMMENDED
|
|
default for production deployments.
|
|
|
|
- Use L3 when regulatory requirements mandate tamper-evident
|
|
audit trails with cryptographic commitment, or when the
|
|
deployment must demonstrate compliance with frameworks such as
|
|
FDA 21 CFR Part 11, MiFID II, or the EU AI Act.
|
|
|
|
A deployment MAY use different assurance levels for different
|
|
workflows within the same infrastructure. When agents at
|
|
different levels interact, the higher level's verification
|
|
requirements apply to the receiving agent.
|
|
|
|
## Backward Compatibility and Level Detection {#level-detection}
|
|
|
|
A verifier determines the assurance level of a received ECT as
|
|
follows:
|
|
|
|
1. If the Execution-Context header value or body content parses
|
|
as valid JSON (not JWS Compact Serialization), the ECT is L1.
|
|
|
|
2. If the value parses as JWS Compact Serialization (three
|
|
Base64url-encoded segments separated by periods), the ECT is
|
|
L2 or L3.
|
|
|
|
3. L2 and L3 use the same JWS format. Differentiation between
|
|
L2 and L3 is a matter of deployment policy: L3 deployments
|
|
require ledger recording ({{l3-ledger}}), while L2
|
|
deployments treat ledger recording as optional.
|
|
|
|
Implementations compliant with draft-nennemann-wimse-ect-00 are
|
|
L2-compatible. No changes to existing -00 implementations are
|
|
required for L2 interoperability.
|
|
|
|
## Identity Binding {#identity-binding}
|
|
|
|
At L2 and L3, the ECT signing key MUST be verifiably bound to the
|
|
agent's identity. This specification defines the abstract
|
|
requirements for identity binding; concrete bindings are
|
|
defined for specific identity frameworks.
|
|
|
|
An identity binding MUST satisfy the following requirements:
|
|
|
|
1. Key Association: The "kid" value in the ECT JOSE header MUST
|
|
resolve to a public key through the identity framework's key
|
|
discovery mechanism.
|
|
|
|
2. Issuer Correspondence: The "iss" claim in the ECT payload
|
|
MUST correspond to the agent identity asserted by the identity
|
|
credential containing the "kid" public key.
|
|
|
|
3. Algorithm Consistency: The "alg" value in the ECT JOSE header
|
|
MUST match the algorithm associated with the identity
|
|
credential.
|
|
|
|
4. Revocation Checking: The verifier MUST be able to determine
|
|
whether the signing key has been revoked using the identity
|
|
framework's revocation mechanism.
|
|
|
|
### WIMSE Binding {#wimse-binding}
|
|
|
|
When the deployment uses the WIMSE framework
|
|
{{I-D.ietf-wimse-arch}}:
|
|
|
|
- The ECT "kid" references the public key from the agent's
|
|
Workload Identity Token (WIT).
|
|
- The ECT "iss" SHOULD be the workload's SPIFFE ID {{SPIFFE}},
|
|
matching the "sub" claim of the WIT.
|
|
- The ECT "alg" MUST match the algorithm in the WIT.
|
|
- Revocation is checked via the SPIFFE trust bundle or the trust
|
|
domain's key lifecycle mechanism.
|
|
- ECTs are transported alongside the WIT and WPT
|
|
({{I-D.ietf-wimse-s2s-protocol}}) in HTTP requests.
|
|
|
|
### X.509 Binding {#x509-binding}
|
|
|
|
When the deployment uses X.509 certificates:
|
|
|
|
- The ECT "kid" MAY be the certificate thumbprint (x5t) or
|
|
subject key identifier.
|
|
- The ECT "iss" SHOULD be a URI derived from the certificate
|
|
subject or subject alternative name.
|
|
- Revocation is checked via CRL or OCSP.
|
|
|
|
### JWK Set Binding {#jwk-binding}
|
|
|
|
When the deployment uses plain JWK sets {{RFC7517}} with
|
|
out-of-band trust establishment:
|
|
|
|
- The ECT "kid" MUST match the "kid" parameter in a JWK from
|
|
the trusted JWK set.
|
|
- The ECT "iss" MUST match a value associated with the JWK
|
|
through the deployment's configuration.
|
|
- Revocation is handled by removing the key from the published
|
|
JWK set.
|
|
|
|
# HTTP Header Transport {#http-header}
|
|
|
|
## Execution-Context Header Field
|
|
|
|
This specification defines the Execution-Context HTTP header field
|
|
{{RFC9110}} for transporting ECTs between agents.
|
|
|
|
The format of the header field value depends on the assurance
|
|
level:
|
|
|
|
- At Level 1, the header field value is the base64url-encoded
|
|
JSON payload (without padding).
|
|
|
|
- At Level 2 and Level 3, the header field value is the ECT in
|
|
JWS Compact Serialization format {{RFC7515}}. The value
|
|
consists of three Base64url-encoded parts separated by period
|
|
(".") characters.
|
|
|
|
An agent sending a request to another agent includes the
|
|
Execution-Context header alongside any identity headers required
|
|
by the deployment's identity framework. In WIMSE deployments,
|
|
agents include the Workload-Identity header and, when available,
|
|
the Workload Proof Token (WPT) per
|
|
{{I-D.ietf-wimse-s2s-protocol}}.
|
|
|
|
~~~
|
|
GET /api/safety-check HTTP/1.1
|
|
Host: safety-agent.example.com
|
|
Authorization: Bearer <identity-token>
|
|
Execution-Context: eyJhbGci...ECT...
|
|
~~~
|
|
{: #fig-http-example title="HTTP Request with ECT Header"}
|
|
|
|
When multiple parent tasks contribute context to a single request,
|
|
multiple Execution-Context header field lines MAY be included, each
|
|
carrying a separate ECT. This applies to all assurance levels.
|
|
|
|
When a receiver processes multiple Execution-Context headers, it
|
|
MUST individually verify each ECT per the applicable verification
|
|
procedure ({{l1-verification}}, {{l2-verification}}, or
|
|
{{l3-verification}}). If any single ECT fails verification, the
|
|
receiver MUST reject the entire request. The set of verified
|
|
parent task IDs across all received ECTs represents the complete
|
|
set of parent dependencies available for the receiving agent's
|
|
subsequent ECT.
|
|
|
|
# DAG Validation {#dag-validation}
|
|
|
|
ECTs form a Directed Acyclic Graph (DAG) where each task
|
|
references its parent tasks via the "par" claim. DAG validation
|
|
is performed against the ECT store — either an audit ledger or
|
|
the set of parent ECTs received inline.
|
|
|
|
DAG validation applies regardless of assurance level.
|
|
|
|
When receiving and verifying an ECT, implementations MUST perform
|
|
the following DAG validation steps:
|
|
|
|
1. Task ID Uniqueness: The "jti" claim MUST be unique within the
|
|
applicable scope (the workflow identified by "wid", or the
|
|
entire ECT store if "wid" is absent). If an ECT with the same
|
|
"jti" already exists, the ECT MUST be rejected.
|
|
|
|
2. Parent Existence: Every task identifier listed in the "par"
|
|
array MUST correspond to a task that is available in the ECT
|
|
store (either previously recorded in the ledger or received
|
|
inline as a verified parent ECT). If any parent task is not
|
|
found, the ECT MUST be rejected.
|
|
|
|
3. Temporal Ordering: The "iat" value of every parent task MUST
|
|
NOT be greater than the "iat" value of the current task plus a
|
|
configurable clock skew tolerance (RECOMMENDED: 30 seconds).
|
|
That is, for each parent: `parent.iat < child.iat +
|
|
clock_skew_tolerance`. The tolerance accounts for clock skew
|
|
between agents; it does not guarantee strict causal ordering
|
|
from timestamps alone. Causal ordering is primarily enforced
|
|
by the DAG structure (parent existence in the ECT store), not by
|
|
timestamps. If any parent task violates this constraint, the
|
|
ECT MUST be rejected.
|
|
|
|
4. Acyclicity: Following the chain of parent references MUST NOT
|
|
lead back to the current ECT's "jti". If a cycle is detected,
|
|
the ECT MUST be rejected.
|
|
|
|
5. Trust Domain Consistency: Parent tasks SHOULD belong to the
|
|
same trust domain or to a trust domain with which a federation
|
|
relationship has been established.
|
|
|
|
To prevent denial-of-service via extremely deep or wide DAGs,
|
|
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.
|
|
|
|
In distributed deployments, a parent ECT may not yet be available
|
|
locally due to replication lag. Implementations MAY defer
|
|
validation to allow parent ECTs to arrive, but MUST NOT treat
|
|
the ECT as verified until all parent references are resolved.
|
|
|
|
# Signature and Token Verification {#verification}
|
|
|
|
## Level Detection
|
|
|
|
Before performing verification, the verifier MUST determine the
|
|
assurance level of the received ECT per {{level-detection}}. If
|
|
the ECT is L1 (unsigned JSON), the verifier follows the L1
|
|
verification procedure ({{l1-verification}}) and skips all
|
|
signature-related steps. If the ECT is L2 or L3 (JWS), the
|
|
verifier follows the L2 verification procedure
|
|
({{l2-verification}}) and, for L3 deployments, the additional
|
|
ledger verification steps ({{l3-verification}}).
|
|
|
|
## L2/L3 Verification Procedure
|
|
|
|
The L2 verification procedure is defined in {{l2-verification}}.
|
|
For L3 deployments, the additional steps in {{l3-verification}}
|
|
MUST also be performed.
|
|
|
|
## HTTP Error Handling
|
|
|
|
When ECT verification fails during HTTP request processing, the
|
|
receiving agent SHOULD respond with HTTP 403 (Forbidden) if the
|
|
agent's identity credential is valid but the ECT is invalid, and
|
|
HTTP 401 (Unauthorized) if the ECT signature verification fails.
|
|
The response body SHOULD include a generic error indicator without
|
|
revealing which specific verification step failed. The receiving
|
|
agent MUST NOT process the requested action when ECT verification
|
|
fails.
|
|
|
|
# Audit Ledger Interface {#ledger-interface}
|
|
|
|
ECTs MAY be recorded in an immutable audit ledger for compliance
|
|
verification and post-hoc analysis. A ledger is OPTIONAL for L1
|
|
and L2 deployments but is REQUIRED for L3 deployments. This
|
|
specification does not mandate a specific storage technology.
|
|
Implementations MAY use append-only logs, databases with
|
|
cryptographic commitment schemes, distributed ledgers, or any
|
|
storage mechanism that provides the required properties.
|
|
|
|
## Baseline Ledger Requirements
|
|
|
|
When an audit ledger is deployed, the implementation MUST provide:
|
|
|
|
1. Append-only semantics: Once an ECT is recorded, it MUST NOT be
|
|
modified or deleted.
|
|
|
|
2. Ordering: The ledger MUST maintain a total ordering of ECT
|
|
entries via a monotonically increasing sequence number.
|
|
|
|
3. Lookup by ECT ID: The ledger MUST support efficient retrieval
|
|
of ECT entries by "jti" value.
|
|
|
|
4. Integrity verification: The ledger SHOULD provide a mechanism
|
|
to verify that no entries have been tampered with (e.g.,
|
|
hash chains or Merkle trees).
|
|
|
|
The ledger SHOULD be maintained by an entity independent of the
|
|
workflow agents to reduce the risk of collusion.
|
|
|
|
## L3 Ledger Requirements
|
|
|
|
At Level 3, the audit ledger MUST satisfy the baseline
|
|
requirements above and the additional requirements defined in
|
|
{{l3-ledger}}. In particular:
|
|
|
|
- Each entry MUST include a cryptographic hash of the previous
|
|
entry, forming a verifiable hash chain.
|
|
|
|
- The ledger MUST provide cryptographic commitment proofs
|
|
(Merkle tree proofs, signed hash chain roots, or equivalent).
|
|
|
|
- The ledger MUST return a receipt upon successful append,
|
|
containing the sequence number, entry hash, and commitment
|
|
proof.
|
|
|
|
## Ledger Independence
|
|
|
|
The audit ledger SHOULD be operated by an entity that is
|
|
independent of the workflow agents. When the ledger operator and
|
|
the workflow agents are controlled by the same organization,
|
|
additional safeguards SHOULD be implemented, such as separation
|
|
of duties between ledger administrators and agent operators, or
|
|
independent ledger replicas maintained by third parties.
|
|
|
|
## L3 Ledger Verification
|
|
|
|
Auditors verifying L3 ledger integrity SHOULD perform the
|
|
following checks:
|
|
|
|
1. Verify the hash chain: for each entry, recompute the hash of
|
|
the previous entry and confirm it matches the recorded value.
|
|
|
|
2. Verify the cryptographic commitment: validate Merkle inclusion
|
|
proofs (or equivalent) for a sample or all entries.
|
|
|
|
3. Verify ECT signatures: for each ECT in the ledger, perform
|
|
the L2 verification procedure ({{l2-verification}}) using
|
|
the public keys valid at the time of recording.
|
|
|
|
4. Verify DAG consistency: confirm that all parent references in
|
|
all ECTs resolve to valid entries in the ledger.
|
|
|
|
# Security Considerations
|
|
|
|
## Threat Model
|
|
|
|
The threat model considers: (1) a malicious agent that creates
|
|
false ECT claims, (2) an agent whose private key has been
|
|
compromised, (3) a ledger tamperer attempting to modify recorded
|
|
entries, and (4) a time manipulator altering timestamps to affect
|
|
perceived ordering.
|
|
|
|
## Level-Specific Security Properties {#level-security}
|
|
|
|
### Level 1
|
|
|
|
L1 provides no cryptographic binding between the ECT and its
|
|
issuer. A compromised or malicious intermediary with access to
|
|
the transport channel can modify L1 ECTs without detection after
|
|
delivery. L1 does not provide non-repudiation: the issuer can
|
|
deny having produced an ECT, and the receiver cannot prove
|
|
otherwise.
|
|
|
|
L1 MUST NOT be used across trust domain boundaries. L1 is
|
|
appropriate only when all agents are operated by the same
|
|
organization, the transport channel is fully trusted (e.g.,
|
|
service mesh with mTLS), and the deployment does not require
|
|
non-repudiation or tamper evidence beyond transport security.
|
|
|
|
### Level 2
|
|
|
|
L2 inherits all security properties of the JWS-based ECT
|
|
mechanism defined in this document. The existing security
|
|
analysis (signature verification, replay prevention, key
|
|
compromise, collusion) applies directly to L2.
|
|
|
|
### Level 3
|
|
|
|
L3 provides all L2 security properties plus tamper-evident
|
|
history via the audit ledger's hash chain and cryptographic
|
|
commitment. Modifications to ledger entries are detectable
|
|
through hash chain verification. Deletions or insertions are
|
|
detectable through Merkle proof validation.
|
|
|
|
L3 does not prevent a compromised ledger operator from refusing
|
|
to record entries (censorship), but the submitting agent's receipt
|
|
mechanism ({{l3-ledger}}) provides evidence of submission.
|
|
Deployments concerned about ledger censorship SHOULD use multiple
|
|
independent ledger replicas.
|
|
|
|
## Self-Assertion Limitation {#self-assertion-limitation}
|
|
|
|
ECTs are self-asserted by the executing agent. The agent claims
|
|
what it did, and this claim is signed with its private key (at L2
|
|
and L3). A compromised or malicious agent could create ECTs with
|
|
false claims (e.g., claiming an action was performed when it was
|
|
not).
|
|
|
|
ECTs do not independently verify that:
|
|
|
|
- The claimed execution actually occurred as described
|
|
- The input/output hashes correspond to the actual data processed
|
|
- The agent faithfully performed the stated action
|
|
|
|
The trustworthiness of ECT claims depends on the trustworthiness
|
|
of the signing agent and the integrity of the broader deployment
|
|
environment. ECTs provide a technical mechanism for execution
|
|
recording; they do not by themselves satisfy any specific
|
|
regulatory compliance requirement.
|
|
|
|
## Signature Verification
|
|
|
|
For L2 and L3 deployments, ECTs MUST be signed with the agent's
|
|
private key using JWS {{RFC7515}}. The signature algorithm MUST
|
|
match the algorithm associated with the agent's identity
|
|
credential (see {{identity-binding}}). Receivers MUST verify the
|
|
ECT signature against the corresponding public key before
|
|
processing any claims. Receivers MUST verify that the signing key
|
|
has not been revoked within the trust domain (see step 6 in
|
|
{{l2-verification}}).
|
|
|
|
If signature verification fails or if the signing key has been
|
|
revoked, the ECT MUST be rejected entirely and the failure MUST
|
|
be logged.
|
|
|
|
Implementations MUST use established JWS libraries and MUST NOT
|
|
implement custom signature verification.
|
|
|
|
## Replay Attack Prevention
|
|
|
|
ECTs include short expiration times (RECOMMENDED: 5-15 minutes)
|
|
and audience restriction via "aud" to limit replay attacks.
|
|
Implementations MUST maintain a cache of recently-seen "jti"
|
|
values and MUST reject ECTs with duplicate "jti" values. For
|
|
L2 and L3, each ECT is cryptographically bound to the issuing
|
|
agent via "kid"; verifiers MUST confirm that "kid" resolves to
|
|
the "iss" agent's key (step 8 in {{l2-verification}}).
|
|
|
|
## Man-in-the-Middle Protection
|
|
|
|
ECTs MUST be transmitted over TLS or mTLS connections. When used
|
|
with WIMSE {{I-D.ietf-wimse-s2s-protocol}} or similar service
|
|
mesh protocols, transport security is already established.
|
|
|
|
## Key Compromise
|
|
|
|
If an agent's private key is compromised, an attacker can forge
|
|
ECTs that appear to originate from that agent. Mitigations:
|
|
|
|
- Implementations SHOULD use short-lived keys and rotate them
|
|
frequently.
|
|
- Private keys SHOULD be stored in hardware security modules or
|
|
equivalent secure key storage.
|
|
- Trust domains MUST support rapid key revocation.
|
|
|
|
ECTs recorded before key revocation remain valid historical
|
|
records but SHOULD be flagged for audit purposes. New ECTs
|
|
MUST NOT reference a parent ECT whose signing key is known to
|
|
be revoked at creation time.
|
|
|
|
## Collusion and DAG Integrity {#collusion-and-false-claims}
|
|
|
|
A single malicious agent cannot forge parent task references
|
|
because DAG validation requires parent tasks to exist in the ECT
|
|
store. However, multiple colluding agents could create a false
|
|
execution history. Additionally, a malicious agent may omit
|
|
actual parent dependencies from "par" to hide influences on its
|
|
output; because ECTs are self-asserted
|
|
({{self-assertion-limitation}}), no mechanism can force complete
|
|
dependency declaration.
|
|
|
|
Mitigations include:
|
|
|
|
- The ledger SHOULD be maintained by an entity independent of the
|
|
workflow agents.
|
|
- Multiple independent ledger replicas can be compared for
|
|
consistency.
|
|
- External auditors can compare the declared DAG against expected
|
|
workflow patterns.
|
|
|
|
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. Authorization decisions MUST remain with the deployment's
|
|
identity and authorization layer.
|
|
|
|
## Denial of Service
|
|
|
|
Implementations SHOULD apply rate limiting to prevent excessive
|
|
ECT submissions. For L2 and L3, DAG validation SHOULD be
|
|
performed after signature verification to avoid wasting resources
|
|
on unsigned or incorrectly signed tokens. L1 ECTs are cheaper
|
|
to validate (no signature verification) but are correspondingly
|
|
easier for an attacker to generate; L1 deployments SHOULD apply
|
|
stricter rate limits to compensate.
|
|
|
|
## Timestamp Accuracy
|
|
|
|
Implementations SHOULD use synchronized time sources (e.g., NTP)
|
|
and SHOULD allow a configurable clock skew tolerance (RECOMMENDED:
|
|
30 seconds). Cross-organizational deployments MAY require a
|
|
higher tolerance and SHOULD document the configured value.
|
|
|
|
## ECT Size Constraints
|
|
|
|
Implementations SHOULD limit the "par" array to a maximum of
|
|
256 entries. See {{extension-claims}} for "ext" size limits.
|
|
|
|
# Privacy Considerations
|
|
|
|
## Data Exposure in ECTs
|
|
|
|
ECTs necessarily reveal:
|
|
|
|
- Agent identities ("iss", "aud") for accountability purposes
|
|
- Action descriptions ("exec_act") for audit trail completeness
|
|
- Timestamps ("iat", "exp") for temporal ordering
|
|
|
|
ECTs are designed to NOT reveal:
|
|
|
|
- Actual input or output data values (replaced with cryptographic
|
|
hashes via "inp_hash" and "out_hash")
|
|
- Internal computation details or intermediate steps
|
|
- Proprietary algorithms or intellectual property
|
|
- Personally identifiable information (PII)
|
|
|
|
Privacy exposure is equivalent across all assurance levels: the
|
|
ECT payload contains the same claims regardless of whether the
|
|
ECT is unsigned (L1), signed (L2), or signed with ledger
|
|
recording (L3). L3 ledger recording increases the durability of
|
|
the privacy-relevant data but does not increase its scope.
|
|
|
|
## Data Minimization {#data-minimization}
|
|
|
|
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.
|
|
Extension keys in "ext" ({{extension-claims}}) deserve particular
|
|
attention: human-readable values risk exposing sensitive operational
|
|
details. See {{extension-claims}} for guidance on using
|
|
structured identifiers.
|
|
|
|
## Storage and Access Control
|
|
|
|
ECTs stored in audit ledgers SHOULD be access-controlled so that
|
|
only authorized auditors can read them. Implementations SHOULD
|
|
consider encryption at rest for ledger storage. ECTs provide
|
|
structural records of execution ordering; they are not intended
|
|
for public disclosure.
|
|
|
|
Full input and output data (corresponding to the hashes in ECTs)
|
|
SHOULD be stored separately from the ledger with additional access
|
|
controls, since auditors may need to verify hash correctness but
|
|
general access to the data values is not needed.
|
|
|
|
# IANA Considerations
|
|
|
|
## Media Type Registrations
|
|
|
|
This document requests registration of the following media types
|
|
in the "Media Types" registry maintained by IANA:
|
|
|
|
### application/exec+jwt
|
|
|
|
Type name:
|
|
: application
|
|
|
|
Subtype name:
|
|
: exec+jwt
|
|
|
|
Required parameters:
|
|
: none
|
|
|
|
Optional parameters:
|
|
: none
|
|
|
|
Encoding considerations:
|
|
: 8bit; at Level 2 and Level 3, an ECT is a JWT that is a JWS
|
|
using the Compact Serialization, which is a sequence of
|
|
Base64url-encoded values separated by period characters. At
|
|
Level 1, this media type is not used; L1 ECTs use
|
|
application/json.
|
|
|
|
Security considerations:
|
|
: See the Security Considerations section of this document.
|
|
|
|
Interoperability considerations:
|
|
: none
|
|
|
|
Published specification:
|
|
: This document
|
|
|
|
Applications that use this media type:
|
|
: Applications that implement agentic workflows requiring execution
|
|
context tracing and audit trails.
|
|
|
|
Additional information:
|
|
: Magic number(s): none
|
|
File extension(s): none
|
|
Macintosh file type code(s): none
|
|
|
|
Person and email address to contact for further information:
|
|
: Christian Nennemann, ietf@nennemann.de
|
|
|
|
Intended usage:
|
|
: COMMON
|
|
|
|
Restrictions on usage:
|
|
: none
|
|
|
|
Author:
|
|
: Christian Nennemann
|
|
|
|
Change controller:
|
|
: IETF
|
|
|
|
### application/wimse-exec+jwt
|
|
|
|
This document also registers "application/wimse-exec+jwt" as an
|
|
alias for backward compatibility with draft-nennemann-wimse-ect-00.
|
|
The registration details are identical to "application/exec+jwt"
|
|
above except for the subtype name. WIMSE deployments MAY use
|
|
either media type; new deployments SHOULD prefer
|
|
"application/exec+jwt".
|
|
|
|
## HTTP Header Field Registration {#header-registration}
|
|
|
|
This document requests registration of the following header field
|
|
in the "Hypertext Transfer Protocol (HTTP) Field Name Registry"
|
|
maintained by IANA:
|
|
|
|
Field name:
|
|
: Execution-Context
|
|
|
|
Status:
|
|
: permanent
|
|
|
|
Specification document:
|
|
: This document, {{http-header}}
|
|
|
|
## JWT Claims Registration {#claims-registration}
|
|
|
|
This document requests registration of the following claims in
|
|
the "JSON Web Token Claims" registry maintained by IANA:
|
|
|
|
| Claim Name | Claim Description | Change Controller | Reference |
|
|
|:---:|:---|:---:|:---:|
|
|
| wid | Workflow Identifier | IETF | {{exec-claims}} |
|
|
| exec_act | Action/Task Type | IETF | {{exec-claims}} |
|
|
| par | Parent Task Identifiers | IETF | {{exec-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"}
|
|
|
|
--- back
|
|
|
|
# Use Cases {#use-cases}
|
|
{:numbered="false"}
|
|
|
|
This section describes representative use cases demonstrating how
|
|
ECTs provide structured execution records at different assurance
|
|
levels.
|
|
|
|
Note: task identifiers in this section are abbreviated for
|
|
readability. In production, all "jti" values are required to be
|
|
UUIDs per {{exec-claims}}.
|
|
|
|
## Cross-Organization Financial Trading (L3)
|
|
{:numbered="false"}
|
|
|
|
In a cross-organization trading workflow, an investment bank's
|
|
agents coordinate with an external credit rating agency. The
|
|
agents operate in separate trust domains with a federation
|
|
relationship. The DAG records that independent assessments from
|
|
both organizations were completed before trade execution.
|
|
|
|
This workflow uses Level 3 (JOSE signing with audit ledger)
|
|
because regulatory requirements (e.g., MiFID II) mandate
|
|
tamper-evident, auditable execution records.
|
|
|
|
~~~
|
|
Trust Domain: bank.example
|
|
Agent A1 (Portfolio Risk):
|
|
jti: task-001 par: []
|
|
iss: spiffe://bank.example/agent/risk
|
|
exec_act: analyze_portfolio_risk
|
|
|
|
Trust Domain: ratings.example (external)
|
|
Agent B1 (Credit Rating):
|
|
jti: task-002 par: []
|
|
iss: spiffe://ratings.example/agent/credit
|
|
exec_act: assess_credit_rating
|
|
|
|
Trust Domain: bank.example
|
|
Agent A2 (Compliance):
|
|
jti: task-003 par: [task-001, task-002]
|
|
iss: spiffe://bank.example/agent/compliance
|
|
exec_act: verify_trade_compliance
|
|
|
|
Agent A3 (Execution):
|
|
jti: task-004 par: [task-003]
|
|
iss: spiffe://bank.example/agent/execution
|
|
exec_act: execute_trade
|
|
~~~
|
|
{: #fig-finance title="Cross-Organization Trading Workflow (L3)"}
|
|
|
|
The resulting DAG:
|
|
|
|
~~~
|
|
task-001 (analyze_portfolio_risk) task-002 (assess_credit_rating)
|
|
[bank.example] [ratings.example]
|
|
\ /
|
|
v v
|
|
task-003 (verify_trade_compliance)
|
|
[bank.example]
|
|
|
|
|
v
|
|
task-004 (execute_trade)
|
|
[bank.example]
|
|
~~~
|
|
{: #fig-finance-dag title="Cross-Organization DAG"}
|
|
|
|
Task 003 has two parents from different trust domains,
|
|
demonstrating cross-organizational fan-in. The compliance agent
|
|
verifies both parent ECTs — one signed by a local key and one by
|
|
a federated key from the rating agency's trust domain.
|
|
|
|
## Internal Microservice Mesh (L1)
|
|
{:numbered="false"}
|
|
|
|
In an internal AI platform, multiple microservices coordinate to
|
|
process requests. All agents operate within a single trust domain
|
|
behind a service mesh with mTLS. Non-repudiation is not required;
|
|
the ECTs are used for observability and debugging.
|
|
|
|
This workflow uses Level 1 (unsigned JSON) because all agents are
|
|
internal, the transport is fully trusted, and the overhead of
|
|
cryptographic signing is not justified.
|
|
|
|
~~~
|
|
Trust Domain: internal.example
|
|
Agent S1 (Preprocessor):
|
|
jti: task-101 par: []
|
|
exec_act: preprocess_input
|
|
|
|
Agent S2 (Model Inference):
|
|
jti: task-102 par: [task-101]
|
|
exec_act: run_inference
|
|
|
|
Agent S3 (Postprocessor):
|
|
jti: task-103 par: [task-102]
|
|
exec_act: format_output
|
|
~~~
|
|
{: #fig-internal title="Internal Microservice Workflow (L1)"}
|
|
|
|
# Related Work
|
|
{:numbered="false"}
|
|
|
|
## WIMSE Workload Identity
|
|
{:numbered="false"}
|
|
|
|
The WIMSE architecture {{I-D.ietf-wimse-arch}} and service-to-
|
|
service protocol {{I-D.ietf-wimse-s2s-protocol}} provide one
|
|
identity foundation with which ECTs can operate. WIT/WPT answer
|
|
"who is this agent?" and "does it have authority?" while ECTs
|
|
record "what did this agent do?" Together they form an
|
|
identity-plus-accountability framework for regulated agentic
|
|
systems. ECTs define an explicit WIMSE identity binding (see
|
|
{{wimse-binding}}) but are not limited to WIMSE deployments.
|
|
|
|
## OAuth 2.0 Token Exchange and the "act" Claim
|
|
{:numbered="false"}
|
|
|
|
{{RFC8693}} defines the OAuth 2.0 Token Exchange protocol and
|
|
registers the "act" (Actor) claim in the JWT Claims registry.
|
|
The "act" claim creates nested JSON objects representing a
|
|
delegation chain: "who is acting on behalf of whom." While
|
|
the nesting superficially resembles a chain, it is strictly
|
|
linear (each "act" object contains at most one nested "act"),
|
|
represents authorization delegation rather than task execution,
|
|
and carries no task identifiers or input/output integrity
|
|
data. The "act" chain cannot represent
|
|
branching (fan-out) or convergence (fan-in) and therefore
|
|
cannot form a DAG.
|
|
|
|
ECTs intentionally use the distinct claim name "exec_act" for the
|
|
action/task type to avoid collision with the "act" claim. The
|
|
two concepts are orthogonal: "act" records "who authorized whom,"
|
|
ECTs record "what was done, in what order."
|
|
|
|
## Transaction Tokens
|
|
{:numbered="false"}
|
|
|
|
OAuth Transaction Tokens {{I-D.ietf-oauth-transaction-tokens}}
|
|
propagate authorization context across workload call chains.
|
|
The Txn-Token "req_wl" claim accumulates a comma-separated list
|
|
of workloads that requested replacement tokens, which is the
|
|
closest existing mechanism to call-chain recording.
|
|
|
|
However, "req_wl" cannot form a DAG because:
|
|
|
|
- It is linear: a comma-separated string with no branching or
|
|
merging representation. When a workload fans out to multiple
|
|
downstream services, each receives the same "req_wl" value and
|
|
the branching is invisible.
|
|
- It is incomplete: only workloads that request a replacement
|
|
token from the Transaction Token Service appear in "req_wl";
|
|
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
|
|
identity and constraints ("agentic_ctx") but no execution
|
|
ordering or DAG structure.
|
|
|
|
ECTs and Transaction Tokens are complementary: a Txn-Token
|
|
propagates authorization context ("this request is authorized
|
|
for scope X on behalf of user Y"), while an ECT records
|
|
execution accountability ("task T was performed, depending on
|
|
tasks P1 and P2"). An
|
|
agent request could carry both a Txn-Token for authorization
|
|
and an ECT for execution recording. In WIMSE deployments, the
|
|
WPT "tth" claim defined in {{I-D.ietf-wimse-s2s-protocol}} can
|
|
hash-bind a WPT to a co-present Txn-Token; a similar binding
|
|
mechanism for ECTs is a potential future extension.
|
|
|
|
## Distributed Tracing (OpenTelemetry)
|
|
{:numbered="false"}
|
|
|
|
OpenTelemetry {{OPENTELEMETRY}} and similar distributed tracing
|
|
systems provide observability for debugging and monitoring. ECTs
|
|
differ in several important ways: at L2 and L3, ECTs are
|
|
cryptographically signed per-task with the agent's private key;
|
|
ECTs are tamper-evident through JWS signatures; ECTs enforce DAG
|
|
validation rules; and ECTs are designed for regulatory audit rather
|
|
than operational monitoring. OpenTelemetry data is typically
|
|
controlled by the platform operator and can be modified or deleted
|
|
without detection. ECTs and distributed traces are complementary:
|
|
traces provide observability while ECTs provide 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 ECT-issuing agents, 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"}
|
|
|
|
The SCITT architecture {{I-D.ietf-scitt-architecture}} defines a
|
|
framework for transparent and auditable supply chain records.
|
|
ECTs and SCITT are complementary: the ECT "wid" claim can serve
|
|
as a correlation identifier in SCITT Signed Statements, linking
|
|
an ECT audit trail to a supply chain transparency record.
|
|
|
|
# Acknowledgments
|
|
{:numbered="false"}
|
|
|
|
The author thanks the WIMSE working group for their foundational
|
|
work on workload identity in multi-system environments. The
|
|
WIMSE concepts of Workload Identity Tokens and Workload Proof
|
|
Tokens provided the original motivation for execution context
|
|
tracing and remain a primary identity binding for ECTs.
|