diff --git a/adr/0019-multiple-identities-alsoknownas.md b/adr/0019-multiple-identities-alsoknownas.md new file mode 100644 index 0000000..0bcbfa7 --- /dev/null +++ b/adr/0019-multiple-identities-alsoknownas.md @@ -0,0 +1,78 @@ +# ADR 0019: Support Multiple Identities via `alsoKnownAs` in the Trust Manifest + +## Status +Proposed + +## Date +2026-07-24 (Proposed) + +**Participants:** Alexander Shenshin (DSR Corporation), Darrel Miller (Microsoft), Jeffrey Damick (Amazon), Junjie Bu (Google), Ramiz Polic (Cisco), Sam Betts (Cisco) + +## Context +A catalog entry can declare exactly one cryptographic identity through the `trustManifest.identity` field (with an optional `identityType` hint). Real artifacts frequently hold more than one verifiable identity at the same time, for example: + +- a SPIFFE ID (`spiffe://acme.com/ns/finance/sa/finance-a2a-pod`) for runtime/workload identity, and +- a DID (`did:web:acme-corp.com`) for organizational/publisher-anchored identity. + +There is no first-class place to list additional identities. Authors are forced to add them through `attestations[]` or `metadata`, where consumers do not reliably look for them and cannot treat them as verifiable subject identities ([issue #52](https://github.com/Agent-Card/ai-catalog/issues/52)). The workarounds are inadequate: + +- **Attestations are limiting.** An `Attestation` is a typed claim with evidence, designed for compliance documents. There is no standard attestation type meaning "this is another identity of the same subject", so alternate identities cannot be discovered or pinned programmatically. +- **Metadata is opaque.** Per the spec, consumers SHOULD ignore metadata keys they do not recognize, so a second identity placed there is invisible and non-interoperable. +- **Conflicts with the domain-alignment rule.** The rule binding the `identity` trust domain to the publisher domain of the entry's `identifier` is written for a single identity and gives no guidance for identities in other trust domains. + +Use cases requiring multiple identities include: co-equal runtime and publisher identities, relying parties that can only resolve a subset of identity schemes, and migration/rotation between identity schemes without breaking existing consumers. + +A key constraint shaped this decision: **declared identities MUST be verifiable through the trust bundle.** An identity claim a consumer cannot verify is worse than no claim at all. + +## Decision +The Trust Manifest gains an OPTIONAL `alsoKnownAs` member: an array of globally unique URIs, each asserting an alternative identity of the **same subject** as the canonical `identity` field. + +```json +"trustManifest": { + "identity": "spiffe://acme.com/ns/finance/sa/finance-agent-pod", + "identityType": "spiffe", + "alsoKnownAs": [ + "did:web:acme-corp.com:agent:finance" + ], + "signature": "eyJhbGciOiJFUzI1NiJ9..detached-jws-signature" +} +``` + +Normative rules: + +1. `identity` remains the single **canonical** subject identifier, used for referencing and equivalence checking. Aliases are co-equal for verification purposes but never canonical. +2. `alsoKnownAs` MUST NOT contain the value of `identity` and MUST NOT contain duplicates; element order carries no significance. +3. The domain-alignment rule applies only to `identity`. Aliases MAY belong to different trust domains or identity schemes. +4. Aliases are publisher claims verified through the existing Trust Manifest `signature`, which covers `alsoKnownAs` as manifest content — no per-alias proof mechanism is defined. Consumers MUST NOT rely on an alias from a manifest whose signature is absent or fails verification. Because the signature proves the publisher claims the alias (not that the alias's trust domain acknowledges the link), authorization decisions inside the alias's trust domain SHOULD additionally rely on proof of control native to the alias scheme (e.g., a DID Document back-reference or DNS TXT record); such proofs are out of scope. +5. A consumer MAY select any verified identity, canonical or alias, matching the schemes it can resolve, rather than rejecting an entry whose canonical identity uses an unsupported scheme. + +### Placement: inside the Trust Manifest, not on the Catalog Entry +We explicitly considered placing `alsoKnownAs` on the parent Catalog Entry (as a sibling of `identifier`) and rejected it: + +- **Signature coverage is decisive.** The Trust Manifest is the only signed unit in the specification, the detached JWS is computed over the JCS-canonicalized manifest content. Fields on the Catalog Entry are not covered by any signature, so under the spec's catalog-poisoning threat model an attacker who can modify the catalog document could inject or strip entry-level aliases undetected. Inside the manifest, aliases are forgery-proof at trust Layer 2, satisfying the "verifiable through the trust bundle" constraint. +- **Separation of concerns (ADR-0015).** The entry's `identifier` is a logical *name* (`urn:air:...`) for discovery and routing; cryptographic *identities* live in the Trust Manifest. Alternative identities are identities, so they belong beside `identity`, not beside the URN. +- **Ecosystem precedent.** W3C DID Core defines `alsoKnownAs` on the DID Document with the same publisher-asserted, same-subject semantics adopted here. +- **Reuse for hosts.** Host Info carries a `trustManifest` too, so hosts gain multi-identity support without adding a new field to two parent structures. + +The trade-off is that entries without a Trust Manifest cannot declare aliases. This is acceptable because an alias outside the trust bundle would be unverifiable by construction. + +## Rationale +- **Interoperability**: A standard, first-class shape means consumers can programmatically discover alternate identities instead of relying on per-publisher attestation or metadata conventions. +- **Simple equivalence checking**: Keeping a single canonical `identity` avoids forcing consumers to choose which of N identities "names" the entry. +- **Backward compatible**: `alsoKnownAs` is OPTIONAL and additive. Existing manifests remain valid; existing consumers that ignore the field lose nothing they had before. +- **Verifiability by construction**: Because the field lives inside the signed manifest content, no new signing mechanism is needed, the existing JCS + detached JWS procedure covers it. + +## Alternatives Considered +- **`identities[]`: an array of Identity objects** (each with `identity`, `identityType`, and optionally its own `signature`). Rejected: it makes equivalence checking harder, forces consumers to choose which identity to use when referencing the entry, and multiplies signature-verification paths. The variant dropping the primary `identity` entirely was also rejected as a breaking change to the existing spec. +- **`trustManifests[]`: multiple Trust Manifests per entry.** Fully independent trust metadata per identity (separate attestations, provenance, signatures). Rejected as disproportionate: the motivating use cases need equivalent identities for one subject, not parallel trust bundles, and multiple manifests reintroduce the "which manifest is authoritative?" problem at a larger scale. +- **`alsoKnownAs` on the Catalog Entry (parent structure).** Rejected for the placement reasons above, mainly that entry-level fields fall outside the signed trust bundle and therefore cannot satisfy the verifiability requirement. +- **Status quo (attestations/metadata workarounds).** Rejected as non-interoperable and non-verifiable, per the Context section. + +## Consequences +- **Specification**: The Trust Manifest optional members, verification procedures (new "Verifying Alternative Identities" section), CDDL schema, data model diagram, and examples are updated. +- **Consumers**: Clients that verify Trust Manifest signatures automatically gain tamper-proof alias coverage. Clients unaware of the field are unaffected. +- **Publishers**: Publishers currently smuggling secondary identities through `attestations[]` or `metadata` SHOULD migrate them to `alsoKnownAs`. +- **Future work**: If per-alias proofs become necessary (e.g., alias-side attestations or inline alias-specific signatures), a structured object form can be layered on without breaking the URI-array form. + +## Meeting Reference +Proposed from [issue #52](https://github.com/Agent-Card/ai-catalog/issues/52) discussion; `alsoKnownAs` was favored over an identities array in issue comments (2026-07). Update the Status and Date once the working group ratifies it. diff --git a/specification/ai-catalog.md b/specification/ai-catalog.md index 81f2bf3..bddc231 100644 --- a/specification/ai-catalog.md +++ b/specification/ai-catalog.md @@ -416,6 +416,15 @@ align with the publisher domain of the entry's `identifier`. When a Trust Manifest appears on a Host Info object, `identity` SHOULD match the host's `identifier` field when present. +An artifact may legitimately hold more than one verifiable identity at +the same time, for example a SPIFFE ID for runtime workload identity +and a DID for publisher-anchored organizational identity. Additional +identities are declared through the OPTIONAL `alsoKnownAs` member (see +[Optional Members](#optional-members)). The `identity` field remains the +single canonical subject identifier: consumers MUST use `identity` when +referencing the artifact's trust subject or checking identity +equivalence between entries. + When multiple entries share the same `identifier` (with different `version` values), each entry MAY carry its own Trust Manifest. There is no requirement that all versions carry identical trust metadata — trust @@ -426,9 +435,31 @@ properties may evolve across versions. The following members are OPTIONAL: `identityType` -: A string providing a type hint for the identity URI (e.g., "did", +: A string providing a type hint for the `identity` URI (e.g., "did", "spiffe", "dns"). This field is OPTIONAL when the type is evident - from the URI scheme. + from the URI scheme. It does not describe entries of `alsoKnownAs`. + +`alsoKnownAs` +: An array of strings, each containing a globally unique URI + [[RFC3986]] that identifies the same subject as `identity` under an + alternative identity scheme. The following rules apply: + + - An alias is an equivalent identity of the subject; `identity` + alone remains canonical and is used for referencing and + equivalence checking. + - The array is an unordered set: it MUST NOT contain duplicate + values or the value of the `identity` field. + - The domain-alignment rule defined in [Identity](#identity) + applies only to `identity`. Aliases MAY belong to different + trust domains or identity schemes. + - The `identityType` hint applies only to `identity`; the type of + an alias is inferred from its URI scheme (e.g., `did:`, + `spiffe:`). + - Aliases are publisher claims covered by the Trust Manifest + `signature`; no per-alias proof is required. Consumers MUST NOT + rely on an alias from a manifest whose signature is absent or + fails verification (see + [Verifying Alternative Identities](#verifying-alternative-identities)). `trustSchema` : A Trust Schema object as defined in [Trust Schema](#trust-schema-object). @@ -466,6 +497,9 @@ provenance: { "identity": "did:web:acme.com:agent:finance", "identityType": "did", + "alsoKnownAs": [ + "spiffe://acme.com/ns/finance/sa/finance-agent-pod" + ], "trustSchema": { "identifier": "urn:trust:acme-enterprise-v1", "version": "1.0", @@ -683,6 +717,27 @@ To verify the publisher of an artifact: 4. Confirm the JWT claims bind the `publisher.identifier` to the Trust Manifest's `identity`. +### Verifying Alternative Identities + +Aliases need no verification procedure of their own. Because the +signed payload covers `alsoKnownAs`, verifying the Trust Manifest +`signature` as described in +[Trust Manifest Signatures](#trust-manifest-signatures) also verifies +every listed alias: a valid signature proves that the publisher +controlling the canonical `identity` claims each alias as an +equivalent identity of the subject. Consumers MUST NOT rely on aliases +from a manifest whose signature is absent or fails verification. + +Once the signature is verified, a consumer MAY use whichever identity, +canonical or alias, matches the identity schemes it is able to +resolve — for example, using a DID alias for DID-based discovery when +its tooling cannot resolve a canonical SPIFFE ID. + +Note that the signature proves the publisher claims the alias, not +that the alias's own trust domain acknowledges the link. Consumers +making authorization decisions inside the alias's trust domain MAY +additionally obtain proof of control native to the alias scheme. + ### Verifying Artifact Integrity When a Trust Manifest includes `provenance` entries with `sourceDigest`: @@ -1140,6 +1195,7 @@ classDiagram } class TrustManifest { identity string + alsoKnownAs string[] trustSchema TrustSchema attestations Attestation[] provenance ProvenanceLink[] @@ -1305,6 +1361,7 @@ Publisher = { TrustManifest = { identity: text, ? identityType: text, + ? alsoKnownAs: [* text], ? trustSchema: TrustSchema, ? attestations: [* Attestation], ? provenance: [* ProvenanceLink], diff --git a/specification/respec-config.json b/specification/respec-config.json index eed8157..27f66bd 100644 --- a/specification/respec-config.json +++ b/specification/respec-config.json @@ -3,8 +3,22 @@ "shortName": "ai-catalog", "edDraftURI": "https://ai-catalog.io/", "abstract": "This document defines the AI Catalog, a JSON format for discovering heterogeneous AI artifacts such as MCP servers, A2A agents, Claude Code plugins, datasets, and model cards. Each catalog entry declares the artifact's type via a media type and references or inlines the native artifact metadata, enabling a single discovery mechanism across protocols and platforms. The specification defines three conformance levels — Minimal, Discoverable, and Trusted — allowing implementations to start with a simple list of entries and progressively add host identity, well-known URI discovery, and verifiable trust metadata as needed. An optional Trust Manifest extension provides identity binding, compliance attestations, provenance tracking, and cryptographic signatures without wrapping or modifying the artifact's native format. Informative appendices describe mappings to OCI distribution registries, MCP Server Cards, and the Claude Code Plugins marketplace.", - "appendixHeaders": ["Data Model", "CDDL", "Example", "Mapping", "Acknowledgment", "Appendix", "IANA"], + "appendixHeaders": [ + "Data Model", + "CDDL", + "Example", + "Mapping", + "Acknowledgment", + "Appendix", + "IANA" + ], "localBiblio": { + "RFC3986": { + "title": "Uniform Resource Identifier (URI): Generic Syntax", + "href": "https://www.rfc-editor.org/rfc/rfc3986", + "status": "RFC", + "publisher": "IETF" + }, "RFC8785": { "title": "JSON Canonicalization Scheme (JCS)", "href": "https://www.rfc-editor.org/rfc/rfc8785",