Files
ietf-wimse-ect-cbor/cbor-variant/claim-mapping.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

112 lines
4.8 KiB
Markdown

# 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
}
```