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>
1340 lines
45 KiB
Markdown
1340 lines
45 KiB
Markdown
---
|
|
title: "CBOR Serialization of Execution Context Tokens for Distributed Agentic Workflows"
|
|
abbrev: "WIMSE ECT-CBOR"
|
|
category: std
|
|
docname: draft-nennemann-wimse-execution-context-cbor-00
|
|
submissiontype: IETF
|
|
number:
|
|
date:
|
|
v: 3
|
|
area: "Security"
|
|
workgroup: "WIMSE"
|
|
keyword:
|
|
- execution context
|
|
- workload identity
|
|
- agentic workflows
|
|
- CBOR
|
|
- COSE
|
|
- CWT
|
|
- constrained environments
|
|
- audit trail
|
|
- compliance
|
|
|
|
author:
|
|
-
|
|
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 {#cose-header}
|
|
|
|
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:
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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 {#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 {#cti-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 {#ect-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 {#uuid-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 {#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:
|
|
|
|
~~~cbor-diag
|
|
[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):
|
|
|
|
~~~cbor-diag
|
|
/ 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 {#pol-decision-enum}
|
|
|
|
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 {#regulated-domain-enum}
|
|
|
|
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 {#cddl-schema}
|
|
|
|
The following CDDL {{RFC8610}} schema defines the structure of an
|
|
ECT-CBOR payload:
|
|
|
|
~~~cddl
|
|
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 {#cose-structure}
|
|
|
|
An ECT-CBOR token is a COSE_Sign1 message {{RFC9052}} Section 4.2
|
|
with the following structure:
|
|
|
|
~~~cddl
|
|
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:
|
|
|
|
~~~cddl
|
|
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 {#transport}
|
|
|
|
## HTTP Transport {#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 {#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 {#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 {#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 {#verification}
|
|
|
|
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 {#ledger}
|
|
|
|
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:
|
|
|
|
~~~cbor-diag
|
|
{
|
|
"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 {#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 {#iana}
|
|
|
|
## 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 {#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 {#cbor-pol-decision-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 {#cbor-regulated-domain-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):
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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):
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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:
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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:
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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:
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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):
|
|
|
|
~~~cbor-diag
|
|
{
|
|
/ 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.
|