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>
This commit is contained in:
63
cbor-variant/README.md
Normal file
63
cbor-variant/README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# CBOR Serialization of Execution Context Tokens (ECT-CBOR)
|
||||||
|
|
||||||
|
**draft-nennemann-wimse-execution-context-cbor-00**
|
||||||
|
|
||||||
|
This Internet-Draft defines a CBOR/COSE/CWT serialization of Execution Context Tokens (ECTs) for the WIMSE working group.
|
||||||
|
|
||||||
|
## Relationship to the JWT Draft
|
||||||
|
|
||||||
|
This document is a **companion** to [draft-nennemann-wimse-execution-context](https://datatracker.ietf.org/doc/draft-nennemann-wimse-execution-context/), which defines the full ECT semantics using JSON/JOSE/JWT serialization.
|
||||||
|
|
||||||
|
- **JWT draft**: Normative semantic definition (claims, DAG validation, verification, operational modes, security model)
|
||||||
|
- **CBOR draft** (this document): CBOR/COSE/CWT serialization mapping, constrained-environment transports (CoAP, MQTT, raw binary)
|
||||||
|
|
||||||
|
The two drafts are designed for **independent adoption**: a deployment uses one or the other (or both in mixed-format mode), not both simultaneously for the same token.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `draft-nennemann-wimse-execution-context-cbor-00.md` | The complete Internet-Draft in kramdown-rfc format |
|
||||||
|
| `claim-mapping.md` | Standalone claim mapping reference table |
|
||||||
|
| `README.md` | This file |
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- [kramdown-rfc](https://github.com/cabo/kramdown-rfc) (Ruby gem)
|
||||||
|
- [xml2rfc](https://xml2rfc.tools.ietf.org/) (Python package)
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install tools (if not already installed)
|
||||||
|
gem install kramdown-rfc
|
||||||
|
pip install xml2rfc
|
||||||
|
|
||||||
|
# Generate XML from kramdown
|
||||||
|
kramdown-rfc2629 draft-nennemann-wimse-execution-context-cbor-00.md > draft-nennemann-wimse-execution-context-cbor-00.xml
|
||||||
|
|
||||||
|
# Generate text output
|
||||||
|
xml2rfc draft-nennemann-wimse-execution-context-cbor-00.xml --text
|
||||||
|
|
||||||
|
# Generate HTML output
|
||||||
|
xml2rfc draft-nennemann-wimse-execution-context-cbor-00.xml --html
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Design Decisions
|
||||||
|
|
||||||
|
1. **UUIDs as 16-byte binary** instead of 36-byte hyphenated text (saves 20 bytes per UUID)
|
||||||
|
2. **`jti`/`cti` as unified token+task ID** — no separate `tid` claim (matching JWT draft)
|
||||||
|
3. **`pol`/`pol_decision` OPTIONAL** but must be paired (matching JWT draft)
|
||||||
|
4. **Integer claim keys** (300-316) instead of string claim names
|
||||||
|
5. **Structured hash arrays** `[alg_id, hash_bytes]` instead of `"algorithm:base64url"` strings
|
||||||
|
6. **Integer enumerations** for pol_decision (0/1/2) and regulated_domain (0/1/2)
|
||||||
|
7. **COSE_Sign1** (single signer) matching the JWT variant's JWS Compact Serialization model
|
||||||
|
8. **~2.8x size reduction** compared to JWT variant (~365 bytes vs ~1006 bytes for a typical ECT)
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
Christian Nennemann
|
||||||
|
Independent Researcher
|
||||||
|
ietf@nennemann.de
|
||||||
111
cbor-variant/claim-mapping.md
Normal file
111
cbor-variant/claim-mapping.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# ECT Claim Mapping: JWT to CWT
|
||||||
|
|
||||||
|
This document provides a standalone reference for mapping JWT claim names from [draft-nennemann-wimse-execution-context](https://datatracker.ietf.org/doc/draft-nennemann-wimse-execution-context/) to CWT integer keys defined in [draft-nennemann-wimse-execution-context-cbor](https://datatracker.ietf.org/doc/draft-nennemann-wimse-execution-context-cbor/).
|
||||||
|
|
||||||
|
## Standard CWT Claims (Existing IANA Registry)
|
||||||
|
|
||||||
|
| JWT Claim | CWT Key | CBOR Type | Req/Opt | Description | Encoding Notes |
|
||||||
|
|:---:|:---:|:---|:---:|:---|:---|
|
||||||
|
| iss | 1 | tstr | REQ | Issuer (SPIFFE ID) | Identical text |
|
||||||
|
| sub | 2 | tstr | OPT | Subject (= iss) | Identical text |
|
||||||
|
| aud | 3 | tstr / [+ tstr] | REQ | Audience | Identical text; array for multi-audience |
|
||||||
|
| exp | 4 | int | REQ | Expiration | Integer epoch seconds (no fractions) |
|
||||||
|
| iat | 6 | int | REQ | Issued At | Integer epoch seconds (no fractions) |
|
||||||
|
| jti / cti | 7 | bstr .size 16 | REQ | Token ID / Task ID | UUID as 16-byte binary (not 36-byte text); serves as both token and task identifier |
|
||||||
|
|
||||||
|
**Note**: nbf (CWT key 5) is not used in ECTs. The `jti`/`cti` claim serves as both the token identifier (for replay detection) and the task identifier (for DAG parent references in `par`), since each ECT records exactly one task.
|
||||||
|
|
||||||
|
## ECT-Specific Claims (New Registrations)
|
||||||
|
|
||||||
|
| JWT Claim | CWT Key | CBOR Type | Req/Opt | Description | Encoding Notes |
|
||||||
|
|:---|:---:|:---|:---:|:---|:---|
|
||||||
|
| wid | 300 | bstr .size 16 | OPT | Workflow ID | UUID as 16-byte binary |
|
||||||
|
| exec_act | 301 | tstr | REQ | Action/task type | Identical text |
|
||||||
|
| par | 302 | [* bstr .size 16] | REQ | Parent ECT IDs | Array of parent cti UUIDs (16-byte binary); empty = root |
|
||||||
|
| pol | 303 | tstr | OPT | Policy rule ID | Identical text; must be paired with pol_decision |
|
||||||
|
| pol_decision | 304 | uint (0..2) | OPT | Policy decision | 0=approved, 1=rejected, 2=pending_human_review; must be paired with pol |
|
||||||
|
| pol_enforcer | 305 | tstr | OPT | Policy enforcer | Identical text (SPIFFE ID) |
|
||||||
|
| pol_timestamp | 306 | int | OPT | Policy timestamp | Integer epoch seconds |
|
||||||
|
| inp_hash | 307 | [int, bstr] | OPT | Input data hash | [COSE_alg_id, raw_hash_bytes] |
|
||||||
|
| out_hash | 308 | [int, bstr] | OPT | Output data hash | [COSE_alg_id, raw_hash_bytes] |
|
||||||
|
| inp_classification | 309 | tstr | OPT | Input classification | Identical text |
|
||||||
|
| exec_time_ms | 310 | uint | OPT | Execution time (ms) | Identical integer |
|
||||||
|
| regulated_domain | 311 | uint (0..2) | OPT | Regulatory domain | 0=medtech, 1=finance, 2=military |
|
||||||
|
| model_version | 312 | tstr | OPT | AI/ML model version | Identical text |
|
||||||
|
| witnessed_by | 313 | [+ tstr] | OPT | Witness identities | Identical text array (SPIFFE IDs) |
|
||||||
|
| compensation_required | 314 | bool | OPT | Compensation flag | CBOR true/false |
|
||||||
|
| compensation_reason | 315 | tstr | OPT | Compensation reason | Identical text |
|
||||||
|
| ext | 316 | map { tstr => any } | OPT | Extension map | Keys: reverse domain notation; values: any CBOR |
|
||||||
|
|
||||||
|
## Enumeration Mappings
|
||||||
|
|
||||||
|
### Policy Decision Values (pol_decision)
|
||||||
|
|
||||||
|
| CBOR uint | JWT string | Description |
|
||||||
|
|:---:|:---|:---|
|
||||||
|
| 0 | "approved" | Policy evaluation succeeded |
|
||||||
|
| 1 | "rejected" | Policy evaluation failed |
|
||||||
|
| 2 | "pending_human_review" | Awaiting human judgment |
|
||||||
|
|
||||||
|
### Regulated Domain Values (regulated_domain)
|
||||||
|
|
||||||
|
| CBOR uint | JWT string | Description |
|
||||||
|
|:---:|:---|:---|
|
||||||
|
| 0 | "medtech" | Medical technology and devices |
|
||||||
|
| 1 | "finance" | Financial services and trading |
|
||||||
|
| 2 | "military" | Military and defense |
|
||||||
|
|
||||||
|
## Hash Algorithm Mapping
|
||||||
|
|
||||||
|
JWT ECTs use the string format `"algorithm:base64url-hash"`. CBOR ECTs use the structured array `[cose_algorithm_id, raw_hash_bytes]`.
|
||||||
|
|
||||||
|
| JWT Hash Algorithm String | COSE Algorithm ID | Reference |
|
||||||
|
|:---|:---:|:---|
|
||||||
|
| sha-256 | -16 | RFC 9053 |
|
||||||
|
| sha-384 | -43 | RFC 9053 |
|
||||||
|
| sha-512 | -44 | RFC 9053 |
|
||||||
|
|
||||||
|
## COSE Header Parameters
|
||||||
|
|
||||||
|
| JOSE Parameter | COSE Label | CBOR Type | Description |
|
||||||
|
|:---|:---:|:---|:---|
|
||||||
|
| alg | 1 | int | Signature algorithm (e.g., -7 = ES256) |
|
||||||
|
| (content type) | 3 | tstr / uint | "application/wimse-exec+cwt" |
|
||||||
|
| kid | 4 | bstr | Key identifier from WIT |
|
||||||
|
| typ | 16 | tstr | "wimse-exec+cwt" |
|
||||||
|
|
||||||
|
## Quick Reference: JWT Example to CBOR Diagnostic
|
||||||
|
|
||||||
|
### JWT Payload
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"iss": "spiffe://example.com/agent/clinical",
|
||||||
|
"aud": "spiffe://example.com/agent/safety",
|
||||||
|
"iat": 1772064150,
|
||||||
|
"exp": 1772064750,
|
||||||
|
"jti": "550e8400-e29b-41d4-a716-446655440001",
|
||||||
|
"exec_act": "recommend_treatment",
|
||||||
|
"par": [],
|
||||||
|
"pol": "clinical_reasoning_policy_v2",
|
||||||
|
"pol_decision": "approved",
|
||||||
|
"regulated_domain": "medtech"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Equivalent CBOR Diagnostic
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
1: "spiffe://example.com/agent/clinical",
|
||||||
|
3: "spiffe://example.com/agent/safety",
|
||||||
|
6: 1772064150,
|
||||||
|
4: 1772064750,
|
||||||
|
7: h'550e8400e29b41d4a716446655440001',
|
||||||
|
301: "recommend_treatment",
|
||||||
|
302: [],
|
||||||
|
303: "clinical_reasoning_policy_v2",
|
||||||
|
304: 0,
|
||||||
|
311: 0
|
||||||
|
}
|
||||||
|
```
|
||||||
1339
cbor-variant/draft-nennemann-wimse-execution-context-cbor-00.md
Normal file
1339
cbor-variant/draft-nennemann-wimse-execution-context-cbor-00.md
Normal file
File diff suppressed because it is too large
Load Diff
354
master-prompt.md
Normal file
354
master-prompt.md
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
# Master Prompt: Generate CBOR/COSE Variant of WIMSE Execution Context Token Draft
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
You are an IETF standards author with deep expertise in CBOR (RFC 8949), COSE (RFC 9052, RFC 9053), CWT (RFC 8392), and the WIMSE working group architecture. You have been given the file `draft-nennemann-wimse-execution-context-00.md` which defines **Execution Context Tokens (ECTs)** — a JWT/JWS-based extension to WIMSE for recording task execution, DAG-structured dependency ordering, and policy evaluation outcomes in regulated agentic workflows.
|
||||||
|
|
||||||
|
Your task is to produce a **companion Internet-Draft** that defines the same ECT semantics using **CBOR/COSE/CWT** serialization instead of JSON/JOSE/JWT. The new draft is designed for constrained environments, non-HTTP transports (CoAP, MQTT, Layer 2 protocols), and bandwidth-sensitive deployments.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
### Step 1 — Read and Analyze the Source Draft
|
||||||
|
|
||||||
|
Read `draft-nennemann-wimse-execution-context-00.md` completely. Extract and internalize:
|
||||||
|
|
||||||
|
1. **All ECT claims** — both standard JWT claims (iss, sub, aud, iat, exp, jti) and ECT-specific claims (wid, tid, exec_act, par, pol, pol_decision, pol_enforcer, pol_timestamp, inp_hash, out_hash, inp_classification, exec_time_ms, regulated_domain, model_version, witnessed_by, compensation_required, compensation_reason, ext).
|
||||||
|
2. **The JOSE header requirements** — alg, typ ("wimse-exec+jwt"), kid.
|
||||||
|
3. **The DAG validation algorithm** — parent existence, temporal ordering, cycle detection, policy decision propagation, trust domain consistency.
|
||||||
|
4. **The verification procedure** — all 15 steps.
|
||||||
|
5. **The three operational modes** — point-to-point, deferred ledger, full ledger.
|
||||||
|
6. **The audit ledger interface** — required properties, entry structure.
|
||||||
|
7. **The HTTP transport mechanism** — Execution-Context header field.
|
||||||
|
8. **Security considerations** — threat model, self-assertion limitation, witness attestation, replay prevention, key compromise, collusion, DoS, timestamp accuracy, size constraints.
|
||||||
|
9. **Privacy considerations** — data minimization, storage access control, regulatory access.
|
||||||
|
10. **IANA registrations** — media type, HTTP header, JWT claims, policy decision values registry, regulated domain values registry.
|
||||||
|
11. **All normative and informative references**.
|
||||||
|
12. **The regulatory motivation** — EU AI Act, FDA 21 CFR Part 11, MiFID II, DORA, EU MDR.
|
||||||
|
|
||||||
|
### Step 2 — Create the CBOR Draft
|
||||||
|
|
||||||
|
Create the file `cbor-variant/draft-nennemann-wimse-execution-context-cbor-00.md` in kramdown-rfc format (same XML/markdown format as the source draft, compatible with `kramdown-rfc` / `xml2rfc`).
|
||||||
|
|
||||||
|
#### 2.1 — Metadata and Front Matter
|
||||||
|
|
||||||
|
- **Title**: `"CBOR Serialization of Execution Context Tokens for Distributed Agentic Workflows"`
|
||||||
|
- **Abbreviation**: `"WIMSE ECT-CBOR"`
|
||||||
|
- **Document name**: `draft-nennemann-wimse-execution-context-cbor-00`
|
||||||
|
- **Submission type**: IETF
|
||||||
|
- **Area**: Security
|
||||||
|
- **Workgroup**: WIMSE
|
||||||
|
- **Author**: Christian Nennemann, Independent Researcher, ietf@nennemann.de
|
||||||
|
|
||||||
|
#### 2.2 — Normative References
|
||||||
|
|
||||||
|
Include (at minimum):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
normative:
|
||||||
|
RFC8392: # CBOR Web Token (CWT)
|
||||||
|
RFC8949: # CBOR
|
||||||
|
RFC9052: # COSE Signatures, MAC, Encryption
|
||||||
|
RFC9053: # COSE Algorithms
|
||||||
|
RFC9338: # COSE Countersignatures
|
||||||
|
RFC7049: # (if needed for back-compat notes)
|
||||||
|
RFC9562: # UUID
|
||||||
|
I-D.ietf-wimse-arch:
|
||||||
|
I-D.ietf-wimse-s2s-protocol:
|
||||||
|
I-D.nennemann-wimse-execution-context: # The JWT variant (this is the companion)
|
||||||
|
```
|
||||||
|
|
||||||
|
Add informative references as appropriate (CoAP RFC 7252, MQTT, OSCORE RFC 8613, EDHOC, EU AI Act, FDA, etc.).
|
||||||
|
|
||||||
|
#### 2.3 — Abstract
|
||||||
|
|
||||||
|
Write an abstract that:
|
||||||
|
- States this document defines a CBOR/COSE serialization of Execution Context Tokens (ECTs).
|
||||||
|
- References the companion JWT-based draft (`draft-nennemann-wimse-execution-context`) for the full semantic definition.
|
||||||
|
- Highlights the target environments: constrained devices, non-HTTP transports, bandwidth-sensitive deployments.
|
||||||
|
- Notes that this serialization preserves all ECT semantics (DAG structure, policy evaluation, compliance state) while using COSE_Sign1 and CWT claims.
|
||||||
|
|
||||||
|
#### 2.4 — Introduction
|
||||||
|
|
||||||
|
- Motivate why a CBOR variant is needed alongside the JWT variant.
|
||||||
|
- Reference the JWT draft as the normative semantic definition.
|
||||||
|
- Explain the target deployment scenarios: IoT agents, medical devices (constrained environments matching the medtech use case), edge computing agents, CoAP-based agent-to-agent communication.
|
||||||
|
- Explicitly state: this document defines **only** the serialization mapping. The semantics, DAG validation rules, verification logic, operational modes, and security model are defined in the JWT draft and apply identically here.
|
||||||
|
|
||||||
|
#### 2.5 — COSE Header Parameters
|
||||||
|
|
||||||
|
Define the COSE protected header for ECTs:
|
||||||
|
|
||||||
|
- **alg (1)**: REQUIRED. Algorithm identifier. MUST support ES256 (-7). MUST NOT be a symmetric algorithm or indicate no signature.
|
||||||
|
- **content type (3)**: REQUIRED. MUST be set to the CoAP Content-Format ID for `application/wimse-exec+cwt` (to be registered).
|
||||||
|
- **kid (4)**: REQUIRED. Key identifier referencing the public key from the agent's WIT. Encoded as bstr.
|
||||||
|
- **typ (16)**: REQUIRED. MUST be `wimse-exec+cwt`. (Per RFC 9596 / CWT typ claim.)
|
||||||
|
|
||||||
|
Note: ECTs MUST use `COSE_Sign1` (single signer) structure, not `COSE_Sign` (multi-signer), matching the single-agent-signs model of the JWT variant.
|
||||||
|
|
||||||
|
#### 2.6 — CWT Claim Mapping (CRITICAL SECTION)
|
||||||
|
|
||||||
|
This is the core of the draft. Define a complete mapping table from JWT claim names to CBOR integer keys.
|
||||||
|
|
||||||
|
**Standard CWT claims** (reuse existing IANA CWT claim keys):
|
||||||
|
|
||||||
|
| JWT Claim | CWT Key (int) | CBOR Type | Description |
|
||||||
|
|-----------|---------------|---------------|--------------------------------|
|
||||||
|
| iss | 1 | tstr | Issuer (SPIFFE ID) |
|
||||||
|
| sub | 2 | tstr | Subject (= iss) |
|
||||||
|
| aud | 3 | tstr / [tstr] | Audience |
|
||||||
|
| exp | 4 | int (#6.1) | Expiration (epoch seconds) |
|
||||||
|
| nbf | 5 | (not used) | Not Before (not used in ECTs) |
|
||||||
|
| iat | 6 | int (#6.1) | Issued At (epoch seconds) |
|
||||||
|
| cti | 7 | bstr | CWT ID (= jti equivalent, UUID as 16-byte binary) |
|
||||||
|
|
||||||
|
**ECT-specific claims** — request new CBOR integer keys from a private-use or early-allocation range. Use a contiguous block starting from a clearly documented base. Proposed mapping (the exact numbers are illustrative; the draft should request IANA allocation):
|
||||||
|
|
||||||
|
| JWT Claim | Proposed CWT Key | CBOR Type | Notes |
|
||||||
|
|------------------------|-------------------|--------------------|---------------------------------------------|
|
||||||
|
| wid | 300 | bstr (16 bytes) | Workflow ID — UUID as binary |
|
||||||
|
| tid | 301 | bstr (16 bytes) | Task ID — UUID as binary |
|
||||||
|
| exec_act | 302 | tstr | Action/task type identifier |
|
||||||
|
| par | 303 | [bstr] | Array of parent task ID UUIDs (binary) |
|
||||||
|
| pol | 304 | tstr | Policy rule identifier |
|
||||||
|
| pol_decision | 305 | uint | Policy decision (0=approved, 1=rejected, 2=pending_human_review) |
|
||||||
|
| pol_enforcer | 306 | tstr | Policy enforcer identity (SPIFFE ID) |
|
||||||
|
| pol_timestamp | 307 | int (#6.1) | Policy decision timestamp |
|
||||||
|
| inp_hash | 308 | [int, bstr] | [hash_alg_id, hash_value] — use COSE hash algorithm IDs |
|
||||||
|
| out_hash | 309 | [int, bstr] | Same format as inp_hash |
|
||||||
|
| inp_classification | 310 | tstr | Data sensitivity classification |
|
||||||
|
| exec_time_ms | 311 | uint | Execution duration in milliseconds |
|
||||||
|
| regulated_domain | 312 | uint | Enumerated: 0=medtech, 1=finance, 2=military |
|
||||||
|
| model_version | 313 | tstr | AI/ML model version string |
|
||||||
|
| witnessed_by | 314 | [tstr] | Array of witness SPIFFE IDs |
|
||||||
|
| compensation_required | 315 | bool | Compensation flag |
|
||||||
|
| compensation_reason | 316 | tstr | Compensation reason identifier |
|
||||||
|
| ext | 317 | map | Extension map (keys: tstr in reverse domain notation) |
|
||||||
|
|
||||||
|
**Important design decisions to document:**
|
||||||
|
|
||||||
|
1. **UUIDs as binary**: In CBOR, UUIDs (wid, tid, par entries, cti) MUST be encoded as 16-byte `bstr` rather than text, saving 20 bytes per UUID vs. the hyphenated text form. Reference RFC 9562 Section 4 for UUID binary format. Optionally use CBOR tag 37 (RFC 9562) to explicitly tag UUID bstr values.
|
||||||
|
2. **Hash encoding**: Instead of the JWT format `"sha-256:base64url-encoded-hash"`, use a structured CBOR array `[hash_algorithm_id, hash_bytes]` where `hash_algorithm_id` is from the COSE Algorithms registry (e.g., SHA-256 = -16) and `hash_bytes` is the raw hash as `bstr`. This is more compact and type-safe.
|
||||||
|
3. **Policy decision as enum**: Instead of string values, use uint enumeration (0, 1, 2). Define the mapping explicitly and register it.
|
||||||
|
4. **Regulated domain as enum**: Same approach — uint enumeration instead of strings.
|
||||||
|
5. **Timestamps**: Use standard CWT NumericDate (integer seconds since epoch), same as JWT but without fractional seconds. Optionally note that tag 1 (epoch-based date/time) MAY be used.
|
||||||
|
|
||||||
|
#### 2.7 — CDDL Schema
|
||||||
|
|
||||||
|
Provide a complete CDDL (RFC 8610) schema for the ECT-CBOR payload. Example structure:
|
||||||
|
|
||||||
|
```cddl
|
||||||
|
ect-cbor-claims = {
|
||||||
|
; Standard CWT claims
|
||||||
|
1 => tstr, ; iss — SPIFFE ID
|
||||||
|
? 2 => tstr, ; sub — SPIFFE ID (= iss)
|
||||||
|
3 => tstr / [+ tstr], ; aud
|
||||||
|
4 => int, ; exp
|
||||||
|
6 => int, ; iat
|
||||||
|
7 => bstr .size 16, ; cti — UUID binary
|
||||||
|
|
||||||
|
; Execution Context claims
|
||||||
|
? 300 => bstr .size 16, ; wid — Workflow ID (UUID)
|
||||||
|
301 => bstr .size 16, ; tid — Task ID (UUID)
|
||||||
|
302 => tstr, ; exec_act
|
||||||
|
303 => [* bstr .size 16], ; par — parent task IDs
|
||||||
|
304 => tstr, ; pol
|
||||||
|
305 => 0..2, ; pol_decision
|
||||||
|
|
||||||
|
; Optional policy claims
|
||||||
|
? 306 => tstr, ; pol_enforcer
|
||||||
|
? 307 => int, ; pol_timestamp
|
||||||
|
|
||||||
|
; Optional data integrity
|
||||||
|
? 308 => [int, bstr], ; inp_hash [alg_id, hash]
|
||||||
|
? 309 => [int, bstr], ; out_hash [alg_id, hash]
|
||||||
|
? 310 => tstr, ; inp_classification
|
||||||
|
|
||||||
|
; Optional metadata
|
||||||
|
? 311 => uint, ; exec_time_ms
|
||||||
|
? 312 => 0..2, ; regulated_domain
|
||||||
|
? 313 => tstr, ; model_version
|
||||||
|
? 314 => [+ tstr], ; witnessed_by
|
||||||
|
? 315 => bool, ; compensation_required
|
||||||
|
? 316 => tstr, ; compensation_reason
|
||||||
|
? 317 => { + tstr => any }, ; ext
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.8 — COSE Structure
|
||||||
|
|
||||||
|
Define the complete COSE_Sign1 structure for an ECT:
|
||||||
|
|
||||||
|
```
|
||||||
|
ECT_COSE = COSE_Sign1 = [
|
||||||
|
protected: bstr, ; Serialized COSE protected header
|
||||||
|
unprotected: {}, ; MUST be empty for ECTs
|
||||||
|
payload: bstr, ; Serialized CBOR ECT claims map
|
||||||
|
signature: bstr ; ECDSA signature
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- Unprotected headers MUST be empty (all header parameters are in the protected bucket for integrity).
|
||||||
|
- The payload is the CBOR-serialized ECT claims map.
|
||||||
|
- External AAD (Additional Authenticated Data) is empty unless bound to a transport-layer context (e.g., OSCORE).
|
||||||
|
|
||||||
|
#### 2.9 — Transport Mechanisms
|
||||||
|
|
||||||
|
Define transport options beyond HTTP:
|
||||||
|
|
||||||
|
**2.9.1 — HTTP Transport**
|
||||||
|
|
||||||
|
Same `Execution-Context` header field as the JWT variant. The value is the Base64url-encoded COSE_Sign1 structure. Receivers distinguish JWT vs. CBOR ECTs by:
|
||||||
|
- JWT ECTs start with `eyJ` (Base64url of `{"`) — JSON object.
|
||||||
|
- CBOR ECTs start with `0o` or similar (Base64url of CBOR tag/array prefix `0xd2` for COSE_Sign1 tag 18).
|
||||||
|
|
||||||
|
Alternatively, define a separate header `Execution-Context-CBOR` or use content negotiation. Document the tradeoffs and pick one approach as RECOMMENDED.
|
||||||
|
|
||||||
|
**2.9.2 — CoAP Transport**
|
||||||
|
|
||||||
|
Define a new CoAP Option for carrying ECTs:
|
||||||
|
- Option Number: TBD (request IANA allocation)
|
||||||
|
- Name: Execution-Context
|
||||||
|
- Format: opaque (COSE_Sign1 bytes)
|
||||||
|
- Reference: This document
|
||||||
|
|
||||||
|
Or use a CoAP Content-Format registration for `application/wimse-exec+cwt`.
|
||||||
|
|
||||||
|
**2.9.3 — MQTT Transport**
|
||||||
|
|
||||||
|
Briefly describe carrying ECTs as MQTT User Properties or within the payload envelope. Keep this informational, not normative.
|
||||||
|
|
||||||
|
**2.9.4 — Raw Binary Transport**
|
||||||
|
|
||||||
|
For Layer 2 / non-IP protocols, ECTs can be embedded directly as COSE_Sign1 byte sequences. Document byte-level framing: length-prefix + COSE_Sign1 bytes.
|
||||||
|
|
||||||
|
#### 2.10 — Verification Procedure
|
||||||
|
|
||||||
|
Reference the JWT draft's verification procedure (Section "Signature and Token Verification") and describe the COSE-specific differences:
|
||||||
|
|
||||||
|
1. Parse the COSE_Sign1 structure per RFC 9052 Section 4.4.
|
||||||
|
2. Verify the `content type` protected header parameter is `application/wimse-exec+cwt`.
|
||||||
|
3. Verify the `alg` protected header parameter is not symmetric and not absent.
|
||||||
|
4. Retrieve the public key using `kid` from the protected header.
|
||||||
|
5. Verify the COSE_Sign1 signature per RFC 9052 Section 4.4.
|
||||||
|
6. (All remaining verification steps — key revocation, algorithm alignment with WIT, issuer matching, audience, expiration, iat freshness, required claims, pol_decision, DAG validation — are **identical** to the JWT variant and are incorporated by reference.)
|
||||||
|
|
||||||
|
#### 2.11 — Audit Ledger Considerations
|
||||||
|
|
||||||
|
The ledger entry structure for CBOR ECTs:
|
||||||
|
|
||||||
|
```cbor-diag
|
||||||
|
{
|
||||||
|
"ledger_sequence": 42,
|
||||||
|
"task_id": h'550e8400e29b41d4a716446655440001',
|
||||||
|
"agent_id": "spiffe://example.com/agent/clinical",
|
||||||
|
"action": "recommend_treatment",
|
||||||
|
"parents": [],
|
||||||
|
"ect_cose": h'D28443...', ; Full COSE_Sign1 bytes
|
||||||
|
"signature_verified": true,
|
||||||
|
"verification_timestamp": 1(1772064151),
|
||||||
|
"stored_timestamp": 1(1772064151)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Ledgers that need to store both JWT and CBOR ECTs SHOULD use a discriminator field or detect the format from the raw bytes.
|
||||||
|
|
||||||
|
#### 2.12 — Size Comparison
|
||||||
|
|
||||||
|
Include a concrete size comparison between the JWT and CBOR variants for the "Complete ECT Example" from the JWT draft (Section 4.8). Calculate approximate sizes:
|
||||||
|
|
||||||
|
- **JWT variant**: JOSE header (~70 bytes) + payload (~600 bytes JSON) + signature (~88 bytes ES256) + Base64url overhead (~33%) ≈ ~1010 bytes
|
||||||
|
- **CBOR variant**: Protected header (~15 bytes CBOR) + payload (~250 bytes CBOR) + signature (~64 bytes raw P-256) ≈ ~330 bytes
|
||||||
|
|
||||||
|
This ~3x reduction is significant for constrained environments. Document the exact calculation.
|
||||||
|
|
||||||
|
#### 2.13 — Security Considerations
|
||||||
|
|
||||||
|
Reference the JWT draft's security considerations in full and add CBOR/COSE-specific considerations:
|
||||||
|
|
||||||
|
- **CBOR canonicalization**: Discuss deterministic encoding (RFC 8949 Section 4.2) requirements for ECT payloads to ensure consistent hashing and signature verification.
|
||||||
|
- **COSE algorithm agility**: Same constraints as JWT variant — no symmetric algorithms, no "none".
|
||||||
|
- **CoAP-specific**: DTLS or OSCORE MUST be used for transport security when using CoAP.
|
||||||
|
- **MQTT-specific**: TLS MUST be used. Note that MQTT User Properties are not encrypted by MQTT itself.
|
||||||
|
- **Binary transport**: Emphasize that ECT signatures provide message-level security, but transport-layer integrity is still RECOMMENDED.
|
||||||
|
|
||||||
|
#### 2.14 — Privacy Considerations
|
||||||
|
|
||||||
|
Reference the JWT draft's privacy considerations. Note that CBOR's binary encoding does not change the privacy properties — the same claims are present, just encoded differently.
|
||||||
|
|
||||||
|
#### 2.15 — IANA Considerations
|
||||||
|
|
||||||
|
Request the following registrations:
|
||||||
|
|
||||||
|
1. **Media Type**: `application/wimse-exec+cwt`
|
||||||
|
2. **CoAP Content-Format**: For `application/wimse-exec+cwt` (TBD number)
|
||||||
|
3. **CWT Claims**: Register all ECT-specific claim keys (300-317 or wherever allocated) in the "CBOR Web Token (CWT) Claims" registry (IANA).
|
||||||
|
4. **ECT-CBOR Policy Decision Values**: Integer enum registry (0=approved, 1=rejected, 2=pending_human_review)
|
||||||
|
5. **ECT-CBOR Regulated Domain Values**: Integer enum registry (0=medtech, 1=finance, 2=military)
|
||||||
|
6. **CoAP Option Number** (if defining a CoAP option): TBD
|
||||||
|
|
||||||
|
#### 2.16 — Examples
|
||||||
|
|
||||||
|
Provide CBOR diagnostic notation examples parallel to the JWT draft's examples:
|
||||||
|
|
||||||
|
1. **Simple Two-Agent Workflow** — Show the CBOR diagnostic notation for the same scenario as JWT Example 1.
|
||||||
|
2. **Medical Device SDLC** — Show at least 2 tasks from the SDLC example in CBOR diagnostic notation.
|
||||||
|
3. **Parallel Execution with Join** — Show the join task with multiple parents.
|
||||||
|
|
||||||
|
For each example, show:
|
||||||
|
- The CBOR diagnostic notation of the protected header
|
||||||
|
- The CBOR diagnostic notation of the payload
|
||||||
|
- A hex dump of the serialized COSE_Sign1 (abbreviated, showing structure)
|
||||||
|
|
||||||
|
#### 2.17 — Related Work / Appendix
|
||||||
|
|
||||||
|
Add a brief section mapping this draft to the JWT draft and to other CBOR-based standards:
|
||||||
|
- Reference how CWT relates to JWT (RFC 8392 ↔ RFC 7519)
|
||||||
|
- Reference how COSE relates to JOSE (RFC 9052 ↔ RFC 7515)
|
||||||
|
- Note that EAT (Entity Attestation Token, RFC 9711 if published) uses CWT and could be a future integration point.
|
||||||
|
- Reference SUIT (Software Update for IoT) manifests as another CBOR-based constrained-environment standard.
|
||||||
|
|
||||||
|
### Step 3 — Output Structure
|
||||||
|
|
||||||
|
Create the output in a folder called `cbor-variant/` containing:
|
||||||
|
|
||||||
|
```
|
||||||
|
cbor-variant/
|
||||||
|
├── draft-nennemann-wimse-execution-context-cbor-00.md # The complete I-D in kramdown-rfc format
|
||||||
|
├── README.md # Build instructions, relationship to JWT draft
|
||||||
|
└── claim-mapping.md # Standalone claim mapping reference table
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4 — Quality Checks
|
||||||
|
|
||||||
|
Before finalizing, verify:
|
||||||
|
|
||||||
|
- [ ] Every claim from the JWT draft has a CBOR mapping
|
||||||
|
- [ ] All REQUIRED/OPTIONAL designations match the JWT draft
|
||||||
|
- [ ] The CDDL schema is syntactically valid
|
||||||
|
- [ ] COSE_Sign1 structure is correctly defined per RFC 9052
|
||||||
|
- [ ] All IANA registrations are complete
|
||||||
|
- [ ] The verification procedure is complete (by reference + COSE-specific steps)
|
||||||
|
- [ ] The DAG validation is incorporated by reference, not redefined
|
||||||
|
- [ ] Security considerations cover CBOR/COSE-specific threats
|
||||||
|
- [ ] Examples use valid CBOR diagnostic notation
|
||||||
|
- [ ] The kramdown-rfc metadata is well-formed
|
||||||
|
- [ ] Normative references are complete and correctly formatted
|
||||||
|
- [ ] The document can be processed by `kramdown-rfc` without errors
|
||||||
|
- [ ] BCP 14 boilerplate is included
|
||||||
|
- [ ] The abstract does not contain references (per I-D nits rules)
|
||||||
|
|
||||||
|
## Key Design Principles
|
||||||
|
|
||||||
|
1. **Semantic equivalence**: The CBOR ECT MUST carry exactly the same information as the JWT ECT. No semantic divergence.
|
||||||
|
2. **Format optimization**: Use CBOR's strengths — binary UUIDs, integer keys, compact encoding, structured hash representation.
|
||||||
|
3. **Reference, don't redefine**: The JWT draft is the normative semantic definition. This draft defines the encoding and transport mapping. DAG validation, verification logic, operational modes, and security model are incorporated by reference.
|
||||||
|
4. **IETF conventions**: Follow CBOR/COSE/CWT conventions established by existing RFCs. Don't invent new patterns where existing ones work.
|
||||||
|
5. **Independent adoption**: The CBOR draft should be usable independently (with the JWT draft as a normative reference for semantics), not require both formats in a single deployment.
|
||||||
|
|
||||||
|
## Author Information
|
||||||
|
|
||||||
|
```
|
||||||
|
Christian Nennemann
|
||||||
|
Independent Researcher
|
||||||
|
Email: ietf@nennemann.de
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user