Identity Propagation Context for Multi-Hop Delegation in OAuth 2.0 Environments
draft-sharma-oauth-identity-propagation-context-01
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 | Ravi Kant Sharma | ||
| Last updated | 2026-07-23 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| 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-sharma-oauth-identity-propagation-context-01
Individual Submission R.K. Sharma
Internet-Draft Ericsson
Intended status: Experimental 23 July 2026
Expires: 24 January 2027
Identity Propagation Context for Multi-Hop Delegation in OAuth 2.0
Environments
draft-sharma-oauth-identity-propagation-context-01
Abstract
This specification defines the Identity Propagation Context (IPC), a
signed, short-lived context artifact that carries identity and
delegation chain information across multi-hop service chains with
per-hop cryptographic re-signing. IPC complements the delegation
semantics of OAuth 2.0 Token Exchange (RFC 8693) by enabling each
trust boundary to independently verify the upstream signature and re-
sign the identity context it forwards, supporting cascade revocation,
delegation depth limits, and cross-protocol propagation (HTTP, gRPC,
and event-streaming systems).
Unlike the act claim in RFC 8693, which is explicitly designated as
"informational only and not to be considered in access control
decisions," IPC is designed for identity propagation that can be used
in access control decisions, with per-hop cryptographic re-signing
within a single trust domain. In autonomous agent architectures and
multi-service platforms, Each trust boundary verifies the upstream
signature and re-signs with its own key before forwarding; the
delegation chain content is asserted by the IPC Creator and trusted
transitively through the chain of re-signing intermediaries. This
provides single-hop-verifiable integrity (each service can verify its
immediate upstream) rather than end-to-end cryptographic proof of the
full chain.
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/.
Sharma Expires 24 January 2027 [Page 1]
Internet-Draft Identity Propagation Context July 2026
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 24 January 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
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 . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Problem Statement . . . . . . . . . . . . . . . . . . . . 4
1.2. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3. Relationship to RFC 8693 . . . . . . . . . . . . . . . . 6
1.4. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6
1.5. Requirements Language . . . . . . . . . . . . . . . . . . 6
1.6. Scope of Applicability . . . . . . . . . . . . . . . . . 6
1.7. Coexistence with OAuth 2.0 Bearer Tokens . . . . . . . . 7
1.8. Multi-Vendor Platform Interoperability . . . . . . . . . 7
2. IPC Format . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1. Claims . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2. Validation Rules . . . . . . . . . . . . . . . . . . . . 11
2.3. Example . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4. Encoding . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5. Signature Computation . . . . . . . . . . . . . . . . . . 15
2.6. Algorithm Restrictions . . . . . . . . . . . . . . . . . 17
2.7. FIPS-Compatible Algorithm Profile . . . . . . . . . . . . 17
2.8. Design Rationale: Why Not JWS? . . . . . . . . . . . . . 18
3. Trust Boundaries and Re-signing . . . . . . . . . . . . . . . 19
3.1. Concept . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2. Verification Algorithm . . . . . . . . . . . . . . . . . 20
3.3. Re-signing Algorithm . . . . . . . . . . . . . . . . . . 27
3.4. Immutability . . . . . . . . . . . . . . . . . . . . . . 28
3.5. Key Management . . . . . . . . . . . . . . . . . . . . . 29
3.6. Key Discovery Endpoint . . . . . . . . . . . . . . . . . 29
Sharma Expires 24 January 2027 [Page 2]
Internet-Draft Identity Propagation Context July 2026
3.7. Error Response Format . . . . . . . . . . . . . . . . . . 31
3.8. Verification Failure . . . . . . . . . . . . . . . . . . 32
3.9. Absent IPC . . . . . . . . . . . . . . . . . . . . . . . 33
4. Delegation Issuance . . . . . . . . . . . . . . . . . . . . . 33
4.1. IPC Creation . . . . . . . . . . . . . . . . . . . . . . 33
4.2. Delegation Token . . . . . . . . . . . . . . . . . . . . 33
4.3. IPC Creation Algorithm . . . . . . . . . . . . . . . . . 33
5. Enforcement Rules . . . . . . . . . . . . . . . . . . . . . . 35
5.1. Maximum Delegation Depth . . . . . . . . . . . . . . . . 35
5.2. Chain Verification . . . . . . . . . . . . . . . . . . . 35
5.3. Expiry Attenuation . . . . . . . . . . . . . . . . . . . 36
5.4. Circular Detection . . . . . . . . . . . . . . . . . . . 36
5.5. Cascade Revocation . . . . . . . . . . . . . . . . . . . 37
5.5.1. Revocation Event Format . . . . . . . . . . . . . . . 37
5.5.2. Propagation Guarantees . . . . . . . . . . . . . . . 39
5.5.3. Partition Tolerance . . . . . . . . . . . . . . . . . 40
5.5.4. Revocation Checking Interface . . . . . . . . . . . . 40
5.6. Configuration Parameters . . . . . . . . . . . . . . . . 40
6. Protocol Bindings . . . . . . . . . . . . . . . . . . . . . . 44
6.1. HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . 44
6.2. gRPC . . . . . . . . . . . . . . . . . . . . . . . . . . 44
6.3. Event-Streaming (Kafka) . . . . . . . . . . . . . . . . . 44
6.4. Protocol Transition Behavior . . . . . . . . . . . . . . 45
6.5. Header Value ABNF . . . . . . . . . . . . . . . . . . . . 45
6.6. Event-Streaming Retention Considerations . . . . . . . . 46
7. Trust Levels . . . . . . . . . . . . . . . . . . . . . . . . 46
8. Security Considerations . . . . . . . . . . . . . . . . . . . 47
8.1. Replay Protection . . . . . . . . . . . . . . . . . . . . 47
8.2. Key Compromise . . . . . . . . . . . . . . . . . . . . . 48
8.3. Spoofing . . . . . . . . . . . . . . . . . . . . . . . . 48
8.4. Chain Forgery . . . . . . . . . . . . . . . . . . . . . . 48
8.5. Single-Signer Verification Model . . . . . . . . . . . . 48
8.6. Size Considerations . . . . . . . . . . . . . . . . . . . 49
8.7. Threat Model . . . . . . . . . . . . . . . . . . . . . . 50
8.8. Key Rotation Procedure . . . . . . . . . . . . . . . . . 55
8.9. Clock Synchronization . . . . . . . . . . . . . . . . . . 55
8.10. Downgrade Attack Prevention . . . . . . . . . . . . . . . 56
8.11. Denial of Service Considerations . . . . . . . . . . . . 57
8.12. Proof-of-Possession . . . . . . . . . . . . . . . . . . . 57
8.13. Bearer Token and IPC Binding . . . . . . . . . . . . . . 58
9. Privacy Considerations . . . . . . . . . . . . . . . . . . . 59
9.1. Transport Protection . . . . . . . . . . . . . . . . . . 59
9.2. Delegation Chain as Sensitive Metadata . . . . . . . . . 59
9.3. Logging and Retention . . . . . . . . . . . . . . . . . . 59
9.4. Data Minimization . . . . . . . . . . . . . . . . . . . . 60
9.5. Correlation Risks . . . . . . . . . . . . . . . . . . . . 60
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 60
10.1. Header Registration . . . . . . . . . . . . . . . . . . 60
Sharma Expires 24 January 2027 [Page 3]
Internet-Draft Identity Propagation Context July 2026
10.2. Claims Registration . . . . . . . . . . . . . . . . . . 61
10.3. Well-Known URI Registration . . . . . . . . . . . . . . 62
10.4. IPC Entity Type Registry . . . . . . . . . . . . . . . . 62
11. Relationship to Other Specifications . . . . . . . . . . . . 63
11.1. Detailed Comparison with AIP . . . . . . . . . . . . . . 65
11.2. Mapping to Authorization Propagation Requirements . . . 66
11.3. Conformance Classes . . . . . . . . . . . . . . . . . . 68
Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 68
Appendix B. References . . . . . . . . . . . . . . . . . . . . . 68
B.1. Normative References . . . . . . . . . . . . . . . . . . 68
B.2. Informative References . . . . . . . . . . . . . . . . . 69
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 70
1. Introduction
1.1. Problem Statement
Modern cloud-native platforms serve multiple classes of autonomous
entities - AI agents, applications, and sub-agents - that initiate
operations traversing complex service chains. A fundamental problem
remains unsolved by existing standards:
How do you propagate the identity of an entity - including its full
delegation chain back to an accountable human - from the initiating
service to the final enforcement point, across multiple trust
boundaries and protocols, in a manner that is per-hop verified,
enforceable, revocable, and depth-limited?
The authentication layer is largely solved: platforms can assign
cryptographic identities to agents (e.g., SPIFFE-based identities
with mTLS and DPoP credential binding) and establish single-hop
delegation (e.g., OAuth 2.0 Token Exchange). What remains unsolved
is carrying the full delegation context - who is the original human,
who authorized this agent, what is the complete chain of delegation -
through multi-hop internal service calls where each intermediate
service independently verifies the context before forwarding it.
This problem has been independently formalized as "authorization
propagation" in the academic literature [Tallam2026].
Existing mechanisms fall short:
* *OAuth 2.0 Bearer Tokens (RFC 6750):* Validated at the first hop
only, not propagated with delegation context.
* *OAuth 2.0 Token Exchange (RFC 8693):* Supports nested act claims
but explicitly limits them to "informational only" for access
control decisions. Requires STS interaction to extend the
delegation chain at each new delegation hop (e.g., when an
Sharma Expires 24 January 2027 [Page 4]
Internet-Draft Identity Propagation Context July 2026
intermediate agent sub-delegates). The resulting token with
nested act claims can be forwarded downstream, but intermediate
services cannot independently attest their verification without
producing a new token via the STS.
* *Agent Identity Protocol (AIP) [I-D.draft-singla-agent-identity-
protocol]:* Defines decentralized agent identity with delegation
chains, but requires the agent to self-issue Credential Tokens.
Does not address platform-transparent propagation through service
infrastructure where the agent is unaware of downstream services.
HTTP-only; no gRPC or event-streaming bindings.
* *WIMSE AI Agent Identity [I-D.draft-ni-wimse-ai-agent-identity]:*
Defines agent identity bootstrapping and attestation via a proxy
architecture, but does not specify how verified identity
propagates through multi-hop service chains after initial
credential issuance.
* *OTEL Baggage (W3C):* Unsigned observability context - not
suitable for enforcement.
* *Transaction Tokens [I-D.draft-ietf-oauth-transaction-tokens]:*
Carry immutable authorization context (user identity, scope,
transaction details) through a call chain within a Trust Domain.
However, Txn-Tokens are passed unchanged through the chain — they
do not support per-hop re-signing, do not carry a mutable
delegation chain that grows with sub-delegation, and do not
provide per-hop verification that each intermediate validated the
context. IPC and Txn-Tokens are complementary: Txn-Tokens for
authorization context, IPC for delegation chain provenance.
* *mTLS / SPIFFE:* Identifies the transport endpoint, not the
originating entity or its delegation chain. Production platforms
(e.g., Google Cloud Agent Identity) assign per-agent SPIFFE
identities and use mTLS + DPoP for credential binding, yet still
lack a mechanism to propagate the full delegation chain (human →
agent → sub-agent) through multi-hop internal service calls.
SPIFFE proves "this workload is Service-A"; it does not prove
"this request originated from operator@example.com who delegated
to energy-optimizer who delegated to cell-configurator."
* *AI Agent Authentication Frameworks [I-D.draft-klrc-aiagent-
auth]:* Composes SPIFFE, WIMSE, OAuth, and OIDC into a unified
agent authentication architecture, but focuses on credential
issuance and initial authentication rather than per-hop identity
propagation through service chains after the agent authenticates.
1.2. Goals
This specification defines:
1. A context format (IPC) that carries delegation chain information
with per-hop cryptographic re-signing.
2. Re-signing semantics at trust boundaries.
Sharma Expires 24 January 2027 [Page 5]
Internet-Draft Identity Propagation Context July 2026
3. Delegation depth enforcement rules.
4. Expiry attenuation (child <= parent).
5. Cascade revocation semantics.
6. Protocol bindings for HTTP, gRPC, and event-streaming (e.g.,
Kafka).
7. A trust model for IPC issuance, verification, and re-signing.
1.3. Relationship to RFC 8693
IPC is complementary to RFC 8693. Token Exchange may be used at the
first hop to establish the initial delegation relationship. IPC then
carries the verified identity context through the remaining multi-hop
chain without requiring further STS interaction.
1.4. Terminology
* *IPC:* Identity Propagation Context - a signed context artifact
carrying delegation chain information.
* *Issuer:* The service that creates or re-signs an IPC at a trust
boundary.
* *Entity:* Any principal (human, agent, application, or system)
that initiates or participates in a delegation chain.
* *Delegation Chain:* The ordered sequence of entities from the
accountable root (typically human) to the current executing
entity.
* *Trust Boundary:* A point in the service chain where IPC is
verified and re-signed by a new issuer.
* *Enforcement Point:* A service that reads the IPC and makes
authorization decisions based on its contents.
* *STS:* Security Token Service - a trusted service that issues
delegation tokens establishing delegation relationships between
entities. The STS authenticates the delegating party and produces
a delegation-token that the IPC Creator consumes during IPC
construction (Section 4.2).
1.5. Requirements Language
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.
1.6. Scope of Applicability
IPC is designed for identity propagation in multi-hop service chains
within a single trust domain or platform. It is NOT suitable for:
Sharma Expires 24 January 2027 [Page 6]
Internet-Draft Identity Propagation Context July 2026
* Cross-organization federation (use RFC 8693 + trust frameworks)
* User-to-application consent flows (use OAuth 2.0 authorization
code flow)
* General-purpose session management (use session cookies or OAuth
refresh tokens)
* Replacing OAuth 2.0 bearer tokens for authentication (IPC travels
alongside, not replacing, the bearer token)
* Dynamic topologies where the terminal enforcement point is unknown
at IPC creation time (the IPC Creator must know the target
audience)
1.7. Coexistence with OAuth 2.0 Bearer Tokens
IPC is carried alongside the standard OAuth 2.0 bearer token in
requests. The bearer token handles authentication (proving the
caller has valid credentials). IPC handles identity propagation
(carrying the full delegation chain for enforcement decisions). Both
MAY be present in the same request.
1.8. Multi-Vendor Platform Interoperability
A standardized IPC format and verification algorithm enables platform
operators to compose service chains from components provided by
multiple vendors without requiring proprietary identity propagation
mechanisms. Any service that implements this specification can
participate in an IPC chain regardless of its vendor origin, provided
it operates within the platform's trust domain and has access to the
upstream issuer's public key.
This is distinct from cross-organization federation: the platform
operator controls the trust domain, manages key distribution, and
defines enforcement policy. The standardization benefit is that
vendors do not need bilateral integration for identity propagation -
they implement one specification.
Implementations claiming multi-vendor interoperability conformance
MUST support key discovery via Section 3.6. IPC Creators and Trust
Boundaries MUST support key discovery as both key consumers (querying
upstream endpoints) and key publishers (exposing own keys) per the
conformance requirements in Section 11.3. Enforcement Points that
only verify (and never re-sign) MUST support key discovery as key
consumers. Static key configuration alone is insufficient for multi-
vendor claims.
2. IPC Format
Sharma Expires 24 January 2027 [Page 7]
Internet-Draft Identity Propagation Context July 2026
2.1. Claims
IPC intentionally carries *identity and delegation context*, not
authorization grants or permissions. Authorization decisions are
made by policy engines (e.g., OpenFGA, OPA, Cedar) that consume IPC
identity as input. This separation ensures that IPC remains a
general-purpose propagation mechanism independent of any particular
authorization model.
IPC uses distinct claim names (entityId, issuer) rather than JWT
registered names (sub, iss) to avoid semantic confusion when IPCs
coexist with JWTs in the same request context, and because IPC's
issuer semantics differ from JWT's iss - in IPC, the issuer changes
at every re-signing hop.
The IPC is a signed JSON object with the following claims:
+=================+=========+==========+============================+
| Claim | Type | Required | Description |
+=================+=========+==========+============================+
| version | string | REQUIRED | IPC specification version |
| | | | (e.g., "1.0") |
+-----------------+---------+----------+----------------------------+
| entityId | string | REQUIRED | Identifier of the entity |
| | | | currently executing |
+-----------------+---------+----------+----------------------------+
| entityType | string | REQUIRED | AUTONOMOUS, SUPERVISED, |
| | | | UTILITY, HUMAN, or SYSTEM |
+-----------------+---------+----------+----------------------------+
| authorizedBy | string | REQUIRED | Identifier of the |
| | | | immediate delegating |
| | | | party |
+-----------------+---------+----------+----------------------------+
| delegationDepth | integer | REQUIRED | Number of delegation hops |
| | | | from root. MUST equal |
| | | | delegationChain.length - |
| | | | 1 |
+-----------------+---------+----------+----------------------------+
| delegationChain | array | REQUIRED | Ordered list of entity |
| | | | identifiers from root to |
| | | | current |
+-----------------+---------+----------+----------------------------+
| audience | string | REQUIRED | Intended *terminal* |
| | | (Level | enforcement point service |
| | | 2+), | identifier. Verified |
| | | OPTIONAL | only by the final service |
| | | (Level | in the chain (not |
| | | 1) | intermediate trust |
Sharma Expires 24 January 2027 [Page 8]
Internet-Draft Identity Propagation Context July 2026
| | | | boundaries). Prevents |
| | | | cross-service replay |
| | | | attacks. |
+-----------------+---------+----------+----------------------------+
| sessionId | string | REQUIRED | Unique identifier for |
| | | | this IPC instance (UUID |
| | | | v7 per RFC 9562 |
| | | | RECOMMENDED). |
| | | | Deployments MAY correlate |
| | | | sessionId with W3C Trace |
| | | | Context through a |
| | | | deployment-internal |
| | | | mapping. Using the same |
| | | | value for both sessionId |
| | | | and externally-visible |
| | | | trace-id is NOT |
| | | | RECOMMENDED when trace |
| | | | context propagates beyond |
| | | | the trust domain |
| | | | boundary, as it enables |
| | | | correlation of identity |
| | | | chains via observability |
| | | | infrastructure. |
+-----------------+---------+----------+----------------------------+
| issuedAt | string | REQUIRED | ISO 8601 timestamp (MUST |
| | | | be UTC, trailing "Z", no |
| | | | fractional seconds). |
| | | | Format: e.g., |
| | | | 2026-07-17T08:00:00Z |
| | | | (exactly 20 characters) |
+-----------------+---------+----------+----------------------------+
| expiresAt | string | REQUIRED | ISO 8601 timestamp (MUST |
| | | | be UTC, trailing "Z", no |
| | | | fractional seconds). |
| | | | Format: e.g., |
| | | | 2026-07-17T08:00:00Z |
| | | | (exactly 20 characters) |
+-----------------+---------+----------+----------------------------+
| issuer | string | REQUIRED | Identifier of the service |
| | | | that signed this IPC |
+-----------------+---------+----------+----------------------------+
| trustLevel | integer | REQUIRED | 1 (unsigned), 2 (signed), |
| | | | or 3 (reserved for future |
| | | | use) |
+-----------------+---------+----------+----------------------------+
| alg | string | REQUIRED | Signing algorithm |
| | | | identifier from the IANA |
| | | | JOSE Algorithms registry: |
Sharma Expires 24 January 2027 [Page 9]
Internet-Draft Identity Propagation Context July 2026
| | | | "EdDSA" (default for |
| | | | multi-hop chains; MUST |
| | | | use curve Ed25519 per RFC |
| | | | 8037), "ES256" (FIPS- |
| | | | compatible alternative |
| | | | for multi-hop chains; |
| | | | ECDSA with P-256 per RFC |
| | | | 7518 Section 3.4; see |
| | | | Section 2.6.1), "HS256" |
| | | | (single-hop only; MUST |
| | | | NOT be used when the IPC |
| | | | will cross more than one |
| | | | trust boundary), or |
| | | | "none" (Trust Level 1 |
| | | | only). Deployments MUST |
| | | | choose either EdDSA or |
| | | | ES256 for their |
| | | | asymmetric algorithm; |
| | | | mixing within a chain is |
| | | | prohibited. |
+-----------------+---------+----------+----------------------------+
| kid | string | REQUIRED | Key identifier of the |
| | | (Level | signing key. Enables key |
| | | 2+) | selection during |
| | | | rotation. The kid format |
| | | | is deployment-specific. |
| | | | The RECOMMENDED format is |
| | | | <issuer>/<key-version> |
| | | | (e.g., api-gateway/key- |
| | | | 1). |
+-----------------+---------+----------+----------------------------+
| signature | string | REQUIRED | Cryptographic signature |
| | | (Level | over all other claims |
| | | 2+) | |
+-----------------+---------+----------+----------------------------+
Table 1
The entityType values are defined as follows:
Sharma Expires 24 January 2027 [Page 10]
Internet-Draft Identity Propagation Context July 2026
+============+================================+
| Type | Definition |
+============+================================+
| HUMAN | A natural person authenticated |
| | via an identity provider |
+------------+--------------------------------+
| SYSTEM | Platform-initiated operation |
| | with no direct human trigger |
+------------+--------------------------------+
| AUTONOMOUS | Agent operating independently |
| | on behalf of a human principal |
+------------+--------------------------------+
| SUPERVISED | Agent requiring human approval |
| | for sensitive operations |
+------------+--------------------------------+
| UTILITY | Stateless service component |
| | invoked by other entities |
+------------+--------------------------------+
Table 2
The entityType is assigned at IPC creation time based on the
authenticated entity's registration in the platform. It MUST NOT
change during re-signing.
The entityType values are case-sensitive. Verifiers MUST perform
exact string matching against the defined values (AUTONOMOUS,
SUPERVISED, UTILITY, HUMAN, SYSTEM).
IPC uses ISO 8601 UTC strings rather than numeric epoch seconds (as
used in JWT) for timestamps. This enables human-readable inspection
of IPC tokens in logs, debugging tools, and wire captures without
requiring numeric-to-date conversion.
Timestamps MUST NOT include fractional seconds. The canonical format
is exactly YYYY-MM-DDTHH:MM:SSZ (20 characters). This ensures JCS
canonicalization produces identical bytes regardless of
implementation, preventing signature verification failures during re-
signing.
Implementations SHOULD parse ISO 8601 timestamps to integer epoch
representation once upon receipt and perform all subsequent
comparisons as integer arithmetic. This avoids repeated string
parsing at each verification step.
2.2. Validation Rules
Sharma Expires 24 January 2027 [Page 11]
Internet-Draft Identity Propagation Context July 2026
* delegationDepth MUST equal delegationChain.length - 1. If
mismatched, the IPC MUST be rejected.
Rationale for carrying both: delegationDepth enables fast policy
rejection (single integer comparison against maxDepth) without
requiring the verifier to parse and compute the length of the
delegationChain array. The redundancy also serves as an integrity
check - a mismatch indicates tampering or corruption. - authorizedBy
MUST equal delegationChain[delegationChain.length - 2] when the chain
has two or more entries. When delegationChain has exactly one entry
(no delegation), authorizedBy MUST equal entityId. If mismatched,
the IPC MUST be rejected.
Rationale for carrying authorizedBy separately: it enables fast
authorization policy lookups ("who authorized this entity?") without
requiring the verifier to parse and index the delegationChain array.
The redundancy also serves as an integrity check.
The delegationChain carries identifiers only, not entity types.
Enforcement points that require type information for intermediate
chain entries MUST resolve types through deployment-specific policy
or a principal registry.
* If audience is present, it identifies the *final enforcement
point* in the chain, not each intermediate hop. Trust boundary
services that re-sign and forward the IPC MUST NOT verify audience
against their own service identifier - they are intermediaries,
not the intended audience. Only the terminal enforcement point
(the service that makes the final authorization decision and does
not re-sign) MUST verify that its own service identifier matches
the audience value. If it does not match, the IPC MUST be
rejected.
For Trust Level 2+ IPCs, audience MUST be a non-empty string
identifying the terminal enforcement point. An empty string value
for audience in a Trust Level 2+ IPC MUST be rejected at creation
time. The verification algorithm's empty-audience check (Section 3.2
Step 9f) rejects empty audience for Trust Level 2+, while Step 12
verifies audience matching only at terminal enforcement points. In
fan-out topologies where an intermediate service forwards to multiple
terminal services, separate IPCs MUST be created for each terminal
path (each with its own audience value). Fan-out IPC creation MUST
NOT be performed on incoming HS256-signed IPCs. If the incoming IPC
has alg of "HS256", the service MUST act as a terminal enforcement
point only and MUST NOT create fan-out IPCs. HS256-signed IPCs
cannot be re-signed or forwarded (Section 3.3) — they are terminal by
definition. The preserved alg will therefore always be "EdDSA" in
fan-out scenarios. In this scenario, the intermediate service acts
Sharma Expires 24 January 2027 [Page 12]
Internet-Draft Identity Propagation Context July 2026
as both a Trust Boundary (verifying the incoming IPC) and an IPC
Creator (issuing new IPCs for each downstream path). The new IPCs
MUST preserve the original delegationChain, entityId, entityType,
authorizedBy, delegationDepth, version, alg, and trustLevel from the
verified incoming IPC. Extension claims (Section 2.2) present in the
incoming IPC MUST also be preserved in fan-out IPCs. Fan-out
creation is semantically equivalent to re-signing with respect to
claim preservation: only issuedAt, expiresAt, audience, sessionId,
issuer, kid, and signature differ in each fan-out IPC. The issuedAt
of each fan-out IPC MUST be set to the current time (the time of fan-
out creation), NOT preserved from the incoming IPC. The expiresAt
MUST be set to min(now() + config.maxTTL, original.expiresAt) to
maintain expiry attenuation (the fan-out IPC cannot outlive the
original). The audience, sessionId, issuer, kid, and signature
differ in each fan-out IPC. Each fan-out IPC MUST have a unique
sessionId to avoid replay cache conflicts at shared downstream
infrastructure.
Note on replay cache interaction: If the fan-out service is also an
enforcement point (dual-role per Section 11.3), it adds the original
incoming IPC's sessionId to its own replay cache upon verification.
Each fan-out IPC carries a new, independent sessionId that is
consumed by downstream enforcement points' replay caches. The
original IPC's replay detection and each downstream path's replay
detection operate independently.
Fan-out security constraints: - The fan-out service MUST be
configured with an explicit allowlist of downstream audience values
for which it may create IPCs. Fan-out IPC creation for audience
values not in the allowlist MUST be rejected. - The fan-out service
MUST enforce a maximum fan-out count per incoming IPC (RECOMMENDED
default: 10). If the number of downstream paths exceeds this limit,
the service MUST reject the fan-out request. - Fan-out IPC creation
MUST NOT be performed when the incoming IPC was accepted in
historical replay mode (Section 6.6) where temporal validity checks
were skipped. Creating fresh IPCs from expired historical records
would circumvent expiry attenuation.
Rationale for regenerating issuedAt: If the original issuedAt were
preserved, the maxTokenAge check (Step 8f) would measure age from the
original creation time. In fan-out topologies with processing
delays, this could cause fan-out IPCs to fail maxTokenAge checks at
downstream services despite being freshly created. Regenerating
issuedAt gives each fan-out IPC a fresh lifetime budget while
expiresAt attenuation ensures it cannot outlive the original
authority.
Sharma Expires 24 January 2027 [Page 13]
Internet-Draft Identity Propagation Context July 2026
A single IPC cannot target multiple terminal enforcement points. -
The first entry in delegationChain MUST be a human or system
principal (determined by deployment policy). - A verifier that
receives an IPC with a major version it does not implement MUST
reject it. Within the same major version (e.g., "1.x"), a verifier
implementing version "1.0" MUST accept tokens with version "1.0" or
any later minor version (e.g., "1.1", "1.2"), ignoring unrecognized
claims per the extension mechanism above. This enables rolling
upgrades without fleet-wide flag-day deployments.
Minor version increments (e.g., "1.0" to "1.1") MUST only add
OPTIONAL claims. A minor version MUST NOT promote an extension claim
to REQUIRED status, MUST NOT change the semantics of existing claims,
and MUST NOT introduce new security-critical properties that earlier
minor versions would silently ignore. Changes that require all
verifiers to understand new claims for security correctness MUST use
a major version increment (e.g., "1.x" to "2.0"). This ensures that
a "1.0" verifier can safely process any "1.x" token without creating
a security gap where newer security properties are silently dropped.
To support non-breaking schema evolution without version bumps, IPC
tokens MAY include additional claims beyond those defined in
Section 2.1. Verifiers MUST ignore unrecognized claims during
verification and MUST NOT reject an IPC solely because it contains
claims not defined in this specification. The version field
indicates the minimum set of claims a verifier must understand.
Unrecognized claims MUST NOT be included in authorization decisions.
This mechanism allows deployments to carry deployment-specific
metadata (e.g., trace correlation IDs, cost center tags) without
requiring a version bump, while ensuring that security-critical
claims are always processed by version-aware verifiers. Deployments
adding extension claims SHOULD use a namespace prefix (e.g.,
x-<org>-<claim>) to avoid collision with future standard claims or
other deployments' extensions.
* Entity identifiers (entityId, entries in delegationChain,
authorizedBy, issuer, audience) MUST conform to the following
constraints:
Verifier-enforceable (checked by the verification algorithm): - MUST
be non-empty strings between 1 and 128 characters - MUST be compared
using exact byte-for-byte matching (case-sensitive) - MUST NOT
contain whitespace or control characters - SHOULD contain only ASCII
printable characters (U+0021 through U+007E). If non-ASCII
characters are used, identifiers MUST be in Unicode Normalization
Form C (NFC) to ensure JCS canonicalization produces identical bytes
across implementations.
Sharma Expires 24 January 2027 [Page 14]
Internet-Draft Identity Propagation Context July 2026
Administrative (enforced by deployment policy, not by verifiers): -
MUST be unique within the deployment's trust domain - RECOMMENDED
format: URI (e.g., mailto:operator@example.com, urn:service:api-
gateway), email address, or deployment-scoped identifier with a
namespace prefix (e.g., agent:energy-optimizer) - Using email-format
identifiers for HUMAN entities (e.g., operator@example.com) and
namespace-prefixed identifiers for agents (e.g., agent:energy-
optimizer, service:api-gateway) is RECOMMENDED for human readability
in audit logs.
2.3. Example
{
"version": "1.0",
"entityId": "cell-configurator",
"entityType": "UTILITY",
"authorizedBy": "energy-optimizer",
"delegationDepth": 2,
"delegationChain": [
"operator@example.com",
"energy-optimizer",
"cell-configurator"
],
"audience": "ncmp.platform.example.com",
"sessionId": "0191a0b0-c8f4-7b2e-9a1c-3d4e5f6a7b8c",
"issuedAt": "2026-07-17T08:00:00Z",
"expiresAt": "2026-07-17T08:05:00Z",
"issuer": "api-gateway",
"trustLevel": 2,
"alg": "EdDSA",
"kid": "api-gateway/key-1",
"signature": "Base64url(...)"
}
2.4. Encoding
The IPC MUST be serialized as JSON, then Base64url-encoded for
transport.
2.5. Signature Computation
The signature is computed over a canonical serialization of all
claims EXCLUDING the signature field itself. The process is:
1. Construct a JSON object containing all claims except signature.
2. Serialize using JSON Canonicalization Scheme (JCS) per RFC 8785
to produce a deterministic byte sequence.
Sharma Expires 24 January 2027 [Page 15]
Internet-Draft Identity Propagation Context July 2026
3. Compute the signature over the canonical byte sequence using the
algorithm specified in the alg claim.
4. Base64url-encode the signature (without padding, per RFC 4648
Section 5) and include it as the signature claim.
The issuer field IS included in the signature input. This means that
when a trust boundary re-signs the IPC: 1. The issuer field is
updated to the re-signing service's identifier. 2. A new signature
is computed over all claims (including the new issuer) using the re-
signing service's private key. 3. The new signature replaces the old
signature value.
This ensures that each signature cryptographically binds the issuer
to the IPC content, proving which service validated and re-signed it.
The signature input includes the current issuer and kid values at the
time of signing. When a trust boundary re-signs, it updates both
issuer and kid before computing the new signature. The downstream
verifier's canonical bytes will therefore reflect the re-signing
service's identity and key identifier, not the original creator's.
Implementations that re-sign IPCs MUST NOT re-serialize claims
through a non-JCS-compliant JSON serializer. The canonical bytes for
signature computation MUST be produced by a JCS-compliant
implementation operating on the complete token object (including any
unrecognized extension claims). Re-serializing through a non-
compliant serializer may alter number representation, Unicode
normalization, or key ordering, causing downstream signature
verification to fail.
The integer claims delegationDepth and trustLevel MUST be serialized
as JSON integers without decimal points (e.g., 2, not 2.0). JCS (RFC
8785) specifies that integer-valued numbers serialize without a
decimal point, but intermediate deserialization into floating-point
types may produce incorrect canonical output.
Note on JCS sort order: JCS (RFC 8785 Section 3.2.3) sorts object
member names by comparing their UTF-16 code unit sequences. For
ASCII-only member names (all claims defined in this specification),
this is equivalent to byte-order sorting. Extension claims
(Section 2.2) that use non-ASCII characters in claim names MUST be
aware that JCS sort order follows RFC 8785 Section 3.2.3 exactly,
including surrogate pair handling. Extension claim names SHOULD be
restricted to ASCII characters for maximum interoperability across
JCS implementations.
Sharma Expires 24 January 2027 [Page 16]
Internet-Draft Identity Propagation Context July 2026
2.6. Algorithm Restrictions
EdDSA with curve Ed25519 (per RFC 8037) MUST be used for IPCs that
traverse multiple trust boundaries (the common case). Ed25519's
asymmetric key model allows each trust boundary to verify using the
upstream's public key without sharing secret material.
HS256 (HMAC-SHA-256, per RFC 7518 Section 3.2) MAY be used only in
single-hop deployments where exactly one service creates the IPC and
exactly one service verifies it. In this configuration, both
services share the symmetric secret. HS256 MUST NOT be used when:
* The IPC will be re-signed at any trust boundary
* More than two services participate in the chain
* The deployment topology may change to include additional hops
Deployments that begin with single-hop HMAC and later add trust
boundaries MUST migrate to EdDSA before enabling re-signing.
2.7. FIPS-Compatible Algorithm Profile
Deployments operating in FIPS 140-2/140-3 constrained environments
(e.g., government, regulated telecom, banking, healthcare) where
Ed25519 is not available in validated cryptographic modules MAY use
ES256 (ECDSA with P-256 and SHA-256, per RFC 7518 Section 3.4) as an
alternative asymmetric signing algorithm.
When ES256 is used: - The alg claim MUST be set to "ES256" - Key
discovery endpoints MUST serve keys with "kty": "EC", "crv": "P-256"
per RFC 7518 Section 6.2 - The signature is computed over the same
JCS canonical bytes as EdDSA (Section 2.5) - The signature value is
the base64url-encoded concatenation of the R and S values (64 bytes
total, per RFC 7518 Section 3.4)
Deployments MUST NOT mix Ed25519 and ES256 within the same service
chain. All trust boundaries and enforcement points in a given chain
MUST use the same asymmetric algorithm. The choice is deployment-
wide, not per-service.
The verification algorithm (Section 3.2, Step 5) MUST accept "ES256"
as a valid algorithm value when the deployment is configured for the
FIPS profile. Step 6g dispatches to ECDSA-P256.Verify for "ES256"
tokens.
Services configured as Trust Boundaries (i.e., services that re-sign
IPCs) MUST have allowHMAC = false. Implementations MUST reject
configurations where a service is assigned the Trust Boundary role
(Section 11.3) and allowHMAC = true. This prevents misconfigured
Sharma Expires 24 January 2027 [Page 17]
Internet-Draft Identity Propagation Context July 2026
services from accepting HMAC-signed tokens in a multi-hop chain where
symmetric key material would need to be shared across trust
boundaries.
2.8. Design Rationale: Why Not JWS?
IPC uses a JSON format with JCS (RFC 8785) canonicalization rather
than JWS (RFC 7515). This is a deliberate design choice driven by
IPC's per-hop re-signing workflow. The following analysis evaluates
both JWS compact serialization and JWS JSON Serialization:
*JWS Compact Serialization (RFC 7515 Section 7.1):*
JWS compact serialization represents a signed token as
BASE64URL(header).BASE64URL(payload).BASE64URL(signature). Re-
signing an IPC at a trust boundary would require: 1. Base64url-
decode the payload to access claims 2. Modify issuer and kid in the
decoded payload 3. Re-encode the modified payload as base64url 4.
Construct a new protected header (or reuse) 5. Compute signature
over the new header.payload concatenation 6. Assemble the new
compact token
IPC's approach requires: 1. Parse the JSON object 2. Modify issuer
and kid 3. Compute JCS canonical bytes (excluding signature) 4.
Sign and set the signature field
The difference is not in operation count but in *verification
determinism*: JWS requires the verifier to use the exact base64url
encoding the signer produced (since the signature covers the encoded
form). IPC's JCS approach allows the verifier to independently
reconstruct the canonical signed bytes from the parsed JSON object
without depending on the signer's encoding choices. This eliminates
a class of interoperability failures where base64url implementations
differ in whitespace handling, line-wrapping, or padding.
*JWS JSON Serialization (RFC 7515 Section 7.2):*
JWS JSON Serialization could in principle support IPC's re-signing
model by placing mutable fields (issuer, kid) in the unprotected
header. However, this approach has practical drawbacks:
1. *Unprotected header semantics vary across implementations.*
Libraries differ in how they expose and validate unprotected
headers. Some JOSE libraries reject or ignore unprotected
headers entirely. A constrained profile mandating specific
unprotected header behavior would require the same implementation
effort as IPC's native format.
Sharma Expires 24 January 2027 [Page 18]
Internet-Draft Identity Propagation Context July 2026
2. *Base64url-within-base64url nesting.* The IPC payload would be
base64url-encoded inside the JWS structure, which is then
base64url- encoded for transport. IPC's flat structure means the
decoded JSON is directly inspectable without double decoding -
valuable for debugging, log analysis, and operator tooling.
3. *Single-object manipulation model.* IPC middleware operates on
one JSON object throughout the verify-modify-sign cycle. JWS
JSON Serialization requires managing separate protected, header,
payload, and signature fields with different encoding rules,
increasing the surface area for implementation bugs in the re-
signing path.
*The core design principle:* IPC optimizes for the re-signing hot
path (verify upstream, update issuer, re-sign, forward) that executes
at every trust boundary in every request. JCS provides a
deterministic canonical form that any conformant implementation can
independently reproduce from the parsed claims, without depending on
how the upstream serialized the token.
*Tradeoffs acknowledged:*
* IPCs are not directly verifiable by existing JWT/JWS libraries
without an IPC-specific implementation. This is acceptable
because IPC operates within platform infrastructure where purpose-
built middleware is deployed at each trust boundary.
* This choice increases the implementation barrier compared to JWS-
based approaches: deployments MUST verify that their JCS
implementation produces correct canonical output (Appendix E
provides a test vector for this purpose) before using it in
production.
* The JCS library ecosystem (RFC 8785) is smaller than the JWS
ecosystem. Implementors SHOULD validate their chosen JCS library
against the RFC 8785 test vectors before production deployment.
* A future revision of this specification MAY define a JWS-based
profile for deployments that prefer JOSE tooling compatibility,
provided the re-signing semantics and verification determinism
requirements can be met. The authors welcome WG input on whether
a constrained JWS JSON Serialization profile should be developed
as an alternative encoding.
3. Trust Boundaries and Re-signing
3.1. Concept
At each trust boundary, the receiving service:
1. Extracts the IPC from the incoming protocol binding.
Sharma Expires 24 January 2027 [Page 19]
Internet-Draft Identity Propagation Context July 2026
2. Verifies the signature using the upstream issuer's public key.
3. Validates all enforcement rules (Section 5).
4. Re-signs the IPC with its own private key, updating the issuer
field.
5. Forwards the re-signed IPC to the next service.
3.2. Verification Algorithm
A service receiving an IPC MUST execute the following steps in order.
The service MUST reject at the first step that fails.
VERIFY-IPC(encoded_ipc, key_resolver, config):
0. Size and Format Pre-check:
If len(encoded_ipc) == 0 -> REJECT (401, "malformed_ipc")
If len(encoded_ipc) > 4096 -> REJECT (401, "malformed_ipc")
If encoded_ipc contains any character not in [A-Za-z0-9_-]
-> REJECT (401, "malformed_ipc")
// Base64url encoding MUST NOT include padding ('=' characters).
// This pre-check prevents resource exhaustion from oversized
// inputs (Section 8.6) and rejects obviously malformed values
// before incurring decode and parse costs.
1. Decode: base64url-decode encoded_ipc to obtain JSON bytes.
If decoding fails -> REJECT (401, "malformed_ipc")
2. Parse: JSON-parse the bytes into a Token object.
If parsing fails -> REJECT (401, "malformed_ipc")
If the JSON object contains duplicate member names
-> REJECT (401, "malformed_ipc")
// RFC 8259 states names SHOULD be unique but does not mandate it.
// IPC requires uniqueness to prevent ambiguous claim values that
// could differ between parser implementations, creating security
// vulnerabilities where verification and enforcement use different
// values for the same claim name.
//
// Implementation note: Verifiers MUST use a JSON parser that
// detects and reports duplicate member names. Parsers that silently
// retain only the first or last value for duplicate names are
// non-conformant. Many standard library JSON parsers (e.g.,
// Python's json.loads into dict, Go's json.Unmarshal into map)
// silently discard duplicates. Implementations MUST use a parser
// mode or wrapper that detects duplicates before constructing the
// Token object.
3. Version:
If Token.version is not a string -> REJECT (401, "malformed_ipc")
If Token.version does not match the format "^[1-9][0-9]*\.[0-9]+$"
Sharma Expires 24 January 2027 [Page 20]
Internet-Draft Identity Propagation Context July 2026
-> REJECT (401, "malformed_ipc")
// Version MUST be exactly "<major>.<minor>" where major is a
// non-zero-padded positive integer and minor is a non-negative
// integer. Examples: "1.0", "2.1", "10.0". Invalid: "01.0",
// "1", "1.0.1", "1.0-beta", "v1.0".
Parse Token.version as "<major>.<minor>".
If major version != "1" -> REJECT (401, "unsupported_version")
// Minor version differences are acceptable per Section 2.2.
4. Trust Level Dispatch:
If Token.trustLevel is not an integer -> REJECT (401, "malformed_ipc")
If Token.trustLevel == 1:
If Token.alg is absent OR Token.alg is not a string OR Token.alg != "none"
-> REJECT (401, "malformed_ipc")
If Token.kid is present and Token.kid != ""
-> REJECT (401, "malformed_ipc")
If Token.signature is present and Token.signature != ""
-> REJECT (401, "malformed_ipc")
// Trust Level 1 IPCs MUST NOT carry kid or signature values.
// A non-empty kid or signature in an unsigned IPC indicates
// either corruption or a downgrade attempt.
If config.isEnforcementPoint == true
-> REJECT (401, "unsigned_token")
// Enforcement points MUST NOT accept Trust Level 1 IPCs regardless
// of config.allowUnsignedForAudit. This prevents downgrade attacks
// where an unsigned IPC is substituted for a signed one.
If config.allowUnsignedForAudit != true
-> REJECT (401, "unsigned_token")
Skip steps 5-6 (key resolution and signature verification)
and proceed to Step 7. Trust Level 1 IPCs undergo structural
validation only and MUST NOT be used for authorization decisions.
If Token.trustLevel < 1 or Token.trustLevel > 2
-> REJECT (401, "malformed_ipc")
// For trustLevel == 2: continue to Step 5
5. Algorithm Validation (Level 2+ only):
If Token.alg is not one of: "EdDSA", "ES256", "HS256"
-> REJECT (401, "unsupported_algorithm")
If Token.alg is "EdDSA" or "ES256":
If config.asymmetricAlgorithm is configured AND
Token.alg != config.asymmetricAlgorithm
-> REJECT (401, "algorithm_not_permitted")
// Deployments MUST NOT mix EdDSA and ES256 within a chain.
// config.asymmetricAlgorithm enforces deployment-wide
// algorithm consistency.
If Token.signature is not a string or is empty or is absent
-> REJECT (401, "malformed_ipc")
Sharma Expires 24 January 2027 [Page 21]
Internet-Draft Identity Propagation Context July 2026
6. Key Resolution and Signature Verification:
Pre-check: If Token.kid is absent, null, or not a string
-> REJECT (401, 'malformed_ipc')
If Token.issuer is absent, null, or not a string
-> REJECT (401, 'malformed_ipc')
a. Extract Token.kid and Token.issuer
b. Resolve upstream_public_key using the tuple
(Token.issuer, Token.kid, Token.alg):
- Via key discovery endpoint (Section 3.6), OR
- Via static key configuration
The verifier MUST maintain a mapping of known upstream issuers
to their key sources (via static config, key discovery endpoint,
or service mesh control plane).
c. If Token.kid is unknown or key not found
-> REJECT (401, "unknown_key")
c2. If the resolved key has status "compromised"
-> REJECT (401, "unknown_key")
// Compromised keys MUST be rejected regardless of token
// validity or expiry.
c3. Pre-validate Token.issuedAt for key validity comparison:
If Token.issuedAt is absent, not a string, or does not match
the canonical format YYYY-MM-DDTHH:MM:SSZ (20 characters)
-> REJECT (401, "malformed_ipc")
// This minimal validation allows safe comparison against
// key validity timestamps. Full temporal validation
// (including clock skew and expiry checks) occurs in Step 8.
If the resolved key has a `validFrom` timestamp and
Token.issuedAt < key.validFrom
-> REJECT (401, "unknown_key")
// The token claims to have been issued before this key
// existed.
c4. If the resolved key has status "retired" and key.validUntil
is set:
Accept only if Token.issuedAt <= key.validUntil.
If Token.issuedAt > key.validUntil
-> REJECT (401, "unknown_key")
// A retired key should only verify tokens issued during
// the key's active period.
d. Verify that the resolved key belongs to Token.issuer. If the
key source serves keys for multiple services, confirm the kid
is associated with Token.issuer. When keys are statically
configured, the configuration MUST explicitly associate each
kid with its owning issuer identifier. A kid that resolves
successfully but is not mapped to Token.issuer indicates a
potential confused-deputy attack (T13). If mismatch:
-> REJECT (401, "unknown_key")
e. Construct canonical_bytes = JCS(Token excluding "signature")
f. Decode sig = base64url-decode(Token.signature)
Sharma Expires 24 January 2027 [Page 22]
Internet-Draft Identity Propagation Context July 2026
g. Dispatch on Token.alg:
If Token.alg == "EdDSA":
Verify: Ed25519.Verify(upstream_public_key, canonical_bytes, sig)
Else if Token.alg == "ES256":
Verify: ECDSA-P256-SHA256.Verify(upstream_public_key, canonical_bytes, sig)
Else if Token.alg == "HS256":
If config.allowHMAC != true -> REJECT (401, "algorithm_not_permitted")
Verify: HMAC-SHA256.Verify(shared_secret, canonical_bytes, sig)
// Note: No Else branch is needed here. Step 5 has already
// validated that Token.alg is one of the supported values.
// Implementations MAY include a defensive Else -> REJECT for
// defense-in-depth, but it is unreachable in conformant code.
If verification fails -> REJECT (401, "signature_invalid")
7. Type Validation:
All REQUIRED claims MUST be present and of the correct JSON type
as defined in Section 2.1 (string, integer, or array).
- entityId, entityType, authorizedBy, sessionId, issuedAt,
expiresAt, issuer, version: MUST be strings
- delegationDepth, trustLevel: MUST be integers. Implementations
MUST verify that these values are encoded as JSON integer
literals without decimal points or exponent notation (matching
the pattern `0|[1-9][0-9]*`). Values such as `2.0`, `2e0`, or
`2E0` MUST be rejected as `malformed_ipc` even if mathematically
integral. This ensures JCS canonicalization produces identical
bytes across implementations regardless of parser numeric
handling.
- delegationChain: MUST be an array of strings
- audience: MUST be a string. MUST be present when trustLevel >= 2.
If trustLevel >= 2 and audience is absent -> REJECT (401, 'malformed_ipc')
// Note: The audience non-empty check is enforced again at Step 9f
// as defense-in-depth. Step 7 checks presence; Step 9f checks
// semantic validity (non-empty, non-whitespace).
- alg: MUST be a string (REQUIRED at all trust levels)
- kid, signature (if present): MUST be strings.
MUST be present when trustLevel >= 2.
If trustLevel >= 2 and (kid is absent OR signature is absent)
-> REJECT (401, 'malformed_ipc')
- entityType MUST be one of: AUTONOMOUS, SUPERVISED, UTILITY,
HUMAN, SYSTEM (case-sensitive exact match)
If any claim is missing, null, of wrong type, or entityType is
unrecognized -> REJECT (401, "malformed_ipc")
8. Temporal Validity:
a. Parse Token.issuedAt and Token.expiresAt as ISO 8601 UTC timestamps.
Both MUST match the canonical format YYYY-MM-DDTHH:MM:SSZ (exactly
20 characters, trailing "Z", no fractional seconds).
If either fails to parse or does not match the canonical format
Sharma Expires 24 January 2027 [Page 23]
Internet-Draft Identity Propagation Context July 2026
-> REJECT (401, 'malformed_ipc')
b. now = current UTC time
c. If Token.expiresAt <= Token.issuedAt -> REJECT (401, "malformed_ipc")
// expiresAt must be strictly after issuedAt (positive lifetime)
c2. If (Token.expiresAt - Token.issuedAt) > config.maxTTL
-> REJECT (401, "malformed_ipc")
// The token's stated lifetime MUST NOT exceed the deployment's
// maximum configured TTL. This prevents a compromised or
// misconfigured IPC Creator from issuing long-lived tokens
// that bypass short-TTL replay protection.
d. If Token.issuedAt > now + config.clockSkew -> REJECT (403, "issued_in_future")
e. If now > Token.expiresAt + config.clockSkew -> REJECT (403, "token_expired")
f. If config.maxTokenAge > 0:
age = now - Token.issuedAt
If age > config.maxTokenAge + config.clockSkew -> REJECT (403, "token_too_old")
Note: maxTokenAge is OPTIONAL and provides defense against tokens
that are valid but were issued unreasonably long ago (e.g., due to
clock manipulation at the creator). Deployments that do not require
this check SHOULD set config.maxTokenAge to 0 (disabled).
Note: The addition of config.clockSkew to the maxTokenAge comparison
is intentional. Without this tolerance, tokens issued at the boundary
of maxTokenAge could be rejected by verifiers whose clocks are
slightly behind the issuer's clock. The effective maximum age is
therefore maxTokenAge + clockSkew. Deployments that require a strict
maximum age SHOULD account for this extension when configuring
maxTokenAge.
9. Structural Integrity:
a. If len(Token.delegationChain) == 0 -> REJECT (403, "empty_chain")
b. If Token.delegationDepth != len(Token.delegationChain) - 1
-> REJECT (403, "depth_mismatch")
c. If len(Token.delegationChain) >= 2 AND
Token.authorizedBy != Token.delegationChain[len-2]
-> REJECT (403, "chain_consistency_error")
d. If len(Token.delegationChain) == 1 AND
Token.authorizedBy != Token.entityId
-> REJECT (403, "chain_consistency_error")
e. If Token.entityId != Token.delegationChain[len(Token.delegationChain) - 1]
-> REJECT (403, "chain_consistency_error")
f. If Token.trustLevel >= 2 AND (Token.audience == "" OR Token.audience contains only whitespace)
-> REJECT (401, "malformed_ipc")
// An empty or whitespace-only audience for Trust Level 2+ is a
// structural validity error (malformed token), not a semantic
// audience mismatch.
g. Identifier constraints:
For each of: Token.entityId, Token.authorizedBy, Token.issuer,
Sharma Expires 24 January 2027 [Page 24]
Internet-Draft Identity Propagation Context July 2026
Token.audience (if present), and each entry in Token.delegationChain:
If len(identifier) < 1 or len(identifier) > 128
-> REJECT (401, 'malformed_ipc')
If identifier contains whitespace or control characters (U+0000-U+001F, U+007F)
-> REJECT (401, 'malformed_ipc')
10. Depth Enforcement:
If Token.delegationDepth > config.maxDepth
-> REJECT (403, "depth_exceeded")
11. Circular Detection:
seen = {}
For each entity in Token.delegationChain:
If entity in seen -> REJECT (403, "circular_delegation")
seen.add(entity)
12. Audience (terminal enforcement points only):
If config.isTerminalEnforcementPoint:
If Token.audience is present AND Token.audience != "" AND Token.audience != config.serviceId
-> REJECT (403, "audience_mismatch")
// Trust boundaries that re-sign and forward MUST skip this step.
// Only the terminal service that makes the final authorization
// decision (and does not re-sign) executes audience verification.
//
// isTerminalEnforcementPoint is a static configuration property
// of the service's role in the deployment topology.
//
// Services that ALWAYS act as terminal enforcement points (never
// forward) set isTerminalEnforcementPoint = true.
//
// Services that ALWAYS act as pass-through trust boundaries (never
// make final decisions) set isTerminalEnforcementPoint = false.
//
// Services that sometimes forward and sometimes terminate MUST
// set isTerminalEnforcementPoint = false in the verification
// algorithm and perform audience verification in application
// logic AFTER VERIFY-IPC returns ACCEPT, only when the service
// determines it will not forward. Such services MUST be
// configured as both Trust Boundary and Enforcement Point
// (per Section 11.3) and MUST document their audience
// verification behavior.
13. Revocation (if RevocationChecker configured):
// Revocation checks MUST use a local in-memory cache or
// bounded-latency shared cache. Verifiers MUST NOT perform
// unbounded synchronous network calls per entity during
// verification. If pull-based revocation is used, polling
// MUST refresh a local cache asynchronously; verification
Sharma Expires 24 January 2027 [Page 25]
Internet-Draft Identity Propagation Context July 2026
// reads from the cache only.
// If revocation state is unavailable, enforcement points
// MUST either fail closed (reject the IPC) or operate under
// an explicitly configured degraded mode that is logged and
// alerted.
For each entity in Token.delegationChain:
revocation = RevocationChecker.GetRevocation(entity)
If revocation is not null:
If revocation.scope == "cascade"
-> REJECT (403, "entity_revoked")
If revocation.scope == "single" AND entity == Token.entityId
-> REJECT (403, "entity_revoked")
// "single" revocations only reject if the revoked entity is
// the current executor (entityId), not an intermediate in the chain.
13b. Caller-to-Issuer Binding (RECOMMENDED):
If config.callerBindingEnabled AND caller_identity is available
(from mTLS certificate, bearer token, or service mesh metadata):
If caller_identity does not match Token.issuer AND
caller_identity is not in config.allowedPresentersFor[Token.issuer]
-> REJECT (403, "issuer_caller_mismatch")
// This step verifies that the authenticated transport identity
// of the immediate caller is authorized to present IPCs signed
// by Token.issuer. Without this check, a service that obtains
// a valid IPC could present it directly to a downstream service
// bypassing the intended chain (confused deputy, T13).
// This step requires caller_identity to be available from the
// transport layer (mTLS, bearer token, service mesh). If caller
// identity is not available, this step is skipped but a warning
// SHOULD be logged.
14. Replay Detection (enforcement points only):
If config.isEnforcementPoint:
// The replay cache operation MUST be atomic (check-and-insert).
// Implementations SHOULD use atomic primitives (e.g., Redis SETNX,
// CAS operations) to prevent race conditions (T18).
If replay cache is unavailable or at capacity:
-> REJECT (503, "replay_cache_unavailable")
// Enforcement points MUST fail closed when replay detection
// cannot be performed. Failing open would allow replay attacks
// during infrastructure degradation — exactly when attacks are
// most likely.
If Token.sessionId exists in replay cache
-> REJECT (403, "token_replayed")
Else: Atomically insert Token.sessionId into replay cache with
TTL = max(config.replayCacheTTL, Token.expiresAt - now() + config.clockSkew)
// The replay cache TTL MUST be at least config.clockSkew to
// prevent premature eviction. The config.replayCacheTTL parameter
Sharma Expires 24 January 2027 [Page 26]
Internet-Draft Identity Propagation Context July 2026
// (Section 5.6) provides the normative minimum floor.
// Pure trust boundaries that only re-sign MAY skip this step.
// Implementations MUST NOT authorize or execute the requested
// operation until all steps complete successfully. Optimistic
// execution that begins processing before ACCEPT is non-conformant.
15. ACCEPT: Token is valid.
3.3. Re-signing Algorithm
A trust boundary that forwards requests downstream MUST re-sign the
IPC after successful verification. The re-signing algorithm is:
Trust boundaries MUST NOT re-sign IPCs with alg set to "HS256". If a
trust boundary receives an HMAC-signed IPC that passes verification
(because it is configured as the single-hop verifier), it MUST NOT
forward a re-signed IPC downstream. HMAC-signed IPCs are terminal by
definition — the trust boundary may only act as an Enforcement Point
for that request, not as a pass-through re-signer. If re-signing and
forwarding is required, the deployment MUST migrate to EdDSA
(Section 2.6).
Sharma Expires 24 January 2027 [Page 27]
Internet-Draft Identity Propagation Context July 2026
RESIGN-IPC(token, service_id, signing_private_key):
1. Verify that token passed VERIFY-IPC (Section 3.2).
Re-signing MUST NOT occur without prior verification.
If token.alg == "HS256" -> ABORT (cannot re-sign HMAC tokens)
2. Update mutable fields:
token.issuer = service_id
token.kid = signing_key_id
3. Compute new signature:
a. canonical_bytes = JCS(token excluding "signature")
b. Dispatch on token.alg:
If token.alg == "EdDSA":
sig = Ed25519.Sign(signing_private_key, canonical_bytes)
Else if token.alg == "ES256":
sig = ECDSA-P256-SHA256.Sign(signing_private_key, canonical_bytes)
c. token.signature = base64url-encode(sig)
4. Immutability check:
All claims other than "issuer", "kid", and "signature" MUST remain
unchanged from the verified token. If any other field was
modified, the implementation is non-conformant.
Note: The token object used for JCS canonicalization in Step 3a
MUST include all claims present in the verified token, including
any unrecognized extension claims (Section 2.2). Implementations
MUST preserve the complete JSON object through the re-signing
process. Deserializing into a typed struct that discards unknown
fields will produce incorrect canonical output, causing downstream
signature verification to fail.
5. Encode for transport:
encoded = base64url-encode(JSON(token))
6. Set protocol binding:
HTTP: Set header Identity-Propagation-Context: <encoded>
gRPC: Set metadata identity-propagation-context: <encoded>
Kafka: Set record header identity-propagation-context: <encoded>
3.4. Immutability
The IPC payload (all claims except issuer, kid, and signature) MUST
NOT be modified during re-signing. Only the issuer, kid, and
signature fields change during re-signing.
Sharma Expires 24 January 2027 [Page 28]
Internet-Draft Identity Propagation Context July 2026
3.5. Key Management
Each trust boundary service maintains: - Its own signing key
(private) - The public key of the upstream issuer (for verification)
A key discovery endpoint (similar to OIDC .well-known/jwks.json) is
RECOMMENDED for dynamic key retrieval.
3.6. Key Discovery Endpoint
Services fulfilling the Trust Boundary or IPC Creator conformance
classes (Section 11.3) MUST make their public keys available through
at least one of the following mechanisms:
1. The IPC key discovery HTTP endpoint defined below (REQUIRED for
multi-vendor interoperability claims per Section 1.8).
2. An authenticated platform control plane that provides equivalent
key material and metadata (e.g., service mesh xDS/SDS, SPIFFE
bundle endpoints, Kubernetes secrets).
The HTTP endpoint is the mandatory-to-implement interoperability
profile. Deployments using control-plane key distribution alone MUST
ensure that the distributed key material includes all fields defined
below (serviceId, keys with status, validFrom, validUntil).
Enforcement Points that only verify (and never re-sign) MAY use
static key configuration alone but SHOULD support key discovery for
operational flexibility.
The key discovery endpoint MUST be available at:
GET /.well-known/ipc-keys
The response MUST be a JSON object:
Sharma Expires 24 January 2027 [Page 29]
Internet-Draft Identity Propagation Context July 2026
{
"serviceId": "scope-enforcement",
"cacheMaxAge": 300,
"keys": [
{
"kid": "scope-enforcement-key-1",
"kty": "OKP",
"crv": "Ed25519",
"x": "<base64url-encoded public key>",
"use": "sig",
"status": "active",
"validFrom": "2026-07-01T00:00:00Z",
"validUntil": null
}
]
}
* serviceId (string, REQUIRED): This service's IPC issuer
identifier. The serviceId value in the key discovery response
MUST exactly match the issuer claim value that this service sets
when signing or re-signing IPCs. Verifiers use this
correspondence to confirm that a resolved key belongs to the
claimed issuer (Section 3.2, Step 6d).
* cacheMaxAge (integer, OPTIONAL): Maximum number of seconds a
client SHOULD cache this response. If absent, clients use their
locally configured cache TTL (RECOMMENDED default: 300 seconds).
The server MAY reduce this value during key rotation to accelerate
downstream key refresh (e.g., set to 30 seconds after publishing a
new key). Clients MUST NOT cache responses longer than this value
when present.
* keys (array, REQUIRED): JWK objects with IPC metadata.
- status (string, REQUIRED): "active", "retired", or
"compromised".
- validFrom (string, REQUIRED): ISO 8601 UTC timestamp.
- validUntil (string or null, REQUIRED): null if still active.
Implementations MUST cache key discovery responses for no longer than
the configured cache TTL (RECOMMENDED default: 300 seconds) and MUST
refresh before using a key whose validUntil has passed.
Sharma Expires 24 January 2027 [Page 30]
Internet-Draft Identity Propagation Context July 2026
Key material validation depends on the algorithm: - For Ed25519 keys
("kty": "OKP", "crv": "Ed25519"): the x field MUST be exactly 43
characters of base64url (representing 32 bytes of public key
material, without padding). Verifiers MUST reject keys where x does
not decode to exactly 32 bytes. - For ES256 keys ("kty": "EC", "crv":
"P-256"): the x and y fields MUST each be exactly 43 characters of
base64url (representing 32 bytes each). Both coordinates are
REQUIRED. Verifiers MUST reject keys where x or y does not decode to
exactly 32 bytes.
The key discovery endpoint exposes only public key material and MAY
be served without authentication (public keys are not secret).
However, deployments SHOULD apply rate limiting to prevent
enumeration attacks and SHOULD restrict access to the platform's
internal network when the endpoint is not intended for external
consumption.
Deployments MUST maintain a mapping from issuer identifiers to key
discovery URLs. This mapping MAY be distributed via service mesh
configuration, DNS service discovery, or static configuration. The
mechanism is deployment-specific and not defined by this
specification.
3.7. Error Response Format
When IPC verification or enforcement fails, the error response MUST
use the following JSON structure:
{
"error": "signature_invalid",
"errorDescription": "IPC signature verification failed",
"sessionId": "0191a0b0-c8f4-7b2e-9a1c-3d4e5f6a7b8c",
"entityId": "cell-configurator",
"issuer": "api-gateway"
}
Fields:
* error (string, REQUIRED): Machine-readable error code. MUST be
one of: malformed_ipc, unsupported_version, unsigned_token,
signature_invalid, issued_in_future, token_expired,
token_replayed, unknown_key, token_too_old, empty_chain,
depth_mismatch, chain_consistency_error, depth_exceeded,
circular_delegation, audience_mismatch, entity_revoked,
algorithm_not_permitted, unsupported_algorithm,
replay_cache_unavailable, issuer_caller_mismatch.
* errorDescription (string, REQUIRED): Human-readable description.
* sessionId (string, OPTIONAL): From the IPC if parseable.
Sharma Expires 24 January 2027 [Page 31]
Internet-Draft Identity Propagation Context July 2026
* entityId (string, OPTIONAL): From the IPC if parseable.
* issuer (string, OPTIONAL): From the IPC if parseable.
IPC error responses use camelCase field names (e.g.,
errorDescription) to align with the IPC claims naming convention
(entityId, sessionId). This intentionally differs from OAuth 2.0's
error_description convention.
The sessionId, entityId, and issuer fields SHOULD be included when
the IPC was successfully parsed (even if signature verification
failed). They MUST NOT be included if the IPC could not be decoded.
3.8. Verification Failure
When IPC verification fails at a trust boundary, the service MUST:
1. Reject the request. The IPC MUST NOT be forwarded downstream.
2. Return an appropriate error to the caller:
* HTTP: 401 Unauthorized if the IPC signature is invalid, or if
the IPC header is absent and fail-closed mode is configured
(Section 3.9).
* HTTP: 403 Forbidden if the IPC is valid but fails enforcement
rules (e.g., delegationDepth > maxDepth, expired, audience
mismatch).
* gRPC: UNAUTHENTICATED (code 16) or PERMISSION_DENIED (code 7)
following the same distinction.
3. Log the failure with sufficient detail for audit (sessionId,
entityId, failure reason) without logging the full IPC (which
could be replayed from logs).
Trust Boundaries and Enforcement Points MUST log the following for
every IPC verification (successful or failed): - sessionId of the IPC
- entityId of the current executor - Verification result (accept/
reject) - If rejected: the error code from Section 3.7 - Timestamp of
the verification event
This requirement is normative because the single-signer model
(Section 8.5) relies on audit trails for forensic traceability.
Without audit logging, a compromised intermediate cannot be detected
after the fact.
During migration periods, deployments MAY configure enforcement
points to operate in "permissive mode" where IPC failures are logged
but not enforced. This MUST be a temporary configuration and MUST
NOT be used in production enforcement.
Sharma Expires 24 January 2027 [Page 32]
Internet-Draft Identity Propagation Context July 2026
3.9. Absent IPC
The behavior when an IPC header is absent from a request is
deployment-specific:
* Security-critical enforcement points SHOULD reject requests
lacking a valid IPC (fail-closed).
* Services operating in mixed environments during migration MAY
accept requests without IPC, provided the bearer token alone
provides sufficient authorization for the requested operation.
* Deployments MUST document which services require IPC and which
operate in a degraded mode without it.
4. Delegation Issuance
4.1. IPC Creation
An IPC is created at the platform trust boundary (e.g., an API
gateway) when:
1. An entity authenticates (e.g., via OAuth 2.0 JWT).
2. Delegation context is provided (e.g., via a delegation-token from
an STS).
3. The trust boundary validates both and constructs the IPC.
4.2. Delegation Token
A delegation-token is a short-lived, signed token issued by a
platform STS that establishes the delegation relationship. It is
consumed by the trust boundary during IPC creation and discarded
afterward.
The delegation-token is NOT the IPC. It is the input from which the
IPC is constructed. The format and issuance protocol for delegation-
tokens is out of scope for this specification - platforms MAY use RFC
8693 Token Exchange, proprietary STS protocols, or any mechanism that
provides authenticated delegation context to the trust boundary.
4.3. IPC Creation Algorithm
The following algorithm defines how an IPC Creator constructs a new
IPC:
Sharma Expires 24 January 2027 [Page 33]
Internet-Draft Identity Propagation Context July 2026
CREATE-IPC(authenticated_entity, delegation_context, config):
1. Determine delegation chain:
If delegation_context is present:
chain = delegation_context.chain + [authenticated_entity.id]
Else:
chain = [authenticated_entity.id]
2. Validate chain depth:
If len(chain) - 1 > config.maxDepth -> REJECT
3. Set claims:
version = "1.0"
entityId = authenticated_entity.id
entityType = authenticated_entity.type
If len(chain) == 1:
authorizedBy = entityId // self-authorized root
Else:
authorizedBy = chain[len(chain) - 2] // immediate parent
delegationDepth = len(chain) - 1
delegationChain = chain
audience = config.targetServiceId // final enforcement point
If trustLevel >= 2 AND audience is empty -> REJECT (creation failed)
sessionId = generateUUIDv7()
issuedAt = now()
If delegation_context is present:
expiresAt = min(now() + config.maxTTL,
delegation_context.expiresAt) // attenuation
Else:
expiresAt = now() + config.maxTTL
issuer = config.serviceId
kid = config.currentKeyId
trustLevel = 2
alg = config.asymmetricAlgorithm // "EdDSA" (default) or "ES256" (FIPS)
4. Sign:
canonical_bytes = JCS(token excluding "signature")
If alg == "EdDSA":
token.signature = base64url(Ed25519.Sign(config.privateKey,
canonical_bytes))
Else if alg == "ES256":
token.signature = base64url(ECDSA-P256-SHA256.Sign(config.privateKey,
canonical_bytes))
5. Encode:
encoded = base64url(JSON(token))
6. Attach to outbound request via protocol binding (Section 6)
Sharma Expires 24 January 2027 [Page 34]
Internet-Draft Identity Propagation Context July 2026
IPC Creators SHOULD implement rate limiting per authenticated entity
to prevent resource exhaustion at downstream replay caches and
signing infrastructure. RECOMMENDED limits: no more than 100 IPC
creations per second per entity under normal operation. Deployments
with higher-throughput requirements MUST ensure their replay cache
infrastructure can sustain the expected creation rate without
evicting entries before their TTL expires.
A new IPC MUST be created for each sub-delegation. Existing IPCs
MUST NOT be modified to add entries to the delegation chain - the
immutability rule (Section 3.4) prevents this. When an entity sub-
delegates, the platform creates a fresh IPC with the extended chain.
5. Enforcement Rules
5.1. Maximum Delegation Depth
Each deployment MUST configure a maximum delegation depth (maxDepth).
An IPC with delegationDepth > maxDepth MUST be rejected.
Deployments SHOULD configure consistent maxDepth values across all
trust boundaries and enforcement points in a given service chain.
Inconsistent values may result in IPCs being accepted at early hops
but rejected downstream. The IPC Creator SHOULD set delegation chain
depth based on the most restrictive enforcement point in the target
path.
5.2. Chain Verification
Every entry in delegationChain MUST be traceable to an accountable
root (the first entry). The root SHOULD be either:
* A human principal (entityType: HUMAN), OR
* A system principal (entityType: SYSTEM) for platform-initiated
operations
Root type enforcement is a deployment policy decision. Deployments
without a principal registry MAY accept any root identifier format
that conforms to the identifier constraints in Section 2.2.
Deployments MAY restrict roots to human principals only via policy.
An IPC where the first entry in delegationChain does not match the
deployment's allowed root types MUST be rejected.
Sharma Expires 24 January 2027 [Page 35]
Internet-Draft Identity Propagation Context July 2026
The root entity's type is determined by the IPC creator (trust
boundary) at issuance time based on the authenticated credential.
The entityType claim in the IPC reflects the _current_ executing
entity, not the root. Verifiers determine root type via deployment-
specific policy (e.g., convention that email-format identifiers are
HUMAN, or a local principal registry lookup).
Root type enforcement is a policy decision applied after the
verification algorithm (Section 3.2) completes. It is not encoded in
the verification algorithm because the IPC does not carry the root
entity's type - only the current entity's type (entityType).
Enforcement points that require root-type validation MUST resolve the
root identity's type through external policy.
5.3. Expiry Attenuation
Expiry attenuation applies at IPC *creation* time, not during re-
signing.
When a new IPC is created as a result of sub-delegation (e.g.,
Agent-1 delegates to Sub-Agent-1, and the platform creates a new IPC
for the sub-agent's request):
child.expiresAt <= parent.expiresAt
A child IPC MUST NOT have a longer lifetime than the parent
delegation that authorized it. This ensures authority shrinks over
time, never grows.
This rule does NOT apply during re-signing (Section 3.3). Re-signing
preserves the original expiresAt unchanged - the immutability rule
(Section 3.4) prevents any modification of expiresAt during re-
signing.
Security note: Expiry attenuation is enforced by the IPC Creator at
issuance time. Downstream services cannot independently verify that
attenuation was correctly applied. A compromised or misconfigured
IPC Creator could issue child IPCs with longer lifetimes than their
parent delegation. The maxTokenAge check (verification Step 8f)
provides a deployment-wide hard cap independent of attenuation.
5.4. Circular Detection
If any identifier appears more than once in the delegationChain, the
IPC MUST be rejected. This prevents circular delegation.
Sharma Expires 24 January 2027 [Page 36]
Internet-Draft Identity Propagation Context July 2026
5.5. Cascade Revocation
When a parent entity is revoked:
1. A revocation event is published (e.g., via event-streaming
topic).
2. All enforcement points receiving IPCs where the revoked entity
appears in the delegationChain MUST reject the IPC as specified
by the revocation scope rules in Section 5.5.1.
3. Additionally, IPCs naturally expire within their short TTL,
providing a secondary bound on exposure.
5.5.1. Revocation Event Format
The revocation event is a JSON object published to a well-known topic
(e.g., ipc-revocation):
{
"version": "1.0",
"eventType": "entity.revoked",
"eventId": "evt-0191b2c3-d4e5-7f6a-8b9c-0d1e2f3a4b5c",
"entityId": "energy-optimizer",
"revokedAt": "2026-07-17T08:02:30Z",
"reason": "compromised",
"scope": "cascade",
"issuedBy": "platform-admin",
"alg": "EdDSA",
"kid": "platform-admin/key-1",
"signature": "Base64url(...)"
}
Field definitions:
+===========+========+===============+============================+
| Field | Type | Required | Description |
+===========+========+===============+============================+
| version | string | REQUIRED | Revocation event schema |
| | | | version (e.g., "1.0"). |
| | | | Major/minor semantics per |
| | | | Section 2.2 versioning |
| | | | rules. Receivers MUST |
| | | | reject events with an |
| | | | unsupported major version. |
+-----------+--------+---------------+----------------------------+
| eventType | string | REQUIRED | MUST be "entity.revoked" |
+-----------+--------+---------------+----------------------------+
| eventId | string | REQUIRED | Unique event identifier |
| | | | (UUID v7 RECOMMENDED) |
Sharma Expires 24 January 2027 [Page 37]
Internet-Draft Identity Propagation Context July 2026
+-----------+--------+---------------+----------------------------+
| entityId | string | REQUIRED | Identifier of the revoked |
| | | | entity |
+-----------+--------+---------------+----------------------------+
| revokedAt | string | REQUIRED | ISO 8601 UTC timestamp of |
| | | | revocation |
+-----------+--------+---------------+----------------------------+
| reason | string | REQUIRED | One of: "compromised", |
| | | | "policy_violation", |
| | | | "operator_request", |
| | | | "expired", "rotation" |
+-----------+--------+---------------+----------------------------+
| scope | string | REQUIRED | "cascade" or "single" |
+-----------+--------+---------------+----------------------------+
| issuedBy | string | REQUIRED | Identifier of the revoking |
| | | | authority |
+-----------+--------+---------------+----------------------------+
| alg | string | REQUIRED | Signing algorithm |
| | | (production) | identifier ("EdDSA" or |
| | | | "ES256"). Enables |
| | | | algorithm-agnostic |
| | | | verification. |
+-----------+--------+---------------+----------------------------+
| kid | string | REQUIRED | Key identifier for the |
| | | (production) | revoking authority's |
| | | | signing key. Enables key |
| | | | selection during rotation. |
+-----------+--------+---------------+----------------------------+
| signature | string | REQUIRED | Signature over all other |
| | | (production), | fields (JCS-canonical, |
| | | OPTIONAL | excluding signature |
| | | (development) | itself) using the |
| | | | algorithm specified in |
| | | | alg. |
+-----------+--------+---------------+----------------------------+
Table 3
Revocation event signing keys are discovered via the same key
discovery mechanism as IPC signing keys (Section 3.6). The issuedBy
field corresponds to the serviceId in the key discovery endpoint. If
no key discovery endpoint is available for the revoking authority,
signature verification is deployment-specific.
Processing rules:
Sharma Expires 24 January 2027 [Page 38]
Internet-Draft Identity Propagation Context July 2026
* When scope is cascade, enforcement points MUST reject any IPC
where the revoked entityId appears anywhere in the
delegationChain.
* When scope is single, only IPCs where the revoked entity is the
entityId (current executor) are rejected.
* Enforcement points SHOULD verify the signature before acting on
the event. Enforcement points operating in production MUST reject
revocation events without a valid signature unless the event
source is authenticated by the transport layer (e.g., mTLS-
authenticated event producer). In development environments,
unsigned revocation events MAY be accepted with a logged warning.
* Duplicate eventId values MUST be ignored (idempotent processing).
Enforcement points MUST maintain deduplication state for eventId
values for at least 24 hours after first receipt. Revocation
events with revokedAt timestamps older than 24 hours from the
current time SHOULD be rejected as stale, preventing replay of old
revocation events. Deployments requiring a different
deduplication window MUST document their chosen value and ensure
it exceeds the maximum propagation delay in their event
infrastructure.
* Enforcement points MUST NOT remove revocation state until the
entity's maximum IPC TTL has elapsed after revokedAt.
Enforcement points SHOULD garbage-collect revocation state entries
whose revokedAt timestamp is older than the maximum configured IPC
TTL. Once all IPCs that could reference a revoked entity have
expired, the revocation entry serves no enforcement purpose and MAY
be removed from the active revocation set (while retaining it in
audit logs).
Guidance on scope selection: - Use cascade when the entity is
compromised or its key material may be leaked - all downstream
authority derived from this entity is suspect. - Use single when the
entity's current execution should be stopped but its prior
delegations remain trustworthy (e.g., an agent that completed its
task and should not accept new requests, but its sub-agents are still
valid). With single, the entity MAY still appear as an intermediate
in other IPCs' delegationChain without causing rejection.
5.5.2. Propagation Guarantees
This specification does not mandate a specific propagation latency.
However, implementations SHOULD target sub-5-second propagation to
minimize the window of exposure. The short IPC TTL (RECOMMENDED
default: <= 5 minutes; deployment-configurable) provides a hard upper
bound on exposure regardless of revocation propagation timing.
Sharma Expires 24 January 2027 [Page 39]
Internet-Draft Identity Propagation Context July 2026
5.5.3. Partition Tolerance
During network partitions where revocation events cannot be
delivered, enforcement points MUST continue to validate IPC expiry
(expiresAt). The short TTL ensures that even without revocation
delivery, compromised IPCs expire naturally within the configured
window.
5.5.4. Revocation Checking Interface
Enforcement points that support revocation MUST implement one of the
following revocation checking mechanisms:
*Option A: Event-Driven (Push)* - Subscribe to the ipc-revocation
topic (or equivalent event stream) - Maintain a local revocation set
in memory or shared cache - Check every IPC's delegationChain against
the local revocation set - Reject if any entity in the chain appears
in the revocation set
*Option B: Polling (Pull)* - Query a revocation status endpoint: GET
/ipc/v1/revocation-status/{entityId} - Response: {"revoked": true/
false, "revokedAt": "...", "scope": "..."} - Cache responses for no
longer than the deployment's configured revocation cache TTL
(RECOMMENDED default: 30 seconds) - Check every IPC's delegationChain
against cached status
*Option C: Expiry-Only (No Infrastructure)* - If no revocation
infrastructure is deployed, enforcement points MUST rely solely on
IPC expiry (expiresAt) for revocation - This is acceptable only when
TTLs are short (RECOMMENDED default: <= 5 minutes) - Deployments
using this option MUST document the maximum exposure window in their
security assessment
The revocation checking mechanism is deployment-specific. This
specification does not mandate a single mechanism but requires that
deployments explicitly choose and document which option they use.
When a revocation check determines that an entity is revoked, the
enforcement point MUST reject the IPC with entity_revoked regardless
of other validity checks.
5.6. Configuration Parameters
This section defines the configuration parameters referenced
throughout this specification, with normative defaults and
constraints to ensure interoperability between independent
implementations.
Sharma Expires 24 January 2027 [Page 40]
Internet-Draft Identity Propagation Context July 2026
+==========================+========+==========+===========+===============+
|Parameter |Type |Default |Normative |Description |
| | | |Constraint | |
+==========================+========+==========+===========+===============+
|maxDepth |integer |5 |MUST be >= |Maximum |
| | | |1, MUST NOT|delegation |
| | | |exceed 10 |chain depth |
+--------------------------+--------+----------+-----------+---------------+
|maxTTL |duration|300s (5 |MUST be >= |Maximum IPC |
| | |min) |30s, MUST |lifetime |
| | | |NOT exceed | |
| | | |600s (10 | |
| | | |min) | |
+--------------------------+--------+----------+-----------+---------------+
|clockSkew |duration|30s |MUST be >= |Clock skew |
| | | |5s, MUST |tolerance for |
| | | |NOT exceed |temporal |
| | | |60s, MUST |checks. The |
| | | |be less |constraint |
| | | |than maxTTL|clockSkew < |
| | | | |maxTTL ensures |
| | | | |that the skew |
| | | | |tolerance does |
| | | | |not exceed the |
| | | | |token lifetime,|
| | | | |which would |
| | | | |undermine |
| | | | |short-TTL |
| | | | |replay |
| | | | |protection. |
+--------------------------+--------+----------+-----------+---------------+
|maxTokenAge |duration|0 |If > 0, |Maximum age |
| | |(disabled)|MUST be >= |from issuedAt |
| | | |maxTTL |(0 = disabled).|
| | | | |The constraint |
| | | | |maxTokenAge >= |
| | | | |maxTTL prevents|
| | | | |false |
| | | | |rejections: |
| | | | |since a token's|
| | | | |lifetime can be|
| | | | |up to maxTTL, |
| | | | |setting |
| | | | |maxTokenAge |
| | | | |below maxTTL |
| | | | |would cause |
| | | | |valid tokens to|
| | | | |be rejected |
Sharma Expires 24 January 2027 [Page 41]
Internet-Draft Identity Propagation Context July 2026
| | | | |before their |
| | | | |expiresAt. The|
| | | | |maxTokenAge |
| | | | |check provides |
| | | | |value as a |
| | | | |deployment-wide|
| | | | |hard cap when |
| | | | |verifiers and |
| | | | |creators have |
| | | | |different |
| | | | |maxTTL |
| | | | |configurations,|
| | | | |or as defense |
| | | | |against clock |
| | | | |manipulation at|
| | | | |the creator. |
+--------------------------+--------+----------+-----------+---------------+
|replayCacheTTL |duration|derived |MUST be >= |Minimum replay |
| | | |maxTTL + |cache entry |
| | | |clockSkew |lifetime |
+--------------------------+--------+----------+-----------+---------------+
|keyDiscoveryCacheTTL |duration|300s |MUST be >= |Key discovery |
| | | |30s, MUST |response cache |
| | | |NOT exceed |duration |
| | | |3600s | |
+--------------------------+--------+----------+-----------+---------------+
|allowUnsignedForAudit |boolean |false |N/A |Whether Trust |
| | | | |Level 1 IPCs |
| | | | |are accepted |
+--------------------------+--------+----------+-----------+---------------+
|allowHMAC |boolean |false |N/A |Whether HS256 |
| | | | |(HMAC-SHA-256) |
| | | | |is permitted |
+--------------------------+--------+----------+-----------+---------------+
|isTerminalEnforcementPoint|boolean |(required)|N/A |Whether this |
| | | | |service always |
| | | | |acts as |
| | | | |terminal |
| | | | |(true), never |
| | | | |terminal |
| | | | |(false). Dual-|
| | | | |role services |
| | | | |set false and |
| | | | |check audience |
| | | | |in application |
| | | | |logic |
| | | | |(Section 3.2 |
| | | | |Step 12). |
Sharma Expires 24 January 2027 [Page 42]
Internet-Draft Identity Propagation Context July 2026
+--------------------------+--------+----------+-----------+---------------+
|isEnforcementPoint |boolean |(required)|N/A |Whether this |
| | | | |service makes |
| | | | |authorization |
| | | | |decisions |
+--------------------------+--------+----------+-----------+---------------+
|serviceId |string |(required)|MUST |This service's |
| | | |conform to |IPC issuer |
| | | |identifier |identifier |
| | | |constraints| |
| | | |(Section | |
| | | |2.2) | |
+--------------------------+--------+----------+-----------+---------------+
Table 4
Configuration consistency constraints:
* If isTerminalEnforcementPoint is true, then isEnforcementPoint
MUST also be true. A terminal enforcement point is by definition
an enforcement point (it makes the final authorization decision).
Implementations MUST reject configurations where
isTerminalEnforcementPoint = true and isEnforcementPoint = false.
* If the service is configured as a Trust Boundary (i.e., it re-
signs IPCs per Section 3.3), allowHMAC MUST be false.
Implementations MUST reject configurations where a Trust Boundary
service has allowHMAC = true (Section 2.6).
Normative requirements:
* Implementations MUST use the default values specified above unless
explicitly overridden by deployment configuration.
* Implementations MUST reject configuration where clockSkew is
greater than or equal to maxTTL. A clock skew tolerance that
equals or exceeds the token lifetime effectively disables temporal
validity as a security control.
* Implementations MUST reject configuration where maxTTL exceeds 600
seconds (10 minutes). Deployments requiring longer lifetimes are
outside the threat model of this specification and MUST conduct a
dedicated security assessment documenting the increased replay and
revocation exposure windows.
* Implementations MUST reject configuration where maxDepth exceeds
10. Deeper chains indicate an architectural issue that should be
resolved by restructuring the service topology.
Sharma Expires 24 January 2027 [Page 43]
Internet-Draft Identity Propagation Context July 2026
* The replayCacheTTL MUST be at least maxTTL + clockSkew to ensure
replay detection covers the full validity window of any IPC.
Implementations SHOULD derive this automatically from the
configured maxTTL and clockSkew values rather than requiring
manual configuration.
* Two conformant implementations using default configuration values
MUST be able to interoperate without additional coordination.
6. Protocol Bindings
IPCs MUST be transmitted only over channels protected by TLS 1.2 or
later. Transmission of IPCs over unencrypted channels is a protocol
violation. This requirement applies to all protocol bindings defined
in this section.
Note on IETF Working Group scope: The HTTP binding (Section 6.1) is
the primary interoperability profile and falls within the scope of
IETF working groups focused on HTTP-based protocols (e.g., OAuth,
WIMSE). The gRPC (Section 6.2) and event-streaming (Section 6.3)
bindings address real deployment requirements in multi-protocol
platforms but may be considered for separate companion documents if
the adopting WG's charter is limited to HTTP. The IPC semantics
(format, verification algorithm, trust model) are protocol-agnostic;
only the transport encoding differs across bindings.
6.1. HTTP
The IPC is carried in the HTTP header:
Identity-Propagation-Context: <base64url-encoded IPC>
Note: The X- prefix is not used, per RFC 6648 which deprecates custom
header prefixes for new headers.
6.2. gRPC
The IPC is carried in gRPC metadata:
identity-propagation-context: <base64url-encoded IPC>
6.3. Event-Streaming (Kafka)
The IPC is carried in a record header:
Header key: identity-propagation-context
Header value: <base64url-encoded IPC>
Sharma Expires 24 January 2027 [Page 44]
Internet-Draft Identity Propagation Context July 2026
6.4. Protocol Transition Behavior
When a service receives a request via one protocol and emits via
another (e.g., HTTP to gRPC, or gRPC to Kafka), this SHOULD be
treated as a trust boundary unless the deployment's security model
explicitly exempts it. The service MUST:
1. Verify the incoming IPC using the inbound protocol's binding
2. Execute the full verification algorithm (Section 3.2)
3. Re-sign the IPC (Section 3.3)
4. Emit the re-signed IPC using the outbound protocol's binding
The verification and re-signing requirements apply regardless of the
protocol direction. A Kafka consumer that triggers an HTTP call to a
downstream service MUST verify the IPC from the Kafka record header
and propagate it in the HTTP Identity-Propagation-Context header.
Audience semantics apply at the terminal enforcement point regardless
of which protocol delivered the IPC.
IPC is a request-direction mechanism. Responses do not carry IPC.
Asynchronous callbacks or event-driven responses that initiate new
request chains require fresh IPC creation at the originating service.
6.5. Header Value ABNF
The Identity-Propagation-Context header value is defined by the
following ABNF [RFC5234]:
IPC-header-value = base64url-encoded-ipc
base64url-encoded-ipc = 1*4096base64url-char
base64url-char = ALPHA / DIGIT / "-" / "_"
; The decoded value is a JSON object conforming to the IPC
; schema defined in Section 2.1, serialized per Section 2.4.
The header field MUST contain exactly one Base64url-encoded IPC.
Multiple IPCs in a single header value are not permitted. If a
request contains multiple Identity-Propagation-Context headers, the
verifier MUST reject with malformed_ipc.
Base64url encoding MUST be used without padding (per RFC 4648
Section 5).
Sharma Expires 24 January 2027 [Page 45]
Internet-Draft Identity Propagation Context July 2026
6.6. Event-Streaming Retention Considerations
In event-streaming systems (e.g., Kafka) where records are retained
beyond the IPC's expiresAt, consumers processing historical records
will encounter expired IPCs. The following guidance applies:
* During real-time processing, temporal validity (Step 8) MUST be
enforced normally.
* During historical replay or reprocessing, enforcement points MAY
skip temporal validity checks (Step 8) while still validating
structural integrity and chain semantics. This mode MUST be
explicitly configured and MUST be limited to replay/audit
scenarios. Services operating in historical replay mode MUST NOT
create new IPCs (including fan-out IPCs) from records processed in
this mode, as doing so would circumvent expiry attenuation by
minting fresh tokens from expired authority.
* Alternatively, deployments MAY strip IPC from records at retention
boundaries and rely on audit logs for historical provenance.
Intermediate services that introduce queuing delays (e.g., message
broker consumers with processing backlogs) SHOULD verify temporal
validity before forwarding and SHOULD reject IPCs with remaining
lifetime shorter than the expected downstream processing time.
7. Trust Levels
+=======+==========+=====================+================+
| Level | Name | Description | Use Case |
+=======+==========+=====================+================+
| 1 | Unsigned | No signature, audit | Development, |
| | | trail only | logging |
+-------+----------+---------------------+----------------+
| 2 | Signed | HS256 or EdDSA | Authorization, |
| | | (Ed25519) signature | enforcement |
+-------+----------+---------------------+----------------+
| 3 | Reserved | Reserved for future | N/A |
| | | extension | |
+-------+----------+---------------------+----------------+
Table 5
Note: Trust Level 3 is reserved for future specification of attested
or countersigned IPCs (e.g., hardware-attested or multi-party
countersigned). This version of the specification defines only
Levels 1 and 2. Implementations MUST NOT use Level 3 until a future
revision defines its semantics. Verifiers implementing this version
of the specification MUST reject IPCs with trustLevel values other
than 1 or 2 (per Section 3.2, Step 4). A future version that defines
Sharma Expires 24 January 2027 [Page 46]
Internet-Draft Identity Propagation Context July 2026
Trust Level 3 semantics will require verifier upgrades; existing
verifiers will safely reject Level 3 IPCs rather than processing them
with undefined behavior.
For Trust Level 1 (unsigned) IPCs: - The alg claim MUST be set to the
string "none" - The kid claim MUST be absent or empty string - The
signature claim MUST be absent or empty string - All other claims
MUST be present and conform to Section 2.1 - Trust Level 1 IPCs MUST
NOT be used for authorization decisions (Section 8.3) and exist
solely for development, debugging, and audit trail purposes
8. Security Considerations
8.1. Replay Protection
IPCs SHOULD have short TTLs (RECOMMENDED default: <= 5 minutes;
deployments MUST configure a maximum TTL appropriate to their threat
model) to limit replay windows. The sessionId claim provides
request-level uniqueness.
Enforcement points MUST maintain a replay cache keyed by sessionId
for at least the deployment's maximum configured IPC TTL. If a
sessionId has been seen before within the cache window, the IPC MUST
be rejected with token_replayed.
The replay cache SHOULD be shared across all instances of the same
enforcement point (e.g., via Redis or equivalent shared store) in
horizontally-scaled deployments. A local in-process cache is
acceptable only for single-instance deployments.
Without a shared replay cache, same-service replay within the TTL
window is possible from a different instance. The short TTL and
audience binding provide partial mitigation. Deployments that cannot
deploy shared state MUST document this as an accepted risk.
For Trust Level 2 deployments, the combination of REQUIRED audience
and sessionId replay cache provides defense-in-depth against both
cross-service and same-service replay attacks.
Trust boundary services that also make enforcement decisions (i.e.,
services fulfilling both the Trust Boundary and Enforcement Point
conformance classes from Section 11.3) MUST also maintain a replay
cache. A pure pass-through trust boundary that only re-signs without
making authorization decisions MAY skip replay checking.
Each IPC creation produces a unique sessionId. When an entity sub-
delegates (creating a new IPC with an extended chain), the child IPC
receives its own unique sessionId. The parent IPC's sessionId and
Sharma Expires 24 January 2027 [Page 47]
Internet-Draft Identity Propagation Context July 2026
the child IPC's sessionId are independent values. Replay caches
operate per-IPC: they prevent the same IPC from being presented
twice, not multiple IPCs from the same original request.
For high-throughput deployments where a centralized replay cache
creates unacceptable latency or availability risk, implementations
MAY use probabilistic data structures (e.g., Bloom filters) as a
RECOMMENDED alternative. Probabilistic structures may produce false-
positive rejections but MUST NOT produce false negatives (missed
replays). Deployments using probabilistic replay detection MUST
document the expected false-positive rate in their operational
assessment.
Note on retries: IPC is single-use per enforcement point within the
replay cache window. If a request times out and the client retries
with the same IPC, the enforcement point will reject the retry as
token_replayed. Retry scenarios require fresh IPC creation at the
platform boundary. Deployments using automatic retry policies (HTTP
retry-after, gRPC retry, Kafka consumer rebalancing) MUST ensure that
retried requests obtain fresh IPCs from the IPC Creator, or MUST
configure intermediate trust boundaries to skip replay detection
(acceptable when they only re-sign without making authorization
decisions).
8.2. Key Compromise
If a signing key is compromised: 1. Rotate the key immediately. 2.
Publish revocation events for all IPCs signed by the compromised key.
3. Short TTL bounds the exposure window naturally.
8.3. Spoofing
An unsigned IPC (Trust Level 1) MUST NOT be used for enforcement
decisions. Only signed (Level 2+) IPCs may be used for
authorization.
8.4. Chain Forgery
Because the IPC payload is immutable (only signature changes at re-
signing), an attacker cannot inject entries into the delegation chain
without invalidating the signature.
8.5. Single-Signer Verification Model
IPC uses a "trust your immediate upstream" model. At any given hop,
only the most recent signer's signature is present - previous
signatures are replaced during re-signing. This means:
Sharma Expires 24 January 2027 [Page 48]
Internet-Draft Identity Propagation Context July 2026
* Service C can verify that Service B signed the IPC.
* Service C CANNOT cryptographically verify that Service A signed it
before B.
* Service C trusts that B performed proper verification before re-
signing.
This is a deliberate design choice that enables local verification
(each service only needs its upstream's public key, not a full chain
of keys). The tradeoff is that compromise of a single intermediate
service allows it to forge or modify IPCs for all downstream
services.
Mitigations: - Short TTLs limit the window of exploitation. -
Revocation events enable rapid response to compromised
intermediaries. - Audit logs at each trust boundary provide forensic
traceability even though the cryptographic proof is single-hop.
Important: IPC provides per-hop re-signing with transitive trust, not
end-to-end cryptographic proof of the full chain. Each trust
boundary verifies the upstream signature before re-signing, attesting
(implicitly, via its own signature) that it performed this
verification. This is analogous to TLS certificate chain validation
- each hop trusts its immediate upstream. A compromised intermediate
can fabricate or alter the chain for downstream services. IPC's
security model relies on all trust boundaries being platform-operated
and within a single administrative domain. Cross-domain propagation
where intermediate trust boundaries are not fully trusted is
explicitly out of scope (Section 1.6).
In fan-out scenarios (Section 2.2), an intermediate service acts as
both Trust Boundary and IPC Creator. Downstream services cannot
distinguish a legitimately fan-out-created IPC from one fabricated by
a compromised intermediate. This is an inherent limitation of the
single-trust-domain model: all IPC Creators and Trust Boundaries are
assumed to be platform-operated and trustworthy. Deployments SHOULD
monitor fan-out services with heightened scrutiny and SHOULD log all
IPC creation events for forensic analysis.
8.6. Size Considerations
IPC size grows linearly with delegation chain depth due to the
delegationChain array. Deployments MUST consider transport-level
limits:
* HTTP headers: Most proxies and servers limit individual header
values to 8,192 bytes. A delegation chain of depth 10 with
64-character entity identifiers produces an IPC of approximately
1,200 bytes (Base64url-encoded), well within limits.
Sharma Expires 24 January 2027 [Page 49]
Internet-Draft Identity Propagation Context July 2026
* gRPC metadata: Default maximum metadata size is 8 KB per entry.
* Kafka record headers: No protocol-level limit, but implementations
commonly limit total header size to 64 KB.
The base64url-encoded IPC (as transmitted in protocol bindings) MUST
NOT exceed 4096 bytes. Verifiers MUST reject encoded IPCs exceeding
this limit before JSON parsing, to prevent resource exhaustion via
oversized tokens. This limit accommodates delegation chains of depth
10 with 128-character identifiers and reasonable extension claims
while remaining well within HTTP header size constraints.
The configured maxDepth serves as the primary mitigation for IPC size
growth. Deployments SHOULD set maxDepth to the minimum value that
accommodates legitimate delegation patterns (RECOMMENDED: <= 5 for
most deployments).
8.7. Threat Model
IPC identifies the following threat categories:
+===+============================+==================================+
|ID |Threat | Mitigation |
+===+============================+==================================+
|T1 |Token Replay | Short TTL (<= 5 min), |
| | | sessionId uniqueness, TLS-only |
| | | transport |
+---+----------------------------+----------------------------------+
|T2 |Key Compromise at Trust | Key rotation (Section 8.8), |
| |Boundary | short TTL limits exposure, |
| | | revocation events |
+---+----------------------------+----------------------------------+
|T3 |Delegation Chain Injection | Signature covers all claims; |
| | | payload immutable during re- |
| | | sign |
+---+----------------------------+----------------------------------+
|T4 |Circular Delegation | Explicit duplicate detection |
| | | in delegationChain |
| | | (Section 5.4) |
+---+----------------------------+----------------------------------+
|T5 |Depth Escalation | Configurable maxDepth |
| | | enforcement at every trust |
| | | boundary |
+---+----------------------------+----------------------------------+
|T6 |Revocation Delay | Dual-layer: event-streaming |
| | | (sub-5s target) + short TTL |
| | | hard bound |
+---+----------------------------+----------------------------------+
|T7 |Cross-Service Replay | Audience claim binding; |
Sharma Expires 24 January 2027 [Page 50]
Internet-Draft Identity Propagation Context July 2026
| | | REQUIRED for Trust Level 2+ |
+---+----------------------------+----------------------------------+
|T8 |Intermediate Service | Single-signer model tradeoff |
| |Compromise | (Section 8.5); mitigated by |
| | | short TTL + revocation |
+---+----------------------------+----------------------------------+
|T9 |IPC Stripping | Fail-closed enforcement |
| | | (Section 3.9); requests |
| | | without IPC are rejected |
+---+----------------------------+----------------------------------+
|T10|Downgrade to Trust Level 1 | Enforcement points MUST reject |
| | | unsigned IPCs (Section 8.10) |
+---+----------------------------+----------------------------------+
|T11|Clock Skew Exploitation | Clock synchronization |
| | | requirements (Section 8.9) |
+---+----------------------------+----------------------------------+
|T12|Denial of Service via Large | Token size limits |
| |Chains | (Section 8.6); maxDepth |
| | | enforcement |
+---+----------------------------+----------------------------------+
|T13|Confused Deputy at Trust | Trust boundaries MUST verify |
| |Boundary | that the presenting service |
| | | identity (mTLS cert, service |
| | | account) matches the expected |
| | | upstream for the IPC's issuer. |
| | | Reject if mismatch. |
+---+----------------------------+----------------------------------+
|T14|Compromised IPC Creator | IPC Creator requires highest |
| | | security posture: HSM- |
| | | protected signing keys, |
| | | restricted access, audit |
| | | logging of all creation |
| | | events, maxTokenAge provides |
| | | deployment-wide hard cap |
+---+----------------------------+----------------------------------+
|T15|Token theft from memory/logs| Short TTLs limit replay |
| | | window; TLS prevents network |
| | | interception; deployments |
| | | SHOULD sanitize IPC values |
| | | from application logs; |
| | | enforcement points SHOULD NOT |
| | | log full IPC header values |
+---+----------------------------+----------------------------------+
|T16|Colluding IPC Creator and | A compromised Creator can |
| |Intermediate | fabricate chains; a colluding |
| | | intermediate can re-sign |
| | | without verifying. Combined, |
| | | they can produce back-dated |
Sharma Expires 24 January 2027 [Page 51]
Internet-Draft Identity Propagation Context July 2026
| | | IPCs with arbitrary chains |
| | | that pass downstream |
| | | verification. Mitigation: IPC |
| | | Creators and Trust Boundaries |
| | | are assumed platform-operated |
| | | (Section 1.6); HSM-protected |
| | | keys at Creators (T14); |
| | | maxTokenAge caps temporal |
| | | exploitation; audit logging |
| | | (Section 3.8) provides |
| | | forensic detection. This |
| | | threat is inherent to the |
| | | single-trust-domain model. |
+---+----------------------------+----------------------------------+
|T17|Time-of-Check-to-Time-of-Use| Between VERIFY-IPC returning |
| |(TOCTOU) | ACCEPT and application code |
| | | using the claims for |
| | | authorization, semantic state |
| | | may change (e.g., entity |
| | | revoked, permissions altered). |
| | | Mitigation: short TTLs (≤ 5 |
| | | min) bound the window; |
| | | applications performing |
| | | asynchronous or deferred |
| | | processing SHOULD re-verify |
| | | temporal validity at point-of- |
| | | use; revocation checking (Step |
| | | 13) provides near-real-time |
| | | state when infrastructure is |
| | | deployed. |
+---+----------------------------+----------------------------------+
|T18|Replay Cache Race Condition | In horizontally-scaled |
| | | enforcement points, two |
| | | requests with the same |
| | | sessionId may arrive at |
| | | different instances |
| | | simultaneously, both passing |
| | | the replay cache check before |
| | | either writes. Mitigation: |
| | | the race window is bounded by |
| | | cache write propagation delay |
| | | (typically < 10ms for Redis); |
| | | audience binding prevents |
| | | cross-service exploitation; |
| | | shared cache with atomic |
| | | check-and-set operations |
| | | (e.g., Redis SETNX) eliminates |
| | | the window entirely. |
Sharma Expires 24 January 2027 [Page 52]
Internet-Draft Identity Propagation Context July 2026
| | | Deployments SHOULD use atomic |
| | | cache operations for replay |
| | | detection. |
+---+----------------------------+----------------------------------+
|T19|Compromised Key Discovery | An attacker who can serve |
| |Endpoint | forged key material at /.well- |
| | | known/ipc-keys can inject |
| | | arbitrary public keys, |
| | | enabling full IPC forgery for |
| | | any claimed issuer. This is |
| | | distinct from T2 (key |
| | | compromise) because no |
| | | legitimate key is stolen — |
| | | arbitrary keys are injected. |
| | | Mitigations: serve key |
| | | discovery endpoints over mTLS |
| | | with client certificate |
| | | validation restricting access |
| | | to known platform services; |
| | | implement key pinning where |
| | | verifiers reject new keys that |
| | | differ from previously-seen |
| | | keys for the same issuer |
| | | unless a rotation event is |
| | | expected; monitor for |
| | | unexpected key changes via |
| | | audit logging; key discovery |
| | | endpoints MUST be served over |
| | | HTTPS only; deployments SHOULD |
| | | restrict access to the |
| | | platform's internal network. |
+---+----------------------------+----------------------------------+
|T20|Cross-Cluster Replay | In deployments where a logical |
| | | service (same audience value) |
| | | spans multiple clusters with |
| | | independent replay caches, an |
| | | attacker can replay the same |
| | | IPC at both clusters within |
| | | the TTL window. The audience |
| | | binding provides no protection |
| | | because the replayed IPC |
| | | targets the same audience. |
| | | Mitigations: use a shared |
| | | cross-cluster replay cache |
| | | (e.g., globally-replicated |
| | | Redis); reduce IPC TTL to |
| | | minimize the exploitation |
| | | window; deploy cluster-scoped |
Sharma Expires 24 January 2027 [Page 53]
Internet-Draft Identity Propagation Context July 2026
| | | audience identifiers (e.g., |
| | | backend.cluster-a.example.com) |
| | | when strict replay prevention |
| | | is required across clusters. |
| | | Deployments that cannot share |
| | | replay state across clusters |
| | | MUST document this as an |
| | | accepted risk with the |
| | | exposure window bounded by |
| | | maxTTL. |
+---+----------------------------+----------------------------------+
|T21|Compromised Service Mesh | In sidecar deployments |
| |Sidecar | (Appendix D), the sidecar |
| | | proxy holds IPC signing keys |
| | | and shares the pod network |
| | | namespace with the application |
| | | container. A compromised |
| | | sidecar (e.g., via container |
| | | escape, supply chain attack on |
| | | sidecar image, or control |
| | | plane compromise) can forge or |
| | | modify IPCs for all requests |
| | | transiting that pod. This is |
| | | a specialization of T8 |
| | | (intermediate compromise) with |
| | | a distinct attack surface: |
| | | sidecars are often pulled from |
| | | third-party registries, key |
| | | material is injected via mesh |
| | | control plane, and the shared |
| | | network namespace enables |
| | | request interception without |
| | | network-level detection. |
| | | Mitigations: verify sidecar |
| | | image signatures and |
| | | provenance; restrict signing |
| | | key access to the sidecar |
| | | process only (not the |
| | | application container); |
| | | monitor for unexpected IPC |
| | | creation patterns from sidecar |
| | | instances; use pod security |
| | | policies to prevent container |
| | | escapes. Note that HSM- |
| | | protected signing keys (T14 |
| | | mitigation) are generally |
| | | impractical for sidecar |
| | | deployments due to scale and |
Sharma Expires 24 January 2027 [Page 54]
Internet-Draft Identity Propagation Context July 2026
| | | ephemeral pod lifecycle. |
+---+----------------------------+----------------------------------+
Table 6
8.8. Key Rotation Procedure
When a trust boundary service rotates its signing key:
1. Generate a new Ed25519 keypair.
2. Publish the new public key at the key discovery endpoint
(Section 3.6) with status: "active" and validFrom set to the
current time. The old key remains status: "active" during the
transition.
3. Wait at least cacheMaxAge (from the key discovery response, or
the deployment's configured keyDiscoveryCacheTTL) to ensure all
downstream verifiers have fetched the new key.
4. Begin signing new IPCs with the new key. The old key is no
longer used for signing but remains accepted for verification.
5. Update the old key's status to "retired" and set validUntil to
the current time.
6. Downstream services MUST continue accepting IPCs signed by the
retired key until validUntil plus the maximum configured IPC TTL
(maxTTL) plus clockSkew has elapsed.
During the rotation window (up to the cache TTL), downstream services
MAY receive IPCs signed by either the old or new key. Services MUST
accept both until the old key's validUntil plus the maximum
configured IPC TTL (Section 5.6 maxTTL) has elapsed.
Key rotation MUST NOT require coordination with upstream or
downstream services beyond the key discovery endpoint. This enables
rolling restarts and zero-downtime key rotation.
If a key is suspected compromised:
1. Set the key status to "compromised" at the discovery endpoint.
2. Publish a revocation event with reason: "rotation" for any IPCs
that may have been signed by the compromised key.
3. Generate and publish a new key immediately.
4. Downstream services MUST reject IPCs signed by a compromised key
regardless of their expiry time.
8.9. Clock Synchronization
IPC's temporal validity checks (issuedAt, expiresAt) require
synchronized clocks across trust boundary services. The following
requirements apply:
Sharma Expires 24 January 2027 [Page 55]
Internet-Draft Identity Propagation Context July 2026
* All services participating in IPC verification MUST synchronize
their clocks using NTP [RFC 5905] or an equivalent time
synchronization protocol.
* Clock skew between any two adjacent trust boundary services SHOULD
NOT exceed the configured clock skew tolerance.
* Verification implementations MUST apply a configurable clock skew
tolerance (RECOMMENDED default: 30 seconds) when checking issuedAt
and expiresAt. Deployments with tighter synchronization
guarantees MAY use a lower tolerance.
* If a deployment cannot guarantee clock synchronization within the
configured tolerance, it MUST increase the tolerance accordingly
and MUST document the increased tolerance as a security risk.
* Services MUST NOT issue IPCs with issuedAt derived from an
unsynchronized clock. If NTP synchronization is lost, the service
SHOULD reject incoming requests rather than issuing IPCs with
unreliable timestamps.
Note: An IPC verified as valid at one trust boundary may expire
before reaching the next service (in-flight expiry). The clock skew
tolerance (RECOMMENDED default: 30 seconds) is designed to
accommodate this scenario for normal request propagation latency.
Deployments with unusually high inter-service latency (> 10 seconds)
SHOULD increase their clock skew tolerance or reduce their IPC TTL to
compensate.
8.10. Downgrade Attack Prevention
An attacker may attempt to downgrade IPC security by:
1. *Stripping the IPC header entirely*: Mitigated by fail-closed
enforcement (Section 3.9). Enforcement points MUST reject
requests without IPC in production.
2. *Replacing a signed IPC with an unsigned one (Trust Level 1)*:
Enforcement points MUST reject Trust Level 1 IPCs for
authorization decisions (Section 8.3). A service configured for
Trust Level 2 enforcement MUST NOT accept Trust Level 1 IPCs.
3. *Replaying an expired IPC from a weaker configuration*: Temporal
validity checks reject expired IPCs regardless of other claims.
4. *Presenting an IPC signed by an unknown issuer*: Services MUST
verify the IPC was signed by a known upstream issuer. Unknown
issuers MUST be rejected with signature_invalid.
5. *Forcing fallback to permissive mode*: Permissive mode
(Section 3.8) MUST be a temporary deployment configuration.
Implementations SHOULD support a deployment-wide flag that
Sharma Expires 24 January 2027 [Page 56]
Internet-Draft Identity Propagation Context July 2026
disables permissive mode entirely and SHOULD alert operators if
permissive mode remains enabled beyond a configured duration
(RECOMMENDED: 7 days maximum).
8.11. Denial of Service Considerations
IPC introduces the following DoS attack surfaces:
* *Verification cost*: Ed25519 signature verification is
computationally inexpensive (~50 microseconds). An attacker
sending invalid IPCs imposes minimal CPU cost per request. Rate
limiting at the transport layer (e.g., connection limits) is the
primary mitigation.
* *Key discovery amplification*: An attacker presenting IPCs with
many distinct issuer values could trigger key discovery endpoint
lookups. Mitigations: cache resolved keys (max 300s), reject
unknown issuers immediately, rate-limit key discovery requests.
* *Revocation event flooding*: An attacker with revocation authority
could flood enforcement points with revocation events.
Mitigations: authenticate revocation event sources (signature
verification), deduplicate by eventId, rate-limit revocation
submissions.
* *Large delegation chains*: Token size grows with chain depth.
Mitigations: maxDepth enforcement (RECOMMENDED <= 5), transport-
layer header size limits provide a natural cap.
8.12. Proof-of-Possession
IPC does not include a proof-of-possession mechanism binding the IPC
to the presenting entity. Possession of a valid IPC header value is
sufficient to present it. This is a deliberate design choice that
enables transparent propagation through middleware and sidecars
without requiring per-hop proof construction.
This is mitigated by: 1. Short TTLs limiting the replay window 2.
The audience claim preventing cross-service use 3. The replay cache
preventing same-service reuse 4. TLS preventing passive interception
5. The coexisting bearer token providing PoP when DPoP or mTLS is
used at the transport layer
Deployments requiring stronger binding between IPC and the presenting
entity SHOULD use mTLS at the transport layer, which
cryptographically binds each request to the presenting service's
certificate.
Sharma Expires 24 January 2027 [Page 57]
Internet-Draft Identity Propagation Context July 2026
8.13. Bearer Token and IPC Binding
IPC travels alongside the OAuth 2.0 bearer token (Section 1.7) but is
not cryptographically bound to it. An attacker who obtains both a
valid bearer token for Entity A and a valid IPC for Entity B could
present them together, creating a mismatch between transport-level
authentication and identity-chain claims.
Enforcement points MUST verify that the authenticated identity
established by the bearer token (e.g., the token's sub, azp, or
client_id claim) is consistent with the IPC's issuer field or
identifies a known trust boundary in the deployment's topology. If
the bearer token identifies an entity that is not a legitimate
upstream issuer for the presented IPC, the enforcement point MUST
reject the request. The RECOMMENDED binding verification procedure
is:
1. Extract the azp (authorized party) claim from the bearer token.
If azp is absent, fall back to client_id.
2. Compare the extracted value against the IPC's issuer field.
3. If the values match, binding is confirmed.
4. If the values do not match, check whether the bearer token's
subject identifies a known trust boundary service in the
deployment's topology (e.g., via a configured allowlist of trust
boundary identifiers).
5. If neither check succeeds, REJECT the request.
Deployments that use a different bearer token claim for binding
verification (e.g., a custom service_id claim) MUST document the
specific claim used and the comparison semantics in their
deployment's security architecture. Two implementations within the
same deployment MUST use the same binding claim to ensure consistent
enforcement.
When the enforcement point cannot determine consistency (e.g., bearer
token lacks identifying claims, or the mapping between bearer token
subjects and IPC issuers is unavailable), it SHOULD log a warning and
MAY proceed based on deployment policy. Deployments operating in
this degraded mode MUST document the accepted risk.
In multi-hop chains, each intermediate service presents its own
bearer token (or mTLS identity) when calling the next service
downstream. The binding verification at each hop compares the
immediate caller's transport-level identity against the IPC's current
issuer field (which was set by the re-signing service at the previous
hop). This means binding verification is always between the direct
caller and the IPC's issuer — not between the original client and the
IPC creator.
Sharma Expires 24 January 2027 [Page 58]
Internet-Draft Identity Propagation Context July 2026
For opaque bearer tokens (where claims are not directly available),
enforcement points MUST use token introspection (RFC 7662) to obtain
the client_id or equivalent identifier for binding verification, or
rely on transport-level identity (mTLS) instead.
Deployments using mTLS or DPoP [RFC 9449] at the transport layer gain
stronger implicit binding: the transport-level identity is
cryptographically proven and SHOULD be compared against the IPC's
issuer to detect token-swapping attacks. When mTLS or DPoP [RFC
9449] is available, enforcement points MUST use the transport-level
identity for binding verification rather than relying solely on
bearer token claims.
9. Privacy Considerations
IPCs contain identity information (entity IDs, delegation chains)
that reveals organizational structure, delegation relationships, and
operational patterns. The following privacy requirements apply:
9.1. Transport Protection
IPCs MUST only be transmitted over encrypted channels (TLS).
Unencrypted transmission exposes the full delegation chain to passive
observers.
9.2. Delegation Chain as Sensitive Metadata
The delegationChain array reveals: - Organizational hierarchy (who
delegates to whom) - Service naming conventions (internal service
identifiers) - Operational patterns (which agents are used for which
tasks) - Delegation depth as a proxy for system complexity
Deployments SHOULD consider using opaque or pseudonymous identifiers
rather than human-readable names in delegationChain entries when IPCs
may be exposed beyond the immediate trust domain (e.g., captured in
shared logging infrastructure, debugging tools, or error responses).
When opaque identifiers are used, a mapping to human-readable names
MUST be maintained by the platform operator for audit purposes but
SHOULD NOT be distributed to all services in the chain.
9.3. Logging and Retention
Section 3.8 requires normative audit logging of IPC verification
events. Deployments MUST establish retention policies for IPC audit
logs that balance forensic traceability against data minimization:
Sharma Expires 24 January 2027 [Page 59]
Internet-Draft Identity Propagation Context July 2026
* Audit logs SHOULD retain sessionId, entityId, verification result,
and timestamp — not the full IPC payload.
* Full IPC payloads (including delegationChain) MUST NOT be logged
unless required for active security investigation.
* Log retention periods SHOULD be defined by deployment policy and
communicated to affected parties per applicable data protection
regulations.
9.4. Data Minimization
Deployments SHOULD minimize the identity information included in IPCs
based on the principle of data minimization:
* Entity identifiers SHOULD NOT contain personally identifiable
information (PII) beyond what is necessary for enforcement
decisions.
* The delegationChain carries the minimum information needed for
cascade revocation and depth enforcement. Deployments that do not
require these features at enforcement points MAY truncate the
chain to include only the root and current entity (reducing
metadata exposure) while documenting the loss of cascade
revocation capability.
9.5. Correlation Risks
The sessionId enables correlation of a single request across multiple
services. Deployments MUST NOT use sessionId for cross-request user
tracking. The RECOMMENDED use of UUID v7 (which contains a timestamp
component) means that sessionId values reveal approximate creation
time even without access to the issuedAt claim.
As noted in Section 2.1, using the same value for sessionId and
externally-visible trace identifiers (e.g., W3C Trace Context) is NOT
RECOMMENDED when trace context propagates beyond the trust domain
boundary.
10. IANA Considerations
10.1. Header Registration
Registration request for a new HTTP header field:
* Header Field Name: Identity-Propagation-Context
* Applicable Protocol: HTTP
* Status: Standard
* Structured Type: N/A (opaque base64url-encoded value; not a
Structured Field per RFC 8941)
* Specification Document: This document, Section 6.1
Sharma Expires 24 January 2027 [Page 60]
Internet-Draft Identity Propagation Context July 2026
Note: gRPC metadata keys and Kafka record header keys do not have
IANA registries. The metadata key identity-propagation-context
(Section 6.2) and Kafka record header key identity-propagation-
context (Section 6.3) are defined by this specification and SHOULD be
treated as reserved by implementations that support IPC.
10.2. Claims Registration
This specification defines the following claims for use in IPCs.
Should a future profile encode IPC as a JWT (RFC 7519), these claims
would be registered in the "JSON Web Token Claims" registry. For
this version, the claims are defined locally within this
specification.
+===============+=====================================+==========+=============+
|Claim Name |Description |Change |Specification|
| | |Controller| |
+===============+=====================================+==========+=============+
|entityId |Identity of executing entity |IESG |This |
| | | |document, |
| | | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
|entityType |Classification |IESG |This |
| |(AUTONOMOUS/SUPERVISED/UTILITY/HUMAN/| |document, |
| |SYSTEM) | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
|authorizedBy |Immediate delegating party |IESG |This |
| | | |document, |
| | | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
|delegationDepth|Hops from root |IESG |This |
| | | |document, |
| | | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
|delegationChain|Ordered provenance chain |IESG |This |
| | | |document, |
| | | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
|trustLevel |Signature assurance level: 1 |IESG |This |
| |(unsigned), 2 (signed), 3 (reserved) | |document, |
| | | |Section 2.1 |
+---------------+-------------------------------------+----------+-------------+
Table 7
Sharma Expires 24 January 2027 [Page 61]
Internet-Draft Identity Propagation Context July 2026
10.3. Well-Known URI Registration
Registration request for a new well-known URI suffix per RFC 8615:
* URI Suffix: ipc-keys
* Change Controller: IESG
* Specification Document: This document, Section 3.6
* Related Information: N/A
10.4. IPC Entity Type Registry
This specification establishes the "IPC Entity Type" registry under
the "Identity Propagation Context (IPC)" heading. The registration
policy is "Specification Required" per RFC 8126.
Initial registry contents:
+============+=========================+============+=============+
| Value | Description | Change | Reference |
| | | Controller | |
+============+=========================+============+=============+
| HUMAN | A natural person | IESG | This |
| | authenticated via an | | document, |
| | identity provider | | Section 2.1 |
+------------+-------------------------+------------+-------------+
| SYSTEM | Platform-initiated | IESG | This |
| | operation with no | | document, |
| | direct human trigger | | Section 2.1 |
+------------+-------------------------+------------+-------------+
| AUTONOMOUS | Agent operating | IESG | This |
| | independently on behalf | | document, |
| | of a human principal | | Section 2.1 |
+------------+-------------------------+------------+-------------+
| SUPERVISED | Agent requiring human | IESG | This |
| | approval for sensitive | | document, |
| | operations | | Section 2.1 |
+------------+-------------------------+------------+-------------+
| UTILITY | Stateless service | IESG | This |
| | component invoked by | | document, |
| | other entities | | Section 2.1 |
+------------+-------------------------+------------+-------------+
Table 8
Sharma Expires 24 January 2027 [Page 62]
Internet-Draft Identity Propagation Context July 2026
Registration requirements for new entity types: - Value MUST be an
uppercase ASCII string matching ^[A-Z][A-Z0-9_]{1,31}$ - A
specification document MUST define the semantics and intended use -
New values MUST NOT conflict semantically with existing registered
types
11. Relationship to Other Specifications
+================+=================================================+
| Specification | Relationship |
+================+=================================================+
| RFC 8693 | Complementary - used at first hop; IPC carries |
| (Token | identity through remaining chain |
| Exchange) | |
+----------------+-------------------------------------------------+
| Transaction | Complementary - Transaction Tokens carry |
| Tokens [I- | immutable authorization context (scope, |
| D.draft-ietf- | transaction details) through a call chain |
| oauth- | unchanged. IPC carries the mutable delegation |
| transaction- | chain identity with per-hop re-signing. Txn- |
| tokens] | Tokens answer "what is this transaction |
| | authorized to do?"; IPC answers "who initiated |
| | this request and through what delegation |
| | chain?" Both may coexist in the same request: |
| | the Txn-Token in the Txn-Token header and the |
| | IPC in the Identity-Propagation-Context header. |
+----------------+-------------------------------------------------+
| RFC 6750 | IPC extends bearer token concepts with |
| (Bearer | delegation chain and re-signing |
| Tokens) | |
+----------------+-------------------------------------------------+
| RFC 7519 (JWT) | IPC uses JSON with JCS (RFC 8785) for canonical |
| | serialization rather than JWT's JWS structure. |
| | JWT claim names are intentionally distinct to |
| | avoid semantic collision. |
+----------------+-------------------------------------------------+
| Agent Identity | Complementary - AIP requires the agent to |
| Protocol (AIP) | actively participate (generate keys, sign |
| [I-D.draft- | tokens); IPC requires nothing from the agent |
| singla-agent- | beyond a standard OAuth JWT. AIP is HTTP-only; |
| identity- | IPC adds gRPC and event-streaming bindings. |
| protocol] | |
+----------------+-------------------------------------------------+
| WIMSE AI Agent | Complementary - WIMSE defines agent identity |
| Identity [I- | bootstrapping and attestation; IPC defines how |
| D.draft-ni- | the resulting verified identity propagates |
| wimse-ai- | through service chains after credential |
| agent- | issuance. |
Sharma Expires 24 January 2027 [Page 63]
Internet-Draft Identity Propagation Context July 2026
| identity] | |
+----------------+-------------------------------------------------+
| AgentID | Shared principle - both require cryptographic |
| Protocol [I- | traceability to a human/organization root. IPC |
| D.draft- | adds per-hop re-signing and cross-protocol |
| gudlab- | propagation. |
| agentid- | |
| protocol] | |
+----------------+-------------------------------------------------+
| W3C Baggage | Complementary - Baggage for observability, IPC |
| | for enforcement |
+----------------+-------------------------------------------------+
| RFC 9449 | Complementary - DPoP provides proof-of- |
| (DPoP) | possession for OAuth tokens at the transport |
| | layer; IPC provides identity propagation |
| | through the service chain. When both are |
| | deployed, DPoP strengthens IPC-to-bearer-token |
| | binding (Section 8.13). |
+----------------+-------------------------------------------------+
| SPIFFE/SPIRE | Complementary - SPIFFE identifies workloads |
| | (pod-to-pod), IPC identifies the initiating |
| | entity and its delegation chain through those |
| | workloads |
+----------------+-------------------------------------------------+
| AI Agent | Complementary - klrc composes SPIFFE |
| Authentication | (identity), WIMSE (credential), and OAuth |
| Framework [I- | (authorization) into a layered agent auth |
| D.draft-klrc- | stack, using RFC 8693 token exchange for |
| aiagent-auth] | downstream delegation. IPC addresses klrc's |
| | "Delegation (downstream)" layer without per-hop |
| | STS interaction: after the agent authenticates |
| | and obtains delegated authority per klrc's |
| | model, IPC carries the verified delegation |
| | chain through multi-hop internal service calls. |
| | klrc's act claim is informational; IPC makes it |
| | enforceable with per-hop re-signing. |
+----------------+-------------------------------------------------+
| Google Cloud | Complementary (informative) - Google assigns |
| Agent Identity | per-agent SPIFFE identities with mTLS + DPoP |
| | credential binding, but does not specify |
| | delegation chain propagation through internal |
| | service hops. IPC fills this gap: after the |
| | agent authenticates with its SPIFFE credential |
| | at the platform boundary, IPC carries the full |
| | delegation chain through downstream services. |
+----------------+-------------------------------------------------+
Table 9
Sharma Expires 24 January 2027 [Page 64]
Internet-Draft Identity Propagation Context July 2026
11.1. Detailed Comparison with AIP
The Agent Identity Protocol (AIP) is the most comprehensive existing
specification for AI agent identity. IPC and AIP operate at
different architectural layers:
+===============+===================+===========================+
| Aspect | AIP | IPC |
+===============+===================+===========================+
| *Purpose* | Agent proves its | Platform carries verified |
| | identity to a | identity through its |
| | relying party | internal chain |
+---------------+-------------------+---------------------------+
| *Who creates | Agent self-issues | Platform trust boundary |
| the | Credential Tokens | creates IPC |
| artifact?* | | |
+---------------+-------------------+---------------------------+
| *Agent | Active - agent | None - agent is not aware |
| involvement* | implements the | of IPC |
| | protocol | |
+---------------+-------------------+---------------------------+
| *Re-signing | Not supported - | Re-signed at every trust |
| at hops* | agent-signed once | boundary |
+---------------+-------------------+---------------------------+
| *Protocol | HTTP only | HTTP, gRPC, Kafka |
| support* | (Bearer/DPoP) | |
+---------------+-------------------+---------------------------+
| *Verification | Registry lookup | Locally-verifiable - no |
| model* | | per-request STS calls |
+---------------+-------------------+---------------------------+
| *Registry | Required for Tier | No registry needed |
| dependency* | 2+ | |
+---------------+-------------------+---------------------------+
Table 10
Both support delegation chains, depth limits, expiry attenuation,
cascade revocation, and circular detection - confirming shared
problem understanding with different architectural solutions.
*When to use which:*
* Use *AIP* when the agent directly presents credentials to a
relying party and the relying party can verify against a registry.
* Use *IPC* when identity must propagate transparently through
platform infrastructure services that the agent does not directly
interact with, especially across protocol boundaries (HTTP -> gRPC
-> Kafka).
Sharma Expires 24 January 2027 [Page 65]
Internet-Draft Identity Propagation Context July 2026
* Use *both* when the agent authenticates at the platform boundary
using AIP, and the platform then propagates identity internally
using IPC.
11.2. Mapping to Authorization Propagation Requirements
Tallam [Tallam2026] formalizes "authorization propagation" as a
workflow-level property of multi-agent systems and derives seven
structural requirements (R1-R7) for any sufficient authorization
architecture. IPC addresses these requirements as follows:
Sharma Expires 24 January 2027 [Page 66]
Internet-Draft Identity Propagation Context July 2026
+=============+==================+===============================+
| Requirement | Description | IPC Coverage |
+=============+==================+===============================+
| R1 | Agent principals | [Full] entityId + entityType |
| | as first-class | - agents are named, typed |
| | authorization | principals |
| | subjects | |
+-------------+------------------+-------------------------------+
| R2 | Delegation | [Full] delegationChain + |
| | explicit, | authorizedBy + re-signing |
| | bounded, | proves each hop validated |
| | auditable | |
+-------------+------------------+-------------------------------+
| R3 | Authorization at | [Full] Re-signing at every |
| | every data | trust boundary; each service |
| | retrieval | independently verifies |
| | boundary | |
+-------------+------------------+-------------------------------+
| R4 | Aggregation | [Partial] IPC provides |
| | policies | identity trace; aggregation |
| | expressible and | logic is delegated to the |
| | enforceable | policy engine |
+-------------+------------------+-------------------------------+
| R5 | Authorization | [Full] IPC is a single, self- |
| | traces workflow- | contained artifact carrying |
| | scoped and self- | the full delegation chain, |
| | contained | inspectable at any hop |
+-------------+------------------+-------------------------------+
| R6 | Temporal | [Full] Configurable expiresAt |
| | validity as | + dual-layer revocation |
| | policy decision | (event-streaming + expiry) |
+-------------+------------------+-------------------------------+
| R7 | Recovery | [Full] sessionId + |
| | traceable | delegationChain enable |
| | through | identification of all |
| | synthesis graph | downstream results derived |
| | | from a specific authorization |
+-------------+------------------+-------------------------------+
Table 11
IPC does not claim to solve aggregation inference (R4) in the general
case - this is acknowledged as an open research problem. However,
IPC provides the prerequisite infrastructure: a self-contained, per-
hop verified identity trace that makes the set of contributing
sources inspectable after the fact, which is necessary for any
aggregation policy enforcement.
Sharma Expires 24 January 2027 [Page 67]
Internet-Draft Identity Propagation Context July 2026
11.3. Conformance Classes
This specification defines three conformance classes:
*IPC Creator* (e.g., API Gateway): - MUST create IPCs conforming to
the format in Section 2 - MUST sign with EdDSA (Ed25519) for multi-
hop deployments (Section 2.6) - MUST enforce expiry attenuation for
sub-delegated IPCs (Section 5.3) - MUST set audience for Trust Level
2 IPCs (Section 2.1) - MUST populate all REQUIRED claims - MUST
publish its own public key via the key discovery endpoint
(Section 3.6) - MUST support key discovery as a key publisher; SHOULD
support key discovery as a key consumer if it also verifies upstream
IPCs
*Trust Boundary* (e.g., intermediate service that re-signs): - MUST
execute the verification algorithm (Section 3.2) before re-signing -
MUST execute the re-signing algorithm (Section 3.3) - MUST NOT modify
any claims other than issuer, kid, and signature - MUST reject IPCs
that fail any verification step - MUST maintain upstream public keys
(via Section 3.6 or static config) - MUST publish its own public key
via the key discovery endpoint (Section 3.6) - MUST support key
discovery as both a key consumer (querying upstream endpoints) and a
key publisher (exposing own keys)
*Enforcement Point* (e.g., terminal service): - MUST execute the
verification algorithm (Section 3.2) - MUST enforce all applicable
rules from Section 5 - MUST check revocation state if revocation
infrastructure is deployed - MUST maintain a replay cache for
sessionId (Section 8.1) - MUST reject Trust Level 1 IPCs for
authorization decisions - MAY skip re-signing if it is the terminal
service in the chain
An implementation MAY fulfill multiple conformance classes
simultaneously (e.g., a service that both re-signs and makes
enforcement decisions).
Appendix A. Acknowledgements
The authors thank the reviewers who provided feedback on early drafts
of this specification.
Appendix B. References
B.1. Normative References
* [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", March 1997.
Sharma Expires 24 January 2027 [Page 68]
Internet-Draft Identity Propagation Context July 2026
* [RFC 4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", October 2006.
* [RFC 5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, January 2008.
* [RFC 5905] Mills, D., et al., "Network Time Protocol Version 4:
Protocol and Algorithms Specification", June 2010.
* [RFC 6648] Saint-Andre, P., et al., "Deprecating the 'X-' Prefix
and Similar Constructs in Application Protocols", June 2012.
* [RFC 6750] Jones, M., et al., "OAuth 2.0 Bearer Token Usage",
October 2012.
* [RFC 7519] Jones, M., et al., "JSON Web Token (JWT)", May 2015.
* [RFC 7518] Jones, M., "JSON Web Algorithms (JWA)", May 2015.
* [RFC 8037] Liusvaara, I., "CFRG Elliptic Curve Diffie-Hellman
(ECDH) and Signatures in JSON Object Signing and Encryption
(JOSE)", January 2017.
* [RFC 8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", May 2017.
* [RFC 8259] Bray, T., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, December 2017.
* [RFC 8615] Nottingham, M., "Well-Known Uniform Resource
Identifiers (URIs)", May 2019.
* [RFC 8693] Jones, M., et al., "OAuth 2.0 Token Exchange", January
2020.
* [RFC 8785] Rundgren, A., et al., "JSON Canonicalization Scheme
(JCS)", June 2020.
* [RFC 9110] Fielding, R., et al., "HTTP Semantics", June 2022.
B.2. Informative References
* [RFC 7515] Jones, M., et al., "JSON Web Signature (JWS)", May
2015.
* [RFC 7662] Richer, J., "OAuth 2.0 Token Introspection", October
2015.
* [RFC 6749] Hardt, D., "The OAuth 2.0 Authorization Framework",
October 2012.
* [RFC 8126] Cotton, M., et al., "Guidelines for Writing an IANA
Considerations Section in RFCs", June 2017.
* [RFC 9449] Fett, D., et al., "OAuth 2.0 Demonstrating Proof of
Possession (DPoP)", September 2023.
* [RFC 8610] Birkholz, H., et al., "Concise Data Definition Language
(CDDL): A Notational Convention to Express Concise Binary Object
Representation (CBOR) and JSON Data Structures", June 2019.
* [RFC 9562] Davis, K., et al., "Universally Unique IDentifiers
(UUIDs)", May 2024.
* [RFC 8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
Signature Algorithm (EdDSA)", January 2017.
* [RFC 8941] Nottingham, M. and P-H. Kamp, "Structured Field Values
for HTTP", February 2021.
Sharma Expires 24 January 2027 [Page 69]
Internet-Draft Identity Propagation Context July 2026
* [I-D.draft-singla-agent-identity-protocol] Singla, P., "Agent
Identity Protocol (AIP): Decentralized Identity and Delegation for
AI Agents", Work in Progress, Internet-Draft, draft-singla-agent-
identity-protocol-03, June 2026.
* [I-D.draft-ni-wimse-ai-agent-identity] Ni, Y. and C. P. Liu,
"WIMSE Applicability for AI Agents", Work in Progress, Internet-
Draft, draft-ni-wimse-ai-agent-identity-02, February 2026.
* [I-D.draft-gudlab-agentid-protocol] "AgentID Protocol", Work in
Progress, Internet-Draft.
* [I-D.draft-klrc-aiagent-auth] Kataria, L., et al., "AI Agent
Authentication and Authorization", Work in Progress, Internet-
Draft, draft-klrc-aiagent-auth-00, March 2026. Note:
Informational draft (Ping Identity, AWS, Zscaler, Defakto)
composing SPIFFE, WIMSE, OAuth, and OIDC for agent authentication.
Thesis: existing standards are sufficient for agent auth; no new
protocol needed.
* [I-D.draft-ietf-oauth-transaction-tokens] Tulshibagwale, A.,
Fletcher, G., and P. Kasselman, "Transaction Tokens", Work in
Progress, Internet-Draft, draft-ietf-oauth-transaction-tokens-09,
July 2026. Note: OAuth WG adopted draft (In WG Last Call)
defining short-lived, transaction-bound JWTs for propagating
immutable authorization context through call chains within a Trust
Domain.
* [GCP-Agent-Identity] Google Cloud, "Agent Identity overview",
https://cloud.google.com/iam/docs/agent-identity-overview
(https://cloud.google.com/iam/docs/agent-identity-overview), 2026.
* [Tallam2026] Tallam, K., "Authorization Propagation in Multi-Agent
AI Systems: Identity Governance as Infrastructure",
arXiv:2605.05440, May 2026. Note: This is an arXiv preprint that
has not undergone formal peer review. It is cited for its problem
formalization (R1-R7 requirements), not as a normative authority.
* [SPIFFE] CNCF, "Secure Production Identity Framework for Everyone"
* [W3C-Baggage] W3C, "Baggage Specification"
Author's Address
Ravi Kant Sharma
Ericsson
Ireland
Email: ravi.k.kant.sharma@ericsson.com
Sharma Expires 24 January 2027 [Page 70]