Skip to content

Verifiers cannot authenticate or policy check the Wallet instance that presents: define Wallet instance authentication on the response #799

Open

Description

@RalphBragg

OpenID4VP defines authentication in one direction only. The Verifier authenticates itself to the Wallet, through the Client Identifier Schemes and verifier_attestation. The reverse direction is undefined: when the response arrives, the Verifier learns nothing authenticated about the Wallet instance that sent it.

Key binding does not fill the gap. It proves the presenter controls the key the Credential was bound to. It says nothing about which Wallet software holds that key, which instance of it, at what assurance, under whose provider, or whether that instance has since been revoked. A Verifier that wants to apply policy on any of those has nothing to apply it to.

This is already asymmetric with OpenID4VCI, where a Wallet authenticates to the Credential Issuer using attestation-based client authentication (draft-ietf-oauth-attestation-based-client-auth), and the Credential Issuer can therefore make an issuance decision about the instance. The same Wallet, presenting the resulting Credential, cannot make the equivalent statement to the Verifier.

Why this is now load bearing

Two things have changed since the asymmetry was acceptable.

Presentation drives consequential actions. Where a presentation authorizes a payment, a disbursement or a regulated action, the Verifier is accountable for a decision about the presenter, not only about the claims. "A valid Credential was presented by someone holding the binding key" is not a sufficient basis for that decision.

The holder is increasingly not a person's handset. Autonomous software acting for a person holds Credentials and presents them. Such a holder is unresolvable in exactly the way a Wallet instance is unresolvable: manufactured or installed software, keys generated per installation, no queryable identity. Whether an instance is a genuine build of a recognised product, running where its provider says, and not revoked, is precisely the question a Verifier must answer before acting, and precisely the question that a Wallet Provider attestation already answers for the Credential Issuer.

What exists and does not reach

  • Key binding. Binds a Credential to a key. Carries no statement about software, instance, assurance or revocation.
  • verifier_attestation. Solves the mirror problem, Verifier to Wallet.
  • Transport level client authentication. Where a Wallet presents over an HTTP response mode there is no defined way to authenticate the sender of that request as a Wallet instance.
  • Wallet Attestation in OpenID4VCI. Defined for the Wallet to Credential Issuer direction. Nothing in OpenID4VP admits the same artifact on the presentation path.

Proposed mechanism

Define an extension point on the response, reusing artifacts that already exist rather than minting new ones.

  1. Carry the existing attestation on the response. Where the response is delivered over HTTP (direct_post, direct_post.jwt, and the equivalent in the Digital Credentials API transport), the Wallet MAY include the headers defined in draft-ietf-oauth-attestation-based-client-auth:

    OAuth-Client-Attestation:     <oauth-client-attestation+jwt>
    OAuth-Client-Attestation-PoP: <oauth-client-attestation-pop+jwt>
    

    sub is the Wallet's client identity as the provider asserts it, cnf binds the instance key. No new artifact and no new claim.

  2. Bind the request itself. The Wallet includes a DPoP proof (RFC 9449) over the response POST, so the attestation cannot be replayed onto a different request.

    DPoP: <dpop+jwt, htm=POST, htu=.../response>
    
  3. One key, not three. This is the part that has to be normative or the extension is decorative. The key in the attestation cnf, the key proving the DPoP request, and the key binding in the presentation MUST be the same key, or MUST be provably linked by the attestation. Without that rule a presentation obtained from one instance can be relayed by another that merely holds a valid attestation of its own.

  4. Attester trust through the federation. The attestation's iss is the Wallet Provider's Entity Identifier, resolved through a Trust Chain to a Trust Anchor. This is the mechanism openid/federation-wallet already defines for the Wallet to Credential Issuer direction, and Credential Verifier instances (POS terminals, mobile readers) have no trust model: define the Wallet Provider pattern for the verifier side federation-wallet#60 establishes the mirror pattern on the Verifier side (now accepted). Defining this direction closes the set: Wallet to Credential Issuer, Verifier to Wallet, Verifier instance to Wallet, and Wallet instance to Verifier, all resolving attester trust the same way instead of through separately baked in keys.

  5. Narrowing, never extension. As in Credential Verifier instances (POS terminals, mobile readers) have no trust model: define the Wallet Provider pattern for the verifier side federation-wallet#60 and consistent with metadata_policy semantics and RFC 8693 scope narrowing, an instance attestation may carry provider asserted constraints that narrow what the organizational entity is entitled to, and may never extend it. The Verifier evaluates the intersection, fail closed. A compromised provider can at worst reduce privileges.

What this makes possible

A Verifier can apply policy to the presenter and not only to the claims: require a minimum assurance level, require a hardware backed instance key, refuse an instance whose status list entry is set, or refuse a class of holder entirely for a class of transaction. None of that is expressible today.

It is also the piece that lets an autonomous agent be treated as a Wallet without weakening the model. The agent presents what it holds, and the Verifier can establish which copy is presenting, on whose authority it was issued, and whether that copy is still recognised, all through the same trust fabric.

Scope

This needs no change to any Credential format and no change to the Authorization Request. It is an extension point on the response, plus one normative statement about key identity, plus a reference for resolving attester trust.

We have implemented instance attestation and sender constrained presentation in agent deployments and would be glad to contribute text.

Activity

  1. RalphBragg commented on Sep 21, 2026

    @RalphBragg
    Author
  2. RalphBragg commented on Sep 21, 2026

    @RalphBragg
    Author

    Further Evidence:

    1. The mechanism now has agreement. federation-wallet#60 establishes the Wallet Provider pattern on the verifier side. When Verifier/Relying Parties need to be able to verify authenticity and validity of (European Digital Identity) Wallets #141 was decided there was no settled way to trust an attester without baking keys into wallet software, so "attestation to the RP" looked like a new hierarchy. It is not one now — it is a direction of a fabric this group's own sibling spec defines.

    2. HAIP superseded the privacy objection in 141. Final, 24 December 2025. Verifier/Relying Parties need to be able to verify authenticity and validity of (European Digital Identity) Wallets #141 closed 8 April 2025. Eight months. §4.4.1 answers correlation by constraint rather than abandonment, and those two sentences apply verbatim with "Verifiers" for "Issuers". I'm proposing the same mechanism here.

    3. Wallets as agents inverts Verifier/Relying Parties need to be able to verify authenticity and validity of (European Digital Identity) Wallets #141's premise. Its resolution rests on the Issuer and Wallet Provider being responsible for the validity of what the Wallet holds. Potentially sound for a passive container held by the person the credential is about, though I'd welcome an argument in any ecosystem where significant financial risk is going to be undertaken solely on a credential. It does not reach a holder that decides when to present, to whom, and on whose behalf, where the Verifier is accountable for a payment.

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