Files
ietf-wimse-ect-cbor/cbor-variant/draft-nennemann-wimse-execution-context-cbor-00.md
Christian Nennemann ea188f1c22 Add CBOR/COSE/CWT serialization of WIMSE Execution Context Tokens
Companion I-D to draft-nennemann-wimse-execution-context defining
ECT semantics mapped to CBOR encoding, COSE_Sign1 signing, and CWT
claims for constrained devices and non-HTTP transports (CoAP, MQTT,
raw binary). Aligned with JWT draft changes: jti/cti as unified
token+task ID (no separate tid), pol/pol_decision optional but paired.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:51:22 +01:00

45 KiB

fullname: Christian Nennemann
organization: Independent Researcher
email: ietf@nennemann.de

normative: RFC8392: RFC8610: RFC8949: RFC9052: RFC9053: RFC9338: RFC9562: RFC9596: I-D.ietf-wimse-arch: I-D.ietf-wimse-s2s-protocol: I-D.nennemann-wimse-execution-context: title: "Execution Context Tokens for Distributed Agentic Workflows" target: https://datatracker.ietf.org/doc/draft-nennemann-wimse-execution-context/ date: 2026-02 author: - name: Christian Nennemann org: Independent Researcher

informative: RFC3552: RFC7252: RFC8126: RFC8613: RFC9110: RFC9147: RFC9421: RFC9528: I-D.ni-wimse-ai-agent-identity: I-D.ietf-scitt-architecture: I-D.ietf-suit-manifest: SPIFFE: title: "Secure Production Identity Framework for Everyone (SPIFFE)" target: https://spiffe.io/docs/latest/spiffe-about/overview/ date: false EU-AI-ACT: title: "Regulation (EU) 2024/1689 of the European Parliament and of the Council laying down harmonised rules on artificial intelligence (Artificial Intelligence Act)" target: https://eur-lex.europa.eu/eli/reg/2024/1689 date: 2024-06-13 author: - org: European Parliament and Council of the European Union FDA-21CFR11: title: "Title 21, Code of Federal Regulations, Part 11: Electronic Records; Electronic Signatures" target: https://www.ecfr.gov/current/title-21/chapter-I/subchapter-A/part-11 date: false author: - org: U.S. Food and Drug Administration DORA: title: "Regulation (EU) 2022/2554 on digital operational resilience for the financial sector (DORA)" target: https://eur-lex.europa.eu/eli/reg/2022/2554 date: 2022-12-14 author: - org: European Parliament and Council of the European Union EU-MDR: title: "Regulation (EU) 2017/745 on medical devices (MDR)" target: https://eur-lex.europa.eu/eli/reg/2017/745 date: 2017-04-05 author: - org: European Parliament and Council of the European Union MQTT: title: "MQTT Version 5.0" target: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html date: 2019-03-07 author: - org: OASIS EAT: title: "The Entity Attestation Token (EAT)" target: https://datatracker.ietf.org/doc/draft-ietf-rats-eat/ date: false author: - name: Laurence Lundblade - name: Giridhar Mandyam - name: Jeremy O'Donoghue - name: Carl Wallace

--- abstract

This document defines a CBOR/COSE/CWT serialization of Execution Context Tokens (ECTs) for distributed agentic workflows in regulated environments. The companion document, draft-nennemann-wimse-execution-context, defines the full ECT semantics using JSON/JOSE/JWT serialization. This specification maps those semantics to CBOR (RFC 8949) encoding, COSE (RFC 9052) signing structures, and CWT (RFC 8392) claims, targeting constrained devices, non-HTTP transports (CoAP, MQTT, Layer 2 protocols), and bandwidth-sensitive deployments. The CBOR serialization preserves all ECT semantics including DAG-structured task dependency ordering, policy evaluation recording, and compliance state tracking while using COSE_Sign1 signatures and integer-keyed CWT claims for compact representation.

--- middle

Introduction

Motivation

The companion specification {{I-D.nennemann-wimse-execution-context}} defines Execution Context Tokens (ECTs) as an extension to the WIMSE architecture {{I-D.ietf-wimse-arch}} for recording task execution, DAG-structured dependency ordering, and policy evaluation outcomes in regulated agentic workflows. That specification uses JSON Web Tokens (JWT) with JSON Object Signing and Encryption (JOSE) serialization, which is well suited for HTTP-based deployments.

However, many deployment scenarios require a more compact serialization:

  • Constrained IoT agents: Medical devices, industrial controllers, and edge computing nodes operating under tight memory and bandwidth budgets benefit from binary encoding.

  • Non-HTTP transports: Agent-to-agent communication over CoAP {{RFC7252}}, MQTT {{MQTT}}, or Layer 2 protocols cannot efficiently carry JSON-encoded tokens.

  • Bandwidth-sensitive environments: Satellite links, low-power wide-area networks, and cellular IoT backhaul incur significant cost per byte.

CBOR {{RFC8949}} provides a binary encoding that is substantially more compact than JSON for the same semantic content. COSE {{RFC9052}} provides equivalent signing and encryption operations to JOSE. CWT {{RFC8392}} provides a CBOR-based claim structure equivalent to JWT. Together, these standards enable a CBOR-native ECT serialization that achieves approximately 3x size reduction compared to the JWT variant while preserving identical semantics.

Scope

This document defines only the CBOR/COSE/CWT serialization mapping for ECTs. The following are defined in the companion JWT specification {{I-D.nennemann-wimse-execution-context}} and apply identically to CBOR-serialized ECTs:

  • ECT claim semantics and processing rules
  • DAG validation algorithm (parent existence, temporal ordering, cycle detection, policy decision propagation, trust domain consistency)
  • Verification procedure (all 15 steps, adapted for COSE in {{verification}})
  • Operational modes (point-to-point, deferred ledger, full ledger)
  • Audit ledger interface requirements
  • Security model and threat analysis
  • Privacy considerations

Implementers MUST read the companion JWT specification for the complete semantic definition. This document covers:

  • COSE header parameter mapping ({{cose-header}})
  • CWT claim key assignments ({{claim-mapping}})
  • CDDL schema for ECT-CBOR payloads ({{cddl-schema}})
  • COSE_Sign1 structure ({{cose-structure}})
  • Transport mechanisms for CoAP, MQTT, HTTP, and raw binary ({{transport}})
  • COSE-specific verification steps ({{verification}})
  • Size comparison with the JWT variant ({{size-comparison}})

Terminology

This document reuses all terminology defined in {{I-D.nennemann-wimse-execution-context}} Section 2. Additionally:

CWT:
CBOR Web Token {{RFC8392}}, the CBOR equivalent of JWT.
COSE:
CBOR Object Signing and Encryption {{RFC9052}}, the CBOR equivalent of JOSE.
COSE_Sign1:
A COSE structure for a message with a single signer {{RFC9052}} Section 4.2.
CDDL:
Concise Data Definition Language {{RFC8610}}, used to define CBOR data structures.

Conventions and Definitions

{::boilerplate bcp14-tagged}

COSE Header Parameters

The COSE protected header for an ECT-CBOR token MUST contain the following parameters:

alg (label 1):
REQUIRED. The COSE algorithm identifier for the digital signature. Implementations MUST support ES256 (COSE algorithm identifier -7) {{RFC9053}}. The algorithm MUST be an asymmetric signature algorithm. Symmetric MAC algorithms MUST NOT be used, as ECTs require asymmetric signatures for non-repudiation. The algorithm MUST match the algorithm in the agent's corresponding WIT.
content type (label 3):
REQUIRED. MUST be set to the string "application/wimse-exec+cwt" or the equivalent CoAP Content-Format number once assigned. Identifies the payload as a CBOR-serialized ECT.
kid (label 4):
REQUIRED. Key identifier referencing the public key from the agent's WIT. Encoded as bstr. Used by verifiers to look up the correct public key for signature verification.
typ (label 16):
REQUIRED. MUST be set to "wimse-exec+cwt". Distinguishes ECT-CBOR tokens from other CWT types, per {{RFC9596}}.

ECTs MUST use the COSE_Sign1 structure (single signer) defined in {{RFC9052}} Section 4.2. The COSE_Sign (multi-signer) structure MUST NOT be used, consistent with the single-agent-signs model of the JWT variant.

The unprotected header bucket MUST be empty. All header parameters MUST be placed in the protected header to ensure integrity protection.

Example protected header in CBOR diagnostic notation:

{
  / alg /           1: -7,       / ES256 /
  / content type /  3: "application/wimse-exec+cwt",
  / kid /           4: h'6167656e742d612d6b65792d323032362d3032',
  / typ /          16: "wimse-exec+cwt"
}

{: #fig-cose-header title="ECT COSE Protected Header Example"}

CWT Claim Mapping

This section defines the complete mapping from JWT claim names used in {{I-D.nennemann-wimse-execution-context}} to CBOR integer keys used in the CWT payload.

Standard CWT Claims

The following claims reuse existing CWT claim keys from the IANA "CBOR Web Token (CWT) Claims" registry {{RFC8392}}:

JWT Claim CWT Key CBOR Type Description
iss 1 tstr Issuer (SPIFFE ID)
sub 2 tstr Subject (MUST equal iss when present)
aud 3 tstr / [+ tstr] Audience
exp 4 int Expiration (epoch seconds)
iat 6 int Issued At (epoch seconds)
cti 7 bstr .size 16 CWT ID / Task ID (UUID as 16-byte binary)
{: #table-standard-claims title="Standard CWT Claim Mapping"}

The nbf (Not Before) claim (CWT key 5) is not used in ECTs, as ECTs record completed actions.

CWT ID Encoding

The CWT ID (cti, key 7) is the CWT equivalent of the JWT jti claim. In the companion JWT specification, jti serves as both the token identifier (for replay detection) and the task identifier (for DAG parent references in par). Since each ECT represents exactly one task, a separate task identifier is not needed.

In the CBOR variant, cti MUST be encoded as a 16-byte binary string containing the UUID in network byte order per {{RFC9562}} Section 4. This saves 20 bytes per token. When wid is present, uniqueness of cti is scoped to the workflow; when wid is absent, uniqueness MUST be enforced globally across the ECT store.

Implementations MAY additionally apply CBOR tag 37 to explicitly mark the value as a UUID.

Timestamp Encoding

Timestamps (exp key 4, iat key 6) use the CWT NumericDate format: integer seconds since the Unix epoch (1970-01-01T00:00:00Z). This is semantically identical to JWT NumericDate but without fractional seconds. Implementations MAY use CBOR tag 1 (epoch-based date/time) to explicitly tag timestamp values.

ECT-Specific Claims

The following claim keys are defined by this specification for ECT-specific claims. These keys are requested for registration in the "CBOR Web Token (CWT) Claims" registry (see {{iana}}).

JWT Claim CWT Key CBOR Type Req/Opt Description
wid 300 bstr .size 16 OPT Workflow ID (UUID binary)
exec_act 301 tstr REQ Action/task type identifier
par 302 [* bstr .size 16] REQ Parent ECT cti UUIDs
pol 303 tstr OPT Policy rule identifier
pol_decision 304 uint OPT Policy decision enum
pol_enforcer 305 tstr OPT Policy enforcer identity
pol_timestamp 306 int OPT Policy decision timestamp
inp_hash 307 [int, bstr] OPT Input hash [alg_id, hash]
out_hash 308 [int, bstr] OPT Output hash [alg_id, hash]
inp_classification 309 tstr OPT Input data classification
exec_time_ms 310 uint OPT Execution duration (ms)
regulated_domain 311 uint OPT Regulatory domain enum
model_version 312 tstr OPT AI/ML model version
witnessed_by 313 [+ tstr] OPT Witness SPIFFE IDs
compensation_required 314 bool OPT Compensation flag
compensation_reason 315 tstr OPT Compensation reason ID
ext 316 map OPT Extension map
{: #table-ect-claims title="ECT-Specific CWT Claim Mapping"}

The Req/Opt column indicates whether the claim is REQUIRED or OPTIONAL, matching the designations in {{I-D.nennemann-wimse-execution-context}}.

The pol (key 303) and pol_decision (key 304) claims are OPTIONAL but MUST be paired: if one is present, the other MUST also be present. When both are absent, the ECT records task execution without a policy checkpoint. Regulated deployments SHOULD include policy claims on all ECTs to maintain complete audit trails.

The par claim (key 302) contains the cti values of previously verified parent ECTs. Since cti serves as both the token identifier and the task identifier, par entries reference cti values directly.

Design Decisions

UUIDs as Binary

In the JWT variant, UUIDs (jti, wid, par entries) are encoded as hyphenated text strings (e.g., "550e8400-e29b-41d4-a716- 446655440001"), consuming 36 bytes per UUID. In the CBOR variant, UUIDs MUST be encoded as 16-byte binary strings (bstr .size 16) in network byte order per {{RFC9562}} Section 4. This saves 20 bytes per UUID.

For the par claim (key 302), each entry is the cti (16-byte binary UUID) of a previously verified parent ECT. An empty par array indicates a root task, identical to the JWT variant semantics.

Implementations MAY use CBOR tag 37 ({{RFC9562}}) to explicitly tag UUID values. Receivers MUST accept UUID values both with and without tag 37.

Hash Encoding

In the JWT variant, hash values use the string format "algorithm:base64url-encoded-hash" (e.g., "sha-256:n4bQgYhM..."). In the CBOR variant, hash values (inp_hash key 307, out_hash key 308) use a structured two-element CBOR array:

[hash_algorithm_id, hash_bytes]

Where:

  • hash_algorithm_id is the integer algorithm identifier from the IANA "COSE Algorithms" registry. For SHA-256, this is -16.

  • hash_bytes is the raw hash value as a binary string (bstr).

This structured encoding is more compact (no base64url overhead) and type-safe (integer algorithm identifiers prevent string parsing ambiguity).

Example (SHA-256 hash):

/ inp_hash / 307: [-16, h'9f86d081884c7d659a2feaa0c55ad015
                           a3bf4f1b2b0b822cd15d6c15b0f00a08']

Implementations MUST support SHA-256 (algorithm ID -16). Hash algorithms weaker than SHA-256 MUST NOT be accepted.

Policy Decision Enumeration

In the JWT variant, pol_decision uses string values. In the CBOR variant, pol_decision (key 304) uses unsigned integer enumeration for compactness:

Integer Value JWT String Value Description
0 approved Policy evaluation succeeded
1 rejected Policy evaluation failed
2 pending_human_review Awaiting human judgment
{: #table-pol-decision title="Policy Decision Enumeration"}

The processing rules are identical to the JWT variant: rejected ECTs MUST still be appended to the ledger, and rejected parents may only feed compensation, rollback, or remediation tasks.

Regulated Domain Enumeration

In the JWT variant, regulated_domain uses string values. In the CBOR variant, regulated_domain (key 311) uses unsigned integer enumeration:

Integer Value JWT String Value Description
0 medtech Medical technology and devices
1 finance Financial services and trading
2 military Military and defense
{: #table-regulated-domain title="Regulated Domain Enumeration"}

Extension Map

The ext claim (key 316) is a CBOR map with text string keys in reverse domain notation (e.g., "com.example.custom_field"), identical to the JWT variant. Values MAY be any CBOR type. The serialized ext map SHOULD NOT exceed 4096 bytes. Map nesting depth SHOULD NOT exceed 5 levels. Unknown extensions MUST be ignored by receivers.

CDDL Schema

The following CDDL {{RFC8610}} schema defines the structure of an ECT-CBOR payload:

ect-cbor-payload = {
  ; === Standard CWT claims ===
  1 => tstr,                         ; iss - Issuer (SPIFFE ID)
  ? 2 => tstr,                      ; sub - Subject (= iss)
  3 => tstr / [+ tstr],             ; aud - Audience
  4 => epoch-time,                   ; exp - Expiration
  6 => epoch-time,                   ; iat - Issued At
  7 => bstr .size 16,               ; cti - CWT/Task ID (UUID)

  ; === Execution Context claims ===
  ? 300 => bstr .size 16,           ; wid - Workflow ID (UUID)
  301 => tstr,                      ; exec_act - Action type
  302 => [* bstr .size 16],         ; par - Parent ECT cti UUIDs

  ; === Optional policy claims (must be paired) ===
  ? 303 => tstr,                    ; pol - Policy rule ID
  ? 304 => pol-decision,            ; pol_decision

  ? 305 => tstr,                    ; pol_enforcer
  ? 306 => epoch-time,              ; pol_timestamp

  ; === Optional data integrity ===
  ? 307 => hash-entry,              ; inp_hash
  ? 308 => hash-entry,              ; out_hash
  ? 309 => tstr,                    ; inp_classification

  ; === Optional metadata ===
  ? 310 => uint,                    ; exec_time_ms
  ? 311 => regulated-domain,        ; regulated_domain
  ? 312 => tstr,                    ; model_version
  ? 313 => [+ tstr],               ; witnessed_by
  ? 314 => bool,                    ; compensation_required
  ? 315 => tstr,                    ; compensation_reason
  ? 316 => { + tstr => any },       ; ext
}

; Policy decision: 0=approved, 1=rejected,
;                  2=pending_human_review
pol-decision = 0..2

; Regulated domain: 0=medtech, 1=finance, 2=military
regulated-domain = 0..2

; Hash entry: [algorithm_id, hash_bytes]
; algorithm_id from COSE Algorithms registry (e.g., -16 = SHA-256)
hash-entry = [int, bstr]

; epoch-time is integer seconds since Unix epoch
epoch-time = int

{: #fig-cddl title="CDDL Schema for ECT-CBOR Payload"}

The COSE_Sign1 wrapper structure is defined in {{cose-structure}}.

COSE_Sign1 Structure

An ECT-CBOR token is a COSE_Sign1 message {{RFC9052}} Section 4.2 with the following structure:

ECT-COSE = COSE_Sign1_Tagged

COSE_Sign1_Tagged = #6.18(COSE_Sign1)

COSE_Sign1 = [
  protected:   bstr,     ; Serialized protected header map
  unprotected: {},       ; MUST be empty
  payload:     bstr,     ; Serialized ECT-CBOR claims map
  signature:   bstr      ; Digital signature
]

{: #fig-cose-structure title="COSE_Sign1 Structure for ECT-CBOR"}

The components are:

protected:
The CBOR-serialized protected header map as defined in {{cose-header}}. Encoded as a bstr wrapping the CBOR map.
unprotected:
MUST be an empty map. No unprotected header parameters are permitted for ECTs. All parameters reside in the protected bucket to ensure integrity.
payload:
The CBOR-serialized ECT claims map conforming to the CDDL schema in {{cddl-schema}}. Encoded as a bstr.
signature:
The digital signature computed per {{RFC9052}} Section 4.4. For ES256, this is a 64-byte value containing the (r, s) pair in fixed-length encoding.

The Sig_structure for computing the signature is per {{RFC9052}} Section 4.4:

Sig_structure = [
  context:       "Signature1",
  body_protected: bstr,    ; Serialized protected header
  external_aad:   bstr,    ; Empty bstr (h'') unless transport-bound
  payload:        bstr     ; Serialized ECT claims map
]

{: #fig-sig-structure title="Sig_structure for ECT Signature Computation"}

External Additional Authenticated Data (external_aad) is an empty byte string unless the ECT is bound to a transport-layer context (e.g., OSCORE {{RFC8613}}). When transport binding is used, the binding mechanism MUST be documented.

Transport Mechanisms

HTTP Transport

When ECT-CBOR tokens are transported over HTTP, the same Execution-Context header field defined in {{I-D.nennemann-wimse-execution-context}} is used. The header value is the Base64url-encoded COSE_Sign1 byte sequence (without padding).

Receivers can distinguish JWT and CBOR ECTs by examining the first bytes of the decoded value:

  • JWT ECTs begin with the byte 0x7B (ASCII '{'), as the decoded JWS header starts with a JSON object.

  • CBOR ECTs begin with the byte 0xD2 (CBOR tag 18 for COSE_Sign1_Tagged) or 0x84 (CBOR array of length 4 for an untagged COSE_Sign1).

Implementations that support both formats MUST perform this detection. Implementations that support only one format MAY reject tokens in the unsupported format.

Example:

GET /api/safety-check HTTP/1.1
Host: safety-agent.example.com
Workload-Identity: eyJhbGci...WIT...
Workload-Proof-Token: eyJhbGci...WPT...
Execution-Context: 0oRYJ6QBJgMeYXBwbGljYXRp...CBOR-ECT...

{: #fig-http-cbor title="HTTP Request with CBOR ECT"}

When multiple parent tasks contribute context, multiple Execution-Context header field lines MAY be included, each carrying either a JWT or CBOR ECT. Receivers MUST individually verify each ECT regardless of its serialization format.

CoAP Transport

For CoAP {{RFC7252}} deployments, ECT-CBOR tokens are carried using one of the following mechanisms:

CoAP Option

A new CoAP Option is defined:

Number Name Format
TBD1 Execution-Context opaque
{: #table-coap-option title="CoAP Option for ECT-CBOR"}

The option value is the raw COSE_Sign1 byte sequence (not Base64url-encoded). CoAP's binary-native transport eliminates the need for text encoding.

When the ECT exceeds the CoAP option size limit, implementations SHOULD use CoAP block-wise transfer {{?RFC7959}} or carry the ECT in the request payload with the Content-Format set to application/wimse-exec+cwt (see {{iana}}).

Content-Format

The CoAP Content-Format identifier for ECT-CBOR is registered in {{iana}}. When ECTs are carried in the CoAP payload body rather than an option, the Content-Format MUST be set to the registered identifier for application/wimse-exec+cwt.

Transport Security

CoAP-based ECT transport MUST use DTLS 1.3 {{RFC9147}}, OSCORE {{RFC8613}}, or EDHOC {{RFC9528}} for transport security. ECT signatures provide message-level security, but transport-layer confidentiality and integrity are still REQUIRED.

MQTT Transport

For MQTT {{MQTT}} deployments, ECT-CBOR tokens MAY be carried as:

  1. MQTT User Property: The property name is "Execution-Context" and the value is the Base64-encoded COSE_Sign1 byte sequence. Multiple Execution-Context properties MAY be included for multiple parent ECTs.

  2. Payload envelope: The ECT is embedded within the MQTT application payload as a CBOR-encoded field. The envelope structure is application-defined.

MQTT transport MUST use TLS for transport security. MQTT User Properties are not encrypted by the MQTT protocol itself; ECT signatures provide message-level integrity but not confidentiality of claim values.

Raw Binary Transport

For Layer 2, fieldbus, or other non-IP protocols, ECT-CBOR tokens can be embedded directly as COSE_Sign1 byte sequences. The framing format is:

+----------------+------------------------------+
| Length (2 or 4 | COSE_Sign1 bytes             |
| bytes, network |                              |
| byte order)    |                              |
+----------------+------------------------------+

{: #fig-binary-framing title="Binary Transport Framing"}

Implementations MUST use 2-byte length for ECTs up to 65535 bytes and 4-byte length for larger ECTs. The length field encodes the number of bytes in the COSE_Sign1 structure that follows.

Multiple ECTs (for multiple parent tasks) are concatenated using this framing.

Verification Procedure

The verification procedure for ECT-CBOR tokens follows the 15-step procedure defined in {{I-D.nennemann-wimse-execution-context}} Section "Signature and Token Verification", with the following COSE-specific adaptations for the initial steps:

  1. Parse COSE_Sign1: Decode the COSE_Sign1 structure per {{RFC9052}} Section 4.4. Extract the protected header, payload, and signature. If the input begins with CBOR tag 18, strip the tag and process the inner array.

  2. Verify content type: The protected header parameter content type (label 3) MUST be present and MUST be "application/wimse-exec+cwt" or the equivalent registered CoAP Content-Format number.

  3. Verify alg: The protected header parameter alg (label 1) MUST be present and MUST be an asymmetric signature algorithm. Symmetric MAC algorithms and absent/null values MUST be rejected.

  4. Verify kid: The protected header parameter kid (label 4) MUST reference a known, valid public key from a WIT within the trust domain.

  5. Verify signature: Retrieve the public key identified by kid and verify the COSE_Sign1 signature per {{RFC9052}} Section 4.4, constructing the Sig_structure as defined in {{cose-structure}}.

  6. Verify key not revoked: Identical to the JWT variant.

  7. Verify algorithm alignment: The alg parameter MUST match the algorithm in the corresponding WIT.

  8. Verify issuer: Decode the payload. The iss claim (key 1) MUST match the sub claim of the WIT associated with the kid public key.

  9. Verify audience: The aud claim (key 3) MUST contain the verifier's own workload identity.

  10. Verify expiration: The exp claim (key 4) MUST indicate the ECT has not expired.

  11. Verify iat freshness: The iat claim (key 6) MUST NOT be unreasonably far in the past (RECOMMENDED: 15 minutes) and MUST NOT be in the future beyond clock skew tolerance (RECOMMENDED: 30 seconds).

  12. Verify required claims: The cti (key 7), exec_act (key 301), and par (key 302) claims MUST all be present and well-formed per the CDDL schema in {{cddl-schema}}.

  13. Verify policy claims: If pol (key 303) or pol_decision (key 304) is present, verify that both are present and that pol_decision is 0, 1, or 2.

  14. Perform DAG validation: Per the DAG validation rules in {{I-D.nennemann-wimse-execution-context}}. When comparing task IDs across JWT and CBOR ECTs in a mixed-format deployment, UUID comparison MUST be performed at the binary level (converting text UUIDs to 16-byte binary for comparison).

  15. Store ECT: If all checks pass and an audit ledger is available, the ECT SHOULD be appended.

Error handling follows the same rules as the JWT variant. Verification failures MUST be logged. Error messages SHOULD NOT reveal whether specific parent task IDs exist in the ledger.

Audit Ledger Considerations

The audit ledger interface defined in {{I-D.nennemann-wimse-execution-context}} applies to CBOR ECTs. The ledger entry structure carries the raw COSE_Sign1 bytes instead of the JWS compact serialization:

{
  "ledger_sequence": 42,
  "ect_jti": h'550e8400e29b41d4a716446655440001',
  "agent_id": "spiffe://example.com/agent/clinical",
  "action": "recommend_treatment",
  "parents": [],
  "ect_cose": h'd28443a10126a058...full COSE_Sign1 bytes...',
  "signature_verified": true,
  "verification_timestamp": 1(1772064151),
  "stored_timestamp": 1(1772064151)
}

{: #fig-ledger-entry title="Ledger Entry for CBOR ECT"}

The ect_cose field is the authoritative record. Convenience fields (agent_id, action, parents) are indexes; if they disagree with the COSE_Sign1 payload, the COSE_Sign1 content takes precedence.

Ledgers that store both JWT and CBOR ECTs SHOULD include a format discriminator field. Alternatively, the format can be detected from the raw bytes: JWT ECTs (JWS compact serialization) are ASCII-printable text with period separators, while CBOR ECTs begin with CBOR-encoded bytes (tag 18 = 0xD2, or array header 0x84).

Size Comparison

The following comparison uses the "Complete ECT Example" from {{I-D.nennemann-wimse-execution-context}} Section 4.8 as the reference payload. This example contains: iss, sub, aud, iat, exp, jti, wid, exec_act, par (empty), pol, pol_decision, pol_enforcer, pol_timestamp, inp_hash, out_hash, inp_classification, exec_time_ms, regulated_domain, model_version, and witnessed_by.

JWT Variant Size

Component Estimated Bytes
JOSE header (JSON) ~70
Payload (JSON) ~620
ES256 signature (raw) 64
Base64url encoding overhead (~33%) ~250
Period separators 2
Total (JWS Compact) ~1006
{: #table-jwt-size title="JWT ECT Size Estimate"}

CBOR Variant Size

Component Estimated Bytes
Protected header (CBOR) ~55
Payload (CBOR) ~240
ES256 signature (raw) 64
COSE_Sign1 array framing ~6
Total (COSE_Sign1) ~365
{: #table-cbor-size title="CBOR ECT Size Estimate"}

Analysis

The CBOR variant achieves approximately 2.8x size reduction compared to the JWT variant. Key savings come from:

  • Integer claim keys vs. string claim names: ~100 bytes saved across all claims.

  • Binary UUIDs (16 bytes each) vs. hyphenated text UUIDs (36 bytes each): ~60 bytes saved across jti, wid, and par entries.

  • Binary hash values vs. base64url-encoded hash strings: ~22 bytes saved per hash (two hashes = ~44 bytes).

  • Integer enumerations vs. string values for pol_decision and regulated_domain: ~15 bytes saved.

  • No Base64url encoding: COSE_Sign1 is a native binary format, eliminating the ~33% overhead of Base64url encoding required for JWS Compact Serialization when carried in binary transports (CoAP, MQTT payload, raw binary).

When transported over HTTP (which requires Base64url encoding of the COSE_Sign1 bytes), the size advantage is reduced but still significant (~2x reduction).

Security Considerations

The security considerations in {{I-D.nennemann-wimse-execution-context}} apply in full to CBOR-serialized ECTs. This section addresses additional considerations specific to the CBOR/COSE serialization.

CBOR Canonicalization

CBOR allows multiple valid encodings of the same data (e.g., different integer widths, indefinite-length encoding). To ensure consistent hashing and signature verification:

  • ECT payloads SHOULD use deterministic CBOR encoding as defined in {{RFC8949}} Section 4.2 (Core Deterministic Encoding Requirements).

  • Implementations MUST NOT reject ECTs solely because the payload uses a non-preferred but valid CBOR encoding, provided the COSE_Sign1 signature verifies correctly.

  • The protected header MUST use deterministic encoding, as it is included in the Sig_structure for signature computation.

COSE Algorithm Agility

The same algorithm constraints as the JWT variant apply: symmetric algorithms MUST NOT be used, and the absence of an algorithm identifier MUST be rejected. Implementations SHOULD support algorithm agility by accepting any COSE asymmetric signature algorithm registered in the IANA "COSE Algorithms" registry, subject to local policy on minimum security strength.

CoAP Transport Security

When ECTs are transported over CoAP, transport security MUST be provided by DTLS 1.3 {{RFC9147}}, OSCORE {{RFC8613}}, or EDHOC {{RFC9528}}. CoAP without transport security MUST NOT be used for ECT transport, even though ECT signatures provide message-level integrity. Transport security provides confidentiality of claim values (ECT signatures do not encrypt the payload).

MQTT Transport Security

When ECTs are transported over MQTT, TLS MUST be used for the MQTT connection. MQTT User Properties are transmitted in cleartext within the MQTT protocol layer; TLS provides the necessary confidentiality. ECT signatures ensure integrity and non-repudiation independent of the transport.

Binary Transport Security

For raw binary transports ({{binary-transport}}), ECT signatures provide message-level integrity and authenticity. However, transport-layer integrity mechanisms (checksums, MACs, link-layer encryption) are RECOMMENDED as defense in depth. Without transport security, claim values are transmitted in cleartext.

Mixed-Format Deployments

In deployments where some agents produce JWT ECTs and others produce CBOR ECTs within the same workflow:

  • DAG validation MUST compare ECT identifiers (jti/cti) at the binary UUID level. Text UUID representations MUST be converted to 16-byte binary before comparison.

  • Hash values MUST be compared at the raw byte level. The JWT base64url-encoded hash MUST be decoded before comparison with the CBOR binary hash.

  • Policy decision values MUST be compared semantically: the JWT string "approved" is equivalent to the CBOR integer 0, "rejected" to 1, and "pending_human_review" to 2.

  • Audit ledgers MUST support both formats and SHOULD normalize comparison operations to a common representation.

Privacy Considerations

The privacy considerations in {{I-D.nennemann-wimse-execution-context}} apply identically to CBOR-serialized ECTs. CBOR's binary encoding does not change the privacy properties: the same claims are present, carrying the same information, encoded differently.

Implementers should note that CBOR's compact encoding does not provide confidentiality. The binary format may create a false sense of obscurity, but CBOR-encoded data is trivially decoded by anyone with access to the byte stream. ECT claim values SHOULD be protected in transit via transport-layer encryption (TLS, DTLS, OSCORE) and at rest via storage encryption.

IANA Considerations

Media Type Registration

This document requests registration of the following media type in the "Media Types" registry maintained by IANA:

Type name:
application
Subtype name:
wimse-exec+cwt
Required parameters:
none
Optional parameters:
none
Encoding considerations:
binary; an ECT-CBOR is a COSE_Sign1 structure containing a CBOR-encoded payload.
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 regulated agentic workflows requiring execution context tracing and audit trails in constrained or binary-transport environments.
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

CoAP Content-Format Registration

This document requests registration of the following Content-Format in the "CoAP Content-Formats" registry maintained by IANA:

Media Type Encoding ID
application/wimse-exec+cwt - TBD2
{: #table-content-format title="CoAP Content-Format Registration"}

CoAP Option Number Registration

This document requests registration of the following CoAP Option in the "CoAP Option Numbers" registry maintained by IANA:

Number Name Reference
TBD1 Execution-Context This document
{: #table-coap-option-reg title="CoAP Option Registration"}

CWT Claims Registration

This document requests registration of the following claims in the "CBOR Web Token (CWT) Claims" registry maintained by IANA:

Claim Name Claim Key Claim Value Type Change Controller Reference
wid 300 bstr IETF {{ect-claims}}
exec_act 301 tstr IETF {{ect-claims}}
par 302 array IETF {{ect-claims}}
pol 303 tstr IETF {{ect-claims}}
pol_decision 304 uint IETF {{ect-claims}}
pol_enforcer 305 tstr IETF {{ect-claims}}
pol_timestamp 306 int IETF {{ect-claims}}
inp_hash 307 array IETF {{ect-claims}}
out_hash 308 array IETF {{ect-claims}}
inp_classification 309 tstr IETF {{ect-claims}}
exec_time_ms 310 uint IETF {{ect-claims}}
regulated_domain 311 uint IETF {{ect-claims}}
model_version 312 tstr IETF {{ect-claims}}
witnessed_by 313 array IETF {{ect-claims}}
compensation_required 314 true/false IETF {{ect-claims}}
compensation_reason 315 tstr IETF {{ect-claims}}
ext 316 map IETF {{ect-claims}}
{: #table-cwt-claims-reg title="CWT Claims Registrations"}

ECT-CBOR Policy Decision Values Registry

This document establishes the "ECT-CBOR Policy Decision Values" registry. Registration policy is Specification Required per {{!RFC8126}}.

The initial contents of the registry are:

Integer Value Description Change Controller Reference
0 Policy evaluation succeeded (approved) IETF {{pol-decision-enum}}
1 Policy evaluation failed (rejected) IETF {{pol-decision-enum}}
2 Awaiting human judgment (pending_human_review) IETF {{pol-decision-enum}}
{: #table-pol-decision-reg title="ECT-CBOR Policy Decision Values"}

ECT-CBOR Regulated Domain Values Registry

This document establishes the "ECT-CBOR Regulated Domain Values" registry. Registration policy is Specification Required per {{!RFC8126}}.

The initial contents of the registry are:

Integer Value Description Change Controller Reference
0 Medical technology and devices (medtech) IETF {{regulated-domain-enum}}
1 Financial services and trading (finance) IETF {{regulated-domain-enum}}
2 Military and defense (military) IETF {{regulated-domain-enum}}
{: #table-regulated-domain-reg title="ECT-CBOR Regulated Domain Values"}

--- back

Related Work

{:numbered="false"}

CWT and JWT Relationship

{:numbered="false"}

CBOR Web Token (CWT) {{RFC8392}} is the CBOR analog of JSON Web Token (JWT) {{?RFC7519}}. CWT reuses the JWT claim semantics with integer keys instead of string names and CBOR encoding instead of JSON. This document follows the same pattern: ECT-CBOR reuses the ECT-JWT claim semantics with CBOR-native encoding.

COSE and JOSE Relationship

{:numbered="false"}

COSE {{RFC9052}} is the CBOR analog of JOSE {{?RFC7515}}. COSE provides equivalent signing (COSE_Sign, COSE_Sign1), MAC (COSE_Mac, COSE_Mac0), and encryption (COSE_Encrypt, COSE_Encrypt0) operations. ECT-CBOR uses COSE_Sign1, the single-signer structure, matching the JWS Compact Serialization (single signature) used by ECT-JWT.

Entity Attestation Token (EAT)

{:numbered="false"}

The Entity Attestation Token (EAT) {{EAT}} uses CWT as its base and defines claims for hardware and software attestation. EAT and ECT-CBOR share the CWT foundation and could potentially be integrated: an EAT providing device attestation could carry ECT claims to combine hardware trust with execution accountability. Future work may define an EAT profile for ECT-CBOR.

SUIT Manifests

{:numbered="false"}

The Software Update for IoT (SUIT) manifest {{I-D.ietf-suit-manifest}} uses CBOR/COSE for secure firmware update descriptions in constrained environments. SUIT and ECT-CBOR target overlapping deployment environments (constrained IoT devices) and share the CBOR/COSE toolchain. An agentic workflow that includes firmware update tasks could use SUIT manifests for the update payload and ECT-CBOR for the execution accountability record.

SCITT Integration

{:numbered="false"}

As noted in {{I-D.nennemann-wimse-execution-context}}, ECTs can integrate with the Supply Chain Integrity, Transparency and Trust (SCITT) architecture {{I-D.ietf-scitt-architecture}}. SCITT uses COSE_Sign1 as its signing structure, making ECT-CBOR a natural fit for SCITT integration: ECT-CBOR tokens can be submitted to SCITT Transparency Services as COSE_Sign1 signed statements without format conversion.

Examples

{:numbered="false"}

Example 1: Simple Two-Agent Workflow

{:numbered="false"}

Agent A executes a data retrieval task and sends the ECT to Agent B.

ECT COSE Protected Header (CBOR diagnostic notation):

{
  / alg /           1: -7,    / ES256 /
  / content type /  3: "application/wimse-exec+cwt",
  / kid /           4: h'6167656e742d612d6b65792d323032362d3032',
  / typ /          16: "wimse-exec+cwt"
}

ECT Payload (CBOR diagnostic notation):

{
  / iss /   1: "spiffe://example.com/agent/data-retrieval",
  / sub /   2: "spiffe://example.com/agent/data-retrieval",
  / aud /   3: "spiffe://example.com/agent/validator",
  / exp /   4: 1772064750,
  / iat /   6: 1772064150,
  / cti /   7: h'550e8400e29b41d4a716446655440001',

  / wid /   300: h'b1c2d3e4f5a67890bcdef01234567890',
  / exec_act / 301: "fetch_patient_data",
  / par /   302: [],
  / pol /   303: "clinical_data_access_policy_v1",
  / pol_decision / 304: 0,  / approved /

  / inp_hash / 307: [-16,
    h'9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'],
  / out_hash / 308: [-16,
    h'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'],
  / exec_time_ms / 310: 142,
  / regulated_domain / 311: 0  / medtech /
}

Agent B receives the ECT, verifies it, executes a validation task, and creates its own ECT:

{
  / iss /   1: "spiffe://example.com/agent/validator",
  / sub /   2: "spiffe://example.com/agent/validator",
  / aud /   3: "spiffe://example.com/system/ledger",
  / exp /   4: 1772064760,
  / iat /   6: 1772064160,
  / cti /   7: h'550e8400e29b41d4a716446655440002',

  / wid /   300: h'b1c2d3e4f5a67890bcdef01234567890',
  / exec_act / 301: "validate_safety",
  / par /   302: [h'550e8400e29b41d4a716446655440001'],
  / pol /   303: "safety_validation_policy_v2",
  / pol_decision / 304: 0,  / approved /

  / exec_time_ms / 310: 89,
  / regulated_domain / 311: 0  / medtech /
}

The resulting DAG:

task 550e...0001 (fetch_patient_data)
  |
  v
task 550e...0002 (validate_safety)

Approximate COSE_Sign1 structure (hex, abbreviated):

d2                          -- Tag 18 (COSE_Sign1_Tagged)
84                          -- Array(4)
  58 37                     -- bstr(55) - protected header
    a4 01 26 03 78 1e ...   -- {1: -7, 3: "application/...", ...}
  a0                        -- {} - empty unprotected header
  58 c8                     -- bstr(200) - payload
    b0 01 78 28 ...         -- {1: "spiffe://...", ...}
  58 40                     -- bstr(64) - signature
    <64 bytes ES256 sig>

Example 2: Medical Device SDLC (Tasks 1 and 5)

{:numbered="false"}

Task 1 (Spec Review Agent) payload:

{
  / iss /   1: "spiffe://meddev.example/agent/spec-reviewer",
  / sub /   2: "spiffe://meddev.example/agent/spec-reviewer",
  / aud /   3: "spiffe://meddev.example/agent/code-gen",
  / exp /   4: 1772064750,
  / iat /   6: 1772064150,
  / cti /   7: h'a1b2c3d4000100000000000000000001',

  / wid /   300: h'c2d3e4f5a6b78901cdef012345678901',
  / exec_act / 301: "review_requirements_spec",
  / par /   302: [],
  / pol /   303: "spec_review_policy_v2",
  / pol_decision / 304: 0,  / approved /

  / inp_hash / 307: [-16,
    h'9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'],
  / out_hash / 308: [-16,
    h'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'],
  / regulated_domain / 311: 0,  / medtech /
  / model_version / 312: "spec-review-v3.1"
}

Task 5 (Human Release Manager Approval) payload:

{
  / iss /   1: "spiffe://meddev.example/human/release-mgr-42",
  / sub /   2: "spiffe://meddev.example/human/release-mgr-42",
  / aud /   3: "spiffe://meddev.example/system/ledger",
  / exp /   4: 1772065110,
  / iat /   6: 1772064510,
  / cti /   7: h'a1b2c3d4000100000000000000000005',

  / wid /   300: h'c2d3e4f5a6b78901cdef012345678901',
  / exec_act / 301: "approve_release",
  / par /   302: [h'a1b2c3d4000100000000000000000004'],
  / pol /   303: "release_approval_policy",
  / pol_decision / 304: 0,  / approved /
  / pol_enforcer / 305:
    "spiffe://meddev.example/human/release-mgr-42",

  / witnessed_by / 313: [
    "spiffe://meddev.example/audit/qa-observer-1"
  ],
  / regulated_domain / 311: 0  / medtech /
}

The five-task DAG:

task ...-0001 (review_requirements_spec)
  |
  v
task ...-0002 (implement_module)
  |
  v
task ...-0003 (execute_test_suite)
  |
  v
task ...-0004 (build_release_artifact)
  |
  v
task ...-0005 (approve_release) [human, witnessed]

Example 3: Parallel Execution with Join

{:numbered="false"}

A financial trading workflow where two tasks execute in parallel and a third task depends on both:

task ...-0001 (assess_risk)
  |            \
  v             v
task ...-0002  task ...-0003
(check         (verify
compliance)    liquidity)
  |            /
  v           v
task ...-0004 (execute_trade)

Task 004 ECT payload (CBOR diagnostic notation):

{
  / iss /   1: "spiffe://bank.example/agent/execution",
  / sub /   2: "spiffe://bank.example/agent/execution",
  / aud /   3: "spiffe://bank.example/system/ledger",
  / exp /   4: 1772064850,
  / iat /   6: 1772064250,
  / cti /   7: h'f1e2d3c4000400000000000000000004',

  / wid /   300: h'd3e4f5a6b7c89012def0123456789012',
  / exec_act / 301: "execute_trade",
  / par /   302: [
    h'f1e2d3c4000200000000000000000002',
    h'f1e2d3c4000300000000000000000003'
  ],
  / pol /   303: "trade_execution_policy_v3",
  / pol_decision / 304: 0,  / approved /
  / regulated_domain / 311: 1  / finance /
}

The par array with two entries records that both compliance checking and liquidity verification were completed before trade execution.

Acknowledgments

{:numbered="false"}

The author thanks the WIMSE working group for their foundational work on workload identity in multi-system environments. The concepts of Workload Identity Tokens and Workload Proof Tokens provide the identity foundation upon which execution context tracing is built.

The CBOR, COSE, and CWT communities have built an excellent constrained-environment security stack that this document builds upon.