Skip to content

Separate workload identity, represented user, and delegated authority claims #568

Open

Description

@imran-siddique

Define separate cMCP claims for workload identity, represented user, token audience, proof-of-possession binding, and delegation reference. Map DPoP and token exchange without treating authentication as runtime attestation. Acceptance evidence: confused-deputy, token replay, audience mismatch, and identity/attestation mismatch tests.

Activity

  1. imran-siddique commented on Sep 7, 2026

    @imran-siddique
    MemberAuthor

    The next deliverable is the identity/authority claim boundary and the confused-deputy, replay, audience, and attestation-mismatch acceptance matrix. Keep this independent from #565’s action identity and #566’s catalog identity.

  2. athena-kanellatou commented on Sep 11, 2026

    @athena-kanellatou
    Contributor

    I traced the current identity path, and I think the cleanest first step is to define the identity/authority boundary and acceptance matrix before choosing a wire format.

    The runtime already has a workload identity path through agent_id, authenticated_subject, and subject_source. I would keep user/delegation authority separate from that rather than overloading authenticated_subject.

    A possible boundary is:

    1. workload identity — which agent/workload is making the request

    2. represented user — the principal the workload is acting for, when present

    3. token audience — the resource the authority is intended for

    4. proof-of-possession binding — the key binding associated with that authority, where applicable

    5. delegation reference — the evidence that carries authority from the represented principal to the workload

    6. runtime attestation — evidence about the executing workload/runtime, never inferred from authentication alone

    For the acceptance matrix, I would expect at least these cases:

    Valid workload identity + valid authority + consistent audience/bindings
    Expected: accept subject to policy

    Authority has the wrong audience
    Expected: refuse before upstream invocation

    Authority is presented outside its required PoP/workload/delegation binding
    Expected: refuse

    Delegated authority is replayed outside its valid scope or context
    Expected: refuse

    Represented-user or delegation evidence conflicts with the authenticated workload identity
    Expected: refuse rather than merge the identities

    Authentication succeeds but runtime attestation is absent or unverified
    Expected: authentication may still be valid, but no runtime-attestation claim

    No represented user is present
    Expected: do not synthesize one, instead evaluate authorization from workload authority and policy

    For conformance, I think each negative case should identify which boundary failed, rather than collapsing workload authentication, delegated authorization, PoP, and attestation into one generic identity error.

    I have intentionally not proposed field names or a token-exchange wire format yet, since those seem downstream of agreeing on the boundary.

    If this matches the intended direction, I’m happy to turn it into the concrete acceptance matrix/conformance cases first and implement the agreed claim representation separately.

  3. imran-siddique commented on Sep 11, 2026

    @imran-siddique
    MemberAuthor

    Yes to the direction, and yes to the split. Ruling the boundary so you can build against it rather than guess.

    The six-way boundary is adopted as you have it. Workload identity, represented user, token audience, proof-of-possession binding, delegation reference, runtime attestation. Keeping user and delegation authority off authenticated_subject is right: overloading it is how a system ends up unable to say whether it authenticated a workload or a person, and once merged those cannot be separated again after the fact.

    Runtime attestation stays outside the authentication set, permanently. Your line that it is "never inferred from authentication alone" is the one I would carve into the section heading. A valid token says a key was held. It says nothing about what code was executing, and a system that treats the first as evidence of the second is exactly the confused deputy this issue exists to prevent.

    Two rows in your matrix are the ones I would protect through any later revision, because both are cases where the tempting behaviour is to produce a value:

    • Authentication succeeds, runtime attestation absent or unverified: authentication stands, and there is no runtime-attestation claim. Not a weak claim, not a default, none.
    • No represented user present: do not synthesize one. Evaluate from workload authority and policy.

    Ruling on your last point, which is the most important one in the comment. Each negative case names which boundary failed. Collapsing workload authentication, delegated authorization, PoP and attestation into one generic identity error destroys the only information a relying party can act on: an audience mismatch and a missing attestation need different responses, and "identity error" supports neither. This is the same discipline as agentrust-io/trace-spec#279, where a verifier surface needs a first-class not-established value rather than folding absence into failure. Worth reading that before you name the failure codes, so we get one vocabulary across the repos rather than two.

    The split is right: acceptance matrix first, claim representation after. Field names and a token-exchange wire format are downstream of the boundary, and deciding them first is how a boundary gets bent to fit a format. Build the matrix and the conformance cases; I will rule on those before anything is implemented.

    Tracing the current identity path before proposing anything is why this is a design comment rather than a wish. agent_id, authenticated_subject and subject_source are indeed the whole of the existing workload path.

  4. athena-kanellatou commented on Sep 11, 2026

    @athena-kanellatou
    Contributor

    Following the boundary ruling, I reduced this to the acceptance cases needed before we choose claim fields or token-exchange representation.

    I am using the #279 discipline here: where evidence is absent or cannot be established, that remains distinct from a verified contradiction. The descriptions below are dispositions, not proposed wire values or final failure-code names.

    ID Case Boundary Expected verifier disposition
    IA-001 Workload authentication succeeds; applicable delegated authority, audience, and PoP bindings are valid and mutually consistent all applicable authority boundaries Continue to policy evaluation. No boundary result alone implies authorization beyond the authority and policy actually established.
    IA-002 Workload authentication fails workload identity Refuse. No authenticated workload identity is established.
    IA-003 Workload authentication succeeds, but runtime-attestation evidence is absent runtime attestation Authentication stands. Produce no runtime-attestation claim. On the verifier surface, preserve that attestation was not established and why; do not synthesize a weak/default attestation value.
    IA-004 Runtime-attestation evidence is present but cannot be verified runtime attestation Authentication stands if independently valid. Produce no positive runtime-attestation claim. Preserve the not-established condition and its cause rather than treating it as either successful attestation or an attestation mismatch.
    IA-005 Runtime-attestation verification completes and the evidence contradicts the expected workload/runtime binding runtime attestation Refuse on the attestation boundary. This is a verified contradiction, not an absence case.
    IA-006 No represented user is present and workload-only authority is permitted represented user Do not synthesize a user. Evaluate authorization from workload authority and policy.
    IA-007 Represented-user or delegated authority is required, but the required evidence is absent or cannot be established represented user / delegation reference Do not treat delegated user authority as established. Refuse where policy requires that authority, while preserving the reason it was not established rather than reporting a contradictory identity.
    IA-008 Represented-user/delegation evidence is validly readable but is bound to a workload other than the authenticated workload delegation reference / workload identity Refuse. Do not merge the represented principal, delegation, and authenticated workload into one identity.
    IA-009 Token audience is present and does not identify the intended relying resource token audience Refuse before upstream invocation. The authority may be valid, but it is valid for a different audience.
    IA-010 A required token audience cannot be established token audience Do not treat audience restriction as satisfied. Refuse where audience binding is required, while keeping this distinct from IA-009's verified audience mismatch.
    IA-011 Required PoP evidence is absent or cannot be established proof-of-possession binding Do not treat possession as established. Refuse where PoP is required, preserving the not-established reason.
    IA-012 PoP verification completes and the presented authority is bound to a different key/workload context proof-of-possession binding Refuse. This is a verified binding contradiction rather than missing PoP evidence.
    IA-013 Delegated authority that was previously valid is replayed outside its bound scope, context, audience, workload, or validity window delegation reference Refuse. Prior cryptographic validity does not establish authority in the new context.

    Three invariants seem worth making explicit across the fixtures:

    1. Authentication never creates attestation. A valid authentication result can coexist with no established runtime attestation.
    2. Absence never becomes identity. A missing represented user is not synthesized, and missing authority evidence is not converted into a default principal or permission.
    3. Not-established and contradiction remain distinguishable. If verification could not establish a boundary, the relying party can see that condition and its cause; if verification ran and established a mismatch, that boundary is reported as the contradiction.

    For conformance, I would make IA-009/IA-010 and IA-011/IA-012 explicit paired fixtures so an implementation cannot pass by collapsing "missing/unverifiable" into the same result as "present and contradictory". IA-003 and IA-006 would remain protected positive controls for absence: neither is allowed to manufacture a value.

    If this boundary looks right, I’ll turn the rows into concrete conformance fixtures next.

  5. imran-siddique commented on Sep 24, 2026

    @imran-siddique
    MemberAuthor

    @athena-kanellatou, proceed with the conformance fixtures, with one addition to IA-003/004: pair optional and required attestation policies. Independently valid authentication stands in both cases. When policy requires attestation, missing or unverifiable evidence must prevent upstream invocation, with the reason preserved.

    Keep the missing-versus-contradictory pairs and assert zero upstream calls for refusal cases. Include controls showing that bypassing each required boundary makes its test fail.

    Claim fields and token-exchange representation remain a separate decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions