The Canonical Action Identifier (CAID)
draft-schrock-canonical-action-identifier-00
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Author | Iman Schrock | ||
| Last updated | 2026-07-19 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Additional resources |
CAID reference implementations, registry, and conformance vectors
|
||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-schrock-canonical-action-identifier-00
Network Working Group I. Schrock
Internet-Draft EMILIA Protocol, Inc.
Intended status: Informational 19 July 2026
Expires: 20 January 2027
The Canonical Action Identifier (CAID)
draft-schrock-canonical-action-identifier-00
Abstract
Authorization, delegation, execution, and audit artifacts often
identify an action using format-local content and digests. Those
digests are not directly comparable when the formats select or encode
material action fields differently. This document defines the
Canonical Action IDentifier (CAID): a typed action object, a
canonicalization and digest suite, a compact identifier string, and
immutable action-type definitions with required material fields. It
also defines an Action-Mapping Profile for projecting independently
verified native artifacts into a common action type, with the closed
results EQUIVALENT_UNDER_PROFILE, NOT_EQUIVALENT, and INDETERMINATE.
CAID carries no trust semantics. It does not establish identity,
authority, authorization, execution, safety, or legal reliance.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 20 January 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
Schrock Expires 20 January 2027 [Page 1]
Internet-Draft CAID July 2026
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3
2. The Action Object . . . . . . . . . . . . . . . . . . . . . . 4
3. Suites and the Identifier . . . . . . . . . . . . . . . . . . 5
3.1. Suites . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2. The Digest . . . . . . . . . . . . . . . . . . . . . . . 5
3.3. Identifier Syntax . . . . . . . . . . . . . . . . . . . . 6
3.4. Parsing . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.5. Equality . . . . . . . . . . . . . . . . . . . . . . . . 7
4. Action Types and the Registry . . . . . . . . . . . . . . . . 7
4.1. Type Names and Versioning . . . . . . . . . . . . . . . . 8
4.2. The Type Definition Schema . . . . . . . . . . . . . . . 8
4.3. Field Types . . . . . . . . . . . . . . . . . . . . . . . 9
4.4. Definition Sources and Unknown Types . . . . . . . . . . 10
5. Computation . . . . . . . . . . . . . . . . . . . . . . . . . 10
6. Verification . . . . . . . . . . . . . . . . . . . . . . . . 11
7. Action-Mapping Profile . . . . . . . . . . . . . . . . . . . 11
7.1. Native Verification Boundary . . . . . . . . . . . . . . 12
7.2. Mapping Profile Object . . . . . . . . . . . . . . . . . 12
7.3. Mapping and Comparison Algorithm . . . . . . . . . . . . 14
7.4. Completeness Assumption . . . . . . . . . . . . . . . . . 15
8. What a CAID Is Not . . . . . . . . . . . . . . . . . . . . . 15
9. Security Considerations . . . . . . . . . . . . . . . . . . . 16
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 18
11.1. Normative References . . . . . . . . . . . . . . . . . . 18
11.2. Informative References . . . . . . . . . . . . . . . . . 19
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 20
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20
1. Introduction
Many formats for permits, receipts, mandates, delegation, and outcome
evidence reference "the action" by digest. Each format selects an
action representation and canonicalization appropriate to its own
protocol. The resulting identifiers are useful inside that format
but are not necessarily comparable across formats.
Schrock Expires 20 January 2027 [Page 2]
Internet-Draft CAID July 2026
This creates two interoperability risks. The first is the material-
fields failure: a digest over an underspecified object can omit the
facts a relying party considers material. A digest computed over
{"action": "wire"} commits to no amount, no currency, and no
beneficiary; the artifact carrying it looks cryptographically bound
to an action while committing to nothing that makes the action
consequential. The second is the join failure: absent an agreed
common definition, two artifacts about the same action, issued by
different systems in different formats, can carry digests that cannot
be compared without an explicit, reviewable mapping.
This document defines the Canonical Action IDentifier (CAID) to close
both gaps. A CAID names typed content: an action object that
declares its own type, carries every material field that type
requires, is canonicalized under a registered suite, and is digested.
The identifier is a compact string embedding the version, the action
type, the suite, and the digest. When formats cannot emit the same
action object, an Action-Mapping Profile (Section 7) defines a
relying-party-pinned, loss-aware projection into the common type and
abstains when the comparison cannot be made.
As informative examples of the artifact classes that can carry a
CAID: authorization receipts [I-D.schrock-ep-authorization-receipts],
permit receipts [I-D.lee-orprg-permit-receipts], and execution
outcome attestations [I-D.morrow-sogomonian-exec-outcome-attest] each
reference an action by digest and could carry a CAID in place of or
alongside their existing action reference. These citations are
examples only; this document neither depends on nor modifies any of
them, and carrying a CAID changes nothing about how any such artifact
is verified.
A CAID deliberately carries no trust semantics. It does not assert
that an action was authorized, executed, safe, or wise. Section 8
states the boundary normatively.
1.1. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
Action object: The typed data object, defined in Section 2, over
which a CAID's digest is computed.
Action type: A versioned type name whose definition (Section 4)
Schrock Expires 20 January 2027 [Page 3]
Internet-Draft CAID July 2026
declares the material fields an action object of that type is
required to carry.
Material field: A field that a type definition declares REQUIRED
because its absence would leave the digest uncommitted to
something that makes the action consequential.
Suite: A registered pairing of a canonicalization scheme and a
digest algorithm (Section 3.1).
Definition source: A collection of type definitions in the schema of
Section 4.2 that an implementation is configured with: the public
registry, a local definitions file, or both.
Issuer: The party that constructs an action object and computes its
CAID.
Verifier: The party that checks a presented CAID against a presented
action object by recomputation (Section 6).
Mapping profile: A hash-identified projection, pinned by the relying
party, from one exact source format and version into one CAID
action type (Section 7).
Native verifier: The verifier defined by a source artifact's own
specification. Native verification precedes mapping and is
outside the CAID trust boundary.
2. The Action Object
An action object is a JSON object (or, under a CBOR suite, a CBOR
map) that identifies material action content. The same object is
referenced, by CAID, from pre-execution artifacts (permits,
challenges, receipts) and post-execution artifacts (outcome
attestations, audit records, reliance events).
An action object:
* MUST contain an action_type member whose value is a registered or
locally defined versioned type name (Section 4). The type is
inside the digested content, so the type asserted by an identifier
cannot be swapped without changing the digest.
* MUST contain every REQUIRED material field of that type, encoded
per the field types the type definition declares (Section 4.3).
* MAY contain additional members beyond those the type definition
declares. Extra members are covered by the digest.
Schrock Expires 20 January 2027 [Page 4]
Internet-Draft CAID July 2026
* MUST NOT encode money or quantity values as JSON numbers where the
type definition declares the field amount-string. Floating-point
and precision malleability across languages makes numeric
encodings of money unsafe for canonicalization.
* Numbers follow a value-based rule: a JSON number is accepted if
and only if its IEEE 754 double-precision value is an integer with
magnitude at most 2^53-1, and it is serialized as that integer in
plain decimal form. The literal form is irrelevant: the literals
1e3 and 2.0 denote the integers 1000 and 2, exactly as an
ECMAScript JSON parser sees them. Fractional, NaN, infinite, and
out-of-range values are refused as unsupported_number by every
conforming implementation, at any depth. Fractional quantities
are carried as strings. Rationale: ECMAScript number
serialization is the leading source of cross-language
canonicalization divergence, and a rule over the parsed value is
the only one that every language can implement identically; a rule
over the literal form cannot be enforced by implementations, such
as ECMAScript, whose JSON parsers do not preserve it.
3. Suites and the Identifier
3.1. Suites
A suite names a canonicalization scheme and a digest algorithm. This
document defines two suites; the suite registry (Section 10) carries
one entry per suite.
jcs-sha256: The JSON Canonicalization Scheme [RFC8785] followed by
SHA-256 [RFC6234]. Support for this suite is REQUIRED for
conforming implementations.
cbor-sha256: CBOR core deterministic encoding (Section 4.2 of
[RFC8949]) followed by SHA-256 [RFC6234]. This suite is defined
in this version; implementations MAY support it.
3.2. The Digest
The digest is computed directly over the canonical bytes of the
action object:
digest = SHA-256(canonical_bytes(action_object))
There is deliberately NO domain separation prefix. The object is
self-typed via its action_type member, and a design goal of CAID is
that existing artifact formats can adopt the identical digest they
may already compute over canonical bytes. Conforming verifiers MUST
check that the in-object action_type equals the action type carried
Schrock Expires 20 January 2027 [Page 5]
Internet-Draft CAID July 2026
in the CAID string (Section 6); that check, not a byte prefix, is
where cross-context reinterpretation dies. Section 9 states this
trade explicitly.
3.3. Identifier Syntax
The identifier is a compact string:
caid:1:<action_type>:<suite>:<digest-b64url>
For example:
caid:1:payment.release.1:jcs-sha256:qL8R4QIcQ_ZsRqOAbeRfcZhilN_MksRt
DaErMPJk0vM
(The example digest is shown wrapped for column width; the identifier
itself contains no whitespace.)
The grammar, in the ABNF of [RFC5234]:
caid = "caid:" caid-version ":" action-type ":"
suite ":" digest
caid-version = "1"
action-type = 1*( name-segment "." ) type-version
name-segment = lower-char *( lower-char / DIGIT / "-" )
type-version = pos-int
pos-int = %x31-39 *DIGIT ; positive integer, no leading zero
suite = lower-char *( lower-char / DIGIT / "-" )
digest = 1*b64url-char
b64url-char = %x41-5A / %x61-7A / DIGIT / "-" / "_"
; A-Z / a-z / 0-9 / "-" / "_"
lower-char = %x61-7A ; a-z
DIGIT is the core rule of [RFC5234].
caid-version is the version of this identifier syntax and is "1" for
this document. action-type is one or more lowercase dotted name
segments followed by a final segment that is the integer version of
the type (for example, payment.release.1). suite is a name from the
suite registry, lowercase. digest is the digest encoded in base64url
(Section 5 of [RFC4648]), unpadded and case-sensitive; for the two
suites defined here the digest is exactly 43 characters, encoding 32
octets.
Schrock Expires 20 January 2027 [Page 6]
Internet-Draft CAID July 2026
3.4. Parsing
Parsers are strict. A conforming parser:
* MUST refuse base64url padding characters ("=") in the digest.
* MUST refuse uppercase characters in the action-type or suite
fields. The digest field is case-sensitive and both cases are
significant there.
* MUST refuse empty segments anywhere in the string, including empty
dotted segments within the action type.
* MUST refuse any content after the digest, including trailing
separators, whitespace, or additional fields.
* MUST refuse a digest that does not decode to exactly the digest
length of the named suite, or whose final character encodes
nonzero unused bits.
* MUST treat an unknown caid-version as a refusal, never as a value
to be guessed at or parsed leniently.
* MUST treat an unknown suite as a refusal, never as a suite to be
guessed.
3.5. Equality
Two CAIDs are equal if and only if their strings are byte-equal.
Cross-suite equivalence is out of scope: no procedure in this
document relates a jcs-sha256 CAID to a cbor-sha256 CAID for the same
object. An artifact MAY carry multiple CAIDs for one action, one per
suite its issuer computed.
Direct CAID equality is content equality, not inferred semantic
equality. The strings "1.50" and "1.5" are different content and
yield different digests. Per-field normalization guidance lives in
the type definition's digest_notes (Section 4.2), and normalization
is the issuer's job: the issuer normalizes before computing the CAID,
and no party renormalizes afterward.
When two native formats cannot produce byte-equal action objects, the
Action-Mapping Profile in Section 7 provides a narrower result:
equivalence of the material projection under exact profiles pinned by
a relying party. It does not claim general semantic equivalence.
4. Action Types and the Registry
Schrock Expires 20 January 2027 [Page 7]
Internet-Draft CAID July 2026
4.1. Type Names and Versioning
An action type name is one or more lowercase dotted name segments
with a final segment that is the integer version of the type, per the
action-type rule of Section 3.3. Registered types live in the CAID
action type registry (Section 10), one entry per versioned type.
Once a version is active, every declaration that affects validation
or material meaning is immutable. Adding or removing a required or
optional field, retyping a field, changing an enum set or
normalization rule, or changing a field's semantics MUST be published
as a new version of the type (payment.release.2), never as an in-
place edit. This immutability is required so a later verifier can
reproduce an earlier result.
4.2. The Type Definition Schema
The entry schema below is normative, and it is normative for local
definitions too: a private deployment carries its own definitions in
this same schema (Section 4.4).
{
"action_type": "payment.release.1",
"status": "active",
"risk_class": "irreversible-financial",
"summary": "Release of a payment instruction to settlement.",
"required_fields": [
{"name": "amount", "type": "amount-string",
"notes": "decimal string, no exponent, no leading '+',
no thousands separators"},
{"name": "currency", "type": "enum",
"values_ref": "ISO 4217 alpha-3"},
{"name": "beneficiary_account", "type": "digest",
"notes": "sha256:<lowercase hex> of the normalized account
identifier; normalization stated by the issuing
system of record"},
{"name": "payment_instruction_id", "type": "string"}
],
"optional_fields": [
{"name": "memo", "type": "string"}
],
"digest_notes": "amounts never renormalized after signing; the
system of record's form is canonical",
"references": []
}
Schrock Expires 20 January 2027 [Page 8]
Internet-Draft CAID July 2026
action_type is the versioned type name. status is the lifecycle state
of the entry. risk_class is a descriptive label for the consequence
class of the action; it carries no verification semantics.
required_fields declares the material fields, each with a name, a
field type from Section 4.3, and optional notes or a values_ref
naming an external value set. optional_fields declares fields the
type recognizes but does not require. digest_notes carries per-type
normalization guidance for issuers. references carries citations for
the type's semantics.
4.3. Field Types
The set of field types in version 1 is closed:
string: A JSON string.
amount-string: A decimal amount carried as a string: an optional
leading "-", one or more digits, and an optional "." with one or
more digits. No exponent, no leading "+", no thousands
separators.
digest: The literal prefix "sha256:" followed by 64 lowercase
hexadecimal characters. Used where a raw identifier must not
appear in the object (Section 9).
enum: A string constrained to a value set named by the field's
values_ref.
timestamp: An RFC 3339 [RFC3339] timestamp in UTC with the "Z"
designator.
integer: A JSON integer. For counts only, never for money.
boolean: A JSON boolean.
object: A JSON object, itself subject to the number restriction of
Section 2.
array: A JSON array, itself subject to the number restriction of
Section 2.
Schrock Expires 20 January 2027 [Page 9]
Internet-Draft CAID July 2026
4.4. Definition Sources and Unknown Types
There is no reserved private-use name syntax. The distinction
between registered and local types is presence: a type is either
present in a definition source the implementation is configured with
(the public registry, or a local definitions file in the same schema)
or it is unknown. A deployment inside a single vendor's boundary can
therefore use CAID with purely local definitions. Cross-domain use
requires the parties to pin the same exact definition or registry
snapshot. A local definition that collides by name with a different
registered definition MUST NOT be treated as interoperable.
An unknown type is a refusal for a conforming issuer (Section 5).
For a verifier, accepting an identifier whose type is unknown is a
policy decision: a verifier MAY offer an accept-unregistered option,
and that option MUST default to off.
5. Computation
A conforming issuer computes a CAID from an action object, a suite,
and its configured definition sources, in the following order. Each
check that fails contributes a refusal reason from the closed set
below; the reason strings are normative.
1. The action_type member is present and its value matches the
action-type grammar of Section 3.3, else invalid_action_type.
2. The type is resolvable in the configured definition sources, else
unknown_action_type.
3. Every REQUIRED field of the type definition is present, else
missing_material_field:<name> for each absent field.
4. Every present field that the type definition declares is valid
for its declared field type, else mistyped_field:<name> for each
violation. An amount-string violation MAY be refined to
invalid_amount:<name>.
5. The requested suite is known, else unknown_suite.
6. Every number in the object, at any depth, satisfies the value-
based rule of Section 2 (an integer with magnitude at most 2^53-1
after IEEE 754 double-precision parsing), else
unsupported_number.
7. Canonicalize under the suite, digest, and emit the CAID string
and the digest.
Schrock Expires 20 January 2027 [Page 10]
Internet-Draft CAID July 2026
On success the issuer emits the identifier and the digest. On any
failure the issuer emits the accumulated refusal reasons and NO
identifier. Computation is fail-closed: malformed or junk input, of
any shape, yields refusal reasons, never an exception or a partial
identifier.
6. Verification
A conforming verifier checks a presented CAID string against a
presented action object, using its own configured definition sources,
in the following order:
1. Strict-parse the CAID string per Section 3.4, else
malformed_caid.
2. The in-object action_type equals the action type carried in the
CAID string, else action_type_mismatch. This check is mandatory;
see Section 3.2 and Section 9.
3. Recompute the digest over the presented object under the suite
named in the CAID; the recomputed digest is equal to the
presented digest, else digest_mismatch.
4. Run the same material validation as computation (Section 5, steps
1 through 6). An identifier whose object fails that validation
is invalid_object, not merely mismatched: a digest that matches
an invalid object still binds nothing material.
The result is a validity bit and the list of reasons. Verification
is deterministic and offline: the same inputs produce the same
reasons in the same order, and any third party with the object, the
identifier, and the definitions can replay the check without
contacting anyone.
7. Action-Mapping Profile
Two native formats can represent the same material action with
different member names, nesting, or format-local metadata. Direct
digest comparison cannot establish whether those representations
denote the same material action. This section defines a narrow,
explicit projection into a common CAID action type. The projection
is identified by its digest and pinned by the relying party.
A mapping result is content correlation only. It does not establish
identity, authority, authorization, provenance, execution, or legal
reliance.
Schrock Expires 20 January 2027 [Page 11]
Internet-Draft CAID July 2026
7.1. Native Verification Boundary
Before mapping, each source artifact MUST be verified under its
native specification and the relying party's native trust anchors.
The source object supplied to the mapper MUST be the payload whose
integrity that native verification established, or a projection for
which the native adapter has established that every mapped source
field is covered by the native integrity mechanism. A mapper MUST
NOT read an unsigned sibling member and treat it as part of a signed
payload.
The source media type, schema identifier, and version supplied to the
mapper MUST come from relying-party configuration or the native
verifier. They MUST NOT be accepted solely from a label inside the
presenter-controlled artifact. CAID mapping does not replace native
verification.
The mapping interface MUST receive an affirmative native verification
result through a relying-party-controlled adapter or equivalent
trusted call path. That result is an API precondition, not a member
a presenter can place in the artifact. A missing or negative native-
verification result yields INDETERMINATE.
7.2. Mapping Profile Object
A version 1 profile is a JSON object with the following shape:
Schrock Expires 20 January 2027 [Page 12]
Internet-Draft CAID July 2026
{
"@version": "CAID-MAPPING-PROFILE-v1",
"profile_id": "urn:example:map:checkout-to-order:1",
"source_format": {
"media_type": "application/example-checkout+json",
"schema": "urn:example:checkout:1",
"version": "1"
},
"target_action_type": "order.place.1",
"loss_policy": "no-material-field-loss",
"material_source_paths": [
"/checkout/order_id",
"/checkout/merchant_id",
"/checkout/total_amount",
"/checkout/currency",
"/checkout/line_items",
"/checkout/customer_id",
"/checkout/fulfillment"
],
"rules": [
{"source_path": "/checkout/order_id",
"target_field": "order_id", "transform": "copy"},
{"source_path": "/checkout/merchant_id",
"target_field": "merchant_ref", "transform": "sha256-utf8"},
{"source_path": "/checkout/total_amount",
"target_field": "total_amount", "transform": "copy"},
{"source_path": "/checkout/currency",
"target_field": "currency", "transform": "copy"},
{"source_path": "/checkout/line_items",
"target_field": "items_digest", "transform": "sha256-jcs"},
{"source_path": "/checkout/customer_id",
"target_field": "customer_ref", "transform": "sha256-utf8"},
{"source_path": "/checkout/fulfillment",
"target_field": "fulfillment_ref", "transform": "sha256-jcs"}
]
}
The profile digest is the lowercase hexadecimal SHA-256 digest of the
profile's JCS serialization, prefixed with "sha256:". The relying
party MUST pin that exact digest. A profile identifier by itself is
not a trust anchor.
Version 1 is a closed object model. A mapper MUST reject an unknown
member in the top-level profile, source_format object, or rule
object. This prevents a misspelled or future policy member from
being covered by the profile digest while being silently ignored by
the mapping algorithm.
Schrock Expires 20 January 2027 [Page 13]
Internet-Draft CAID July 2026
source_format binds the exact media type, schema identifier, and
version accepted by the profile. target_action_type names a type from
a definition source pinned by the relying party. loss_policy MUST be
"no-material-field-loss" in version 1. source_path values are JSON
Pointers [RFC6901]. Every material_source_paths entry MUST have
exactly one rule, and every REQUIRED field of the target action type
MUST be the target of exactly one rule. Duplicate target fields,
malformed pointers, missing fields, and unknown transforms are
mapping failures.
The version 1 transform set is closed:
copy: Copy the source value after confirming that it has a
conforming JCS representation.
sha256-utf8: For a source string, emit "sha256:" followed by the
lowercase hexadecimal SHA-256 digest of its UTF-8 bytes.
sha256-jcs: Emit "sha256:" followed by the lowercase hexadecimal
SHA-256 digest of the source value's JCS representation.
A mapper MUST refuse an unregistered transform. Version 1 performs
no unit conversion, currency conversion, date inference, case
folding, or lossy normalization.
7.3. Mapping and Comparison Algorithm
For each source, a conforming mapper:
1. Requires an affirmative native-verification result from the
trusted adapter.
2. Validates the complete profile shape and closed transform set.
3. Recomputes the profile digest and compares it to the relying-
party pin.
4. Compares the verifier-derived source descriptor to the profile's
source_format object.
5. Confirms one-to-one coverage of material source paths and all
REQUIRED target fields.
6. Computes a source digest over the complete source object for
reproducibility.
7. Extracts and transforms every rule. A missing path or mistyped
value is a mapping failure.
Schrock Expires 20 January 2027 [Page 14]
Internet-Draft CAID July 2026
8. Computes a CAID for the projected action under Section 5.
Comparison of two mapping results returns exactly one of:
EQUIVALENT_UNDER_PROFILE: Both mappings succeeded, both target the
same action type, and the resulting CAID strings are byte-equal.
NOT_EQUIVALENT: Both mappings succeeded and target the same action
type, but the resulting CAIDs differ.
INDETERMINATE: Either native verification did not succeed, either
mapping failed, either profile was not pinned, a source descriptor
differed, a target action type differed, or any required fact was
absent or ambiguous.
A consumer MUST NOT convert INDETERMINATE into equivalence. It also
MUST NOT treat EQUIVALENT_UNDER_PROFILE as authorization.
Authorization remains a separate relying-party decision over
separately verified evidence.
For reproducibility, each successful per-source mapping result MUST
carry the complete source-object digest, mapping-profile digest,
projected action object, resulting CAID, and suite. A comparison
result MUST retain both per-source mapping results. A consumer that
persists or transmits only the final verdict or CAID loses the
information needed to reproduce which profiles and source objects
produced that result.
7.4. Completeness Assumption
The algorithm proves that a pinned profile maps every field the
target action type declares material. It cannot prove that the
profile author correctly identified every material concept in the
native source schema. The relying party's selection and review of
mapping profiles is therefore an explicit policy assumption.
Profiles SHOULD be versioned, publicly reviewable, and accompanied by
positive, negative, and indeterminate conformance vectors.
8. What a CAID Is Not
Under the selected suite's security assumptions, recomputing a CAID
establishes that an identifier commits to the supplied canonical
typed content. Comparing CAIDs emitted directly from the same action
type, or emitted through pinned Action-Mapping Profiles, provides the
scoped matching result defined here. It does not prove that the
action was authorized, executed, safe, or wise. It confers no trust,
names no humans, and replaces no verifier: every artifact that
carries a CAID still verifies inside its own trust boundary under its
Schrock Expires 20 January 2027 [Page 15]
Internet-Draft CAID July 2026
own specification, exactly as it did before carrying one.
In particular:
* A CAID is not authorization. Possession of an identifier, or of
the object it digests, authorizes nothing.
* A capability scope can name one or more CAIDs as exact content
constraints. The capability's signature, issuer trust, holder
proof, budget state, and local policy create that authorization
context; the CAIDs themselves still grant nothing.
* A capability grant, a narrowing delegation, and each capability
exercise are different material actions and can have separate
CAIDs. Equality or EQUIVALENT_UNDER_PROFILE does not establish
that an exercise falls within a grant. Scope containment,
attenuation, remaining budget, and permission to act are evaluated
by the capability protocol under relying-party-selected inputs.
* A CAID is not identity. It names content, not any human, agent,
workload, or organization.
* A CAID is not proof of execution or of outcome. An artifact
asserting execution proves that under its own specification, or
not at all.
* Composition joins on the identifier and never ingests another
verifier's evidence. When two artifacts about one action are
composed, the join key is the CAID; each leg's evidence is
verified by that leg's own verifier under that leg's own trust
anchors, and no verifier imports another's conclusions into its
own trust boundary.
9. Security Considerations
Digest strength. The binding between an identifier and its content
rests on the second-preimage resistance of SHA-256. If SHA-256
weakens, the migration path is suite agility: a new suite is
registered and issuers move to it, emitting new identifiers. There
is no in-place algorithm change within a suite, ever.
Schrock Expires 20 January 2027 [Page 16]
Internet-Draft CAID July 2026
No domain separation. The digest input carries no domain separation
prefix, deliberately, so that existing formats can adopt a digest
they may already compute over canonical bytes (Section 3.2). The
compensating control is mandatory: verifiers MUST enforce the check
that the in-object action_type equals the type carried in the CAID
string. Skipping that check re-opens cross-context reinterpretation,
in which bytes canonicalized for one context are presented under a
type label from another. The check is step 2 of Section 6 and is not
optional.
Personally identifiable information. Action objects, CAIDs, and
their correlations should be assumed to travel and to appear in logs.
A plain SHA-256 digest of a low-entropy identifier is pseudonymous,
not anonymous: an observer can test likely account, patient, or order
identifiers by dictionary attack. The digest field type keeps raw
values out of the action object but does not by itself provide
confidentiality or unlinkability. Type authors handling personal
data SHOULD prefer high-entropy opaque references or a deployment-
specific privacy-preserving commitment scheme, document its
normalization and correlation scope, and avoid placing unnecessary
personal data in the action object. A deployment-specific scheme can
require an explicit mapping profile for cross-domain joins.
Canonicalization malleability. Cross-language number serialization
is the historical source of canonicalization divergence, which is why
numbers are restricted to the value-based integer rule and money is
carried as amount-string (Section 2). JCS and CBOR core
deterministic encoding are the only permitted canonical forms; no
other serialization, however stable it appears, is a conforming
digest input.
A CAID is not a capability. Possession of an identifier proves
nothing and grants nothing. Identifiers SHOULD be treated as public
values: they may appear in logs, URLs, and audit records without
weakening anything. Protocols MUST NOT treat knowledge of a CAID as
evidence of anything beyond knowledge of the object's content.
Profile-bounded equivalence. Direct CAID verification does not infer
semantic equality. The Action-Mapping Profile makes only a narrower
statement about material projections under exact pinned profiles. A
malicious or incomplete profile can omit a concept that the relying
party should have considered material. Profile selection is
therefore a relying-party policy decision; unpinned, lossy, or
ambiguous mappings MUST yield INDETERMINATE.
Schrock Expires 20 January 2027 [Page 17]
Internet-Draft CAID July 2026
Native integrity coverage. A valid native signature does not make
unsigned members beside the signed payload trustworthy. A native
adapter MUST establish that every mapped field is covered by the
native integrity mechanism. The source descriptor is verifier-
derived, not presenter-asserted (Section 7.1).
Definition stability. A versioned action-type definition is
immutable once active. Cross-domain verifiers MUST pin an exact
definition source or registry snapshot. A local and a registered
definition that share a name but differ in validation semantics MUST
NOT be treated as the same type.
Duplicate object member names. A raw JSON parser feeding CAID
computation or mapping MUST reject duplicate member names before
constructing the data model. Accepting duplicate names can make the
native verifier and mapper select different values.
10. IANA Considerations
This document requests no immediate IANA actions.
Two registries are described: the CAID action type registry
(Section 4), whose entries follow the normative schema of
Section 4.2, and the CAID suite registry (Section 3.1), which for
this version contains jcs-sha256 and cbor-sha256. Both are published
as machine-readable JSON under a public-domain dedication and are
maintained by the author's organization pending adoption. Active
entries are immutable in every field that affects validation or
material meaning. The stated intent is to transition maintenance to
IANA or another neutral standards body if this specification is
adopted. A future revision would then specify registration policies
for both registries.
A URN namespace registration for CAID identifiers may be useful in
the future; it is out of scope for this revision.
11. References
11.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet:
Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002,
<https://www.rfc-editor.org/info/rfc3339>.
Schrock Expires 20 January 2027 [Page 18]
Internet-Draft CAID July 2026
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<https://www.rfc-editor.org/info/rfc4648>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>.
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms
(SHA and SHA-based HMAC and HKDF)", RFC 6234,
DOI 10.17487/RFC6234, May 2011,
<https://www.rfc-editor.org/info/rfc6234>.
[RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed.,
"JavaScript Object Notation (JSON) Pointer", RFC 6901,
DOI 10.17487/RFC6901, April 2013,
<https://www.rfc-editor.org/info/rfc6901>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON
Canonicalization Scheme (JCS)", RFC 8785,
DOI 10.17487/RFC8785, June 2020,
<https://www.rfc-editor.org/info/rfc8785>.
[RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object
Representation (CBOR)", STD 94, RFC 8949,
DOI 10.17487/RFC8949, December 2020,
<https://www.rfc-editor.org/info/rfc8949>.
11.2. Informative References
[I-D.lee-orprg-permit-receipts]
Lee, Y. B., "Permit Receipts for Permit-Before-Commit
Authorization of AI-Agent and Workload External Effects",
Work in Progress, Internet-Draft, draft-lee-orprg-permit-
receipts-00, 4 June 2026,
<https://datatracker.ietf.org/doc/html/draft-lee-orprg-
permit-receipts-00>.
Schrock Expires 20 January 2027 [Page 19]
Internet-Draft CAID July 2026
[I-D.morrow-sogomonian-exec-outcome-attest]
Morrow and A. Sogomonian, "Execution Outcome Attestation
for AI Agents and Automated Systems", Work in Progress,
Internet-Draft, draft-morrow-sogomonian-exec-outcome-
attest-00, 4 April 2026,
<https://datatracker.ietf.org/doc/html/draft-morrow-
sogomonian-exec-outcome-attest-00>.
[I-D.schrock-ep-authorization-receipts]
Schrock, I., "Authorization Receipts for High-Risk Agent
Actions", Work in Progress, Internet-Draft, draft-schrock-
ep-authorization-receipts-06, 6 July 2026,
<https://datatracker.ietf.org/doc/html/draft-schrock-ep-
authorization-receipts-06>.
Appendix A. Acknowledgments
The separation between cryptographic validity and authority in this
document was sharpened by review from Eric Rescorla. Linda Dunbar's
cross-administrative-domain Agent Gateway scenarios motivated the
requirement for a reproducible action join across operator
boundaries. Chris Hood's work on agent transport and composition
helped expose the need to keep action identity independent from any
one authorization artifact. These acknowledgments do not imply
endorsement of this document.
Author's Address
Iman Schrock
EMILIA Protocol, Inc.
United States of America
Email: team@emiliaprotocol.ai
Schrock Expires 20 January 2027 [Page 20]