Wallet Backend API (1.0.0)

Download OpenAPI specification:

License: Proprietary

Client Attestation and Key Attestation issuance for wallets — carved out of the main VC Platform API (../../../docs/api/openapi.yaml) into its own deployable, apps/wallet-backend, for security isolation: these four endpoints are the only fully unauthenticated, pre-auth routes anywhere on the VC Platform system. A private Wallet-Provider↔Wallet-Instance protocol, not part of any OpenID4VC spec — this is this platform's own minimal, PoP-gated version of it. See the User Guide for the full walkthrough with worked examples and error-handling guidance; this reference states the wire contract precisely and nothing more.

Reached through the same public hostname as the rest of the VC Platform API — routing to this separate service happens at the edge, not by the caller knowing two different hosts.

Attestations

The reference client-attestation issuer. Both OpenID4VCI grants on the main VC Platform API require a wallet to present a Client Attestation JWT from some Wallet Provider; obtaining one in the first place is deliberately left undefined by every OpenID4VC spec, so this service ships its own minimal, PoP-gated version for wallets that don't have a real Wallet Provider of their own yet.

Issue a single-use PoP challenge

No body, no headers required. The returned challenge has a 300-second TTL and can be consumed exactly once, by a following call to POST /attestations.

Responses

Response samples

Content type
application/json
{
  • "challenge": "string"
}

Issue a Client Attestation JWT

Self-attested: this vouches for whoever holds the private key matching jwk, not for the key's trustworthiness. pop is a compact JWS over {"challenge": "<challenge>"}, signed by that same private key. The challenge is consumed on use — a second call with the same challenge and pop fails, even if the first succeeded.

Request Body schema: application/json
required
jwk
required
object

Public JWK of the key being attested — the wallet-instance key for POST /attestations, the credential-holder key for POST /key-attestations.

challenge
required
string

From a prior call to the matching /challenge endpoint above.

pop
required
string

Compact JWS over {"challenge": "<challenge>"}, signed by the private key matching jwk.

Responses

Request samples

Content type
application/json
{
  • "jwk": { },
  • "challenge": "string",
  • "pop": "string"
}

Response samples

Content type
application/json
{
  • "attestation_jwt": "string",
  • "client_id": "string"
}

Key Attestations

ARF Annex 2 Topic 9 Key Attestation issuance. Same PoP-gated challenge shape as Attestations, but attests the credential-holder key (what a wallet typically calls identity.jwk) rather than the wallet-instance key, and describes key storage (key_storage: ["software"], deliberately no hardware-backed claim) instead of authenticating an OAuth client.

Issue a single-use PoP challenge

Same shape and TTL as POST /attestations/challenge, but tracked in a separate namespace — a challenge from one endpoint is never valid at the other, even if the same string were somehow issued by both.

Responses

Response samples

Content type
application/json
{
  • "challenge": "string"
}

Issue a Key Attestation JWT

Same self-attested PoP shape as POST /attestations, but jwk here is the credential-holder key a future credential will be bound to — allowed to be, and by ARF's own design usually should be, a different key from the Client Attestation's wallet-instance key.

Request Body schema: application/json
required
jwk
required
object

Public JWK of the key being attested — the wallet-instance key for POST /attestations, the credential-holder key for POST /key-attestations.

challenge
required
string

From a prior call to the matching /challenge endpoint above.

pop
required
string

Compact JWS over {"challenge": "<challenge>"}, signed by the private key matching jwk.

Responses

Request samples

Content type
application/json
{
  • "jwk": { },
  • "challenge": "string",
  • "pop": "string"
}

Response samples

Content type
application/json
{
  • "key_attestation_jwt": "string"
}