Wallet Flow Specifications
This page explains the flow between aadhaar app and wallet for credential exchange
1. Introduction
This document outlines a resident-friendly flow for the exchange of identity credentials in standard formats (SD-JWT or ISO mDOC) with the wallet. This flow is inspired by OpenID4VCI standards and customised to meet the Aadhaar Act and Regulations for OVSE. The flow supports Pre-authorised Code flow, wherein the Aadhaar app obtains the code from the CIDR before the exchange of the flow. This code is further used to obtain a credential with the wallet. OpenID for Verifiable Credential Issuance (OpenID4VCI) is an API that enables the issuance of verifiable credentials using OAuth 2.0.
2. Actors
Credentials exchange involves the following actors:-
2.1 Aadhaar Number Holder (ANH) - Key actor in the exchange of the credential
2.2 Aadhaar App - Mobile app of UIDAI for credential exchange and aadhaar app lifecycle management
2.3 Wallet - Digital Wallet for holding credentials and facilitating its exchange.
2.4 Wallet backend - Wallet backend is the server-side component of the wallet. The Aadhaar app will upload the credentials to the Wallet backend.
2.5 CIDR - Central Identities Data Repository. The Aadhaar app interfaces with the CIDR for the issuance of the credential.
3. Sequence Diagram
The sequence diagram for the exchange of credentials is as shown in Figure -1.
The sequence diagram envisions the Aadhaar App to be pre-installed on the mobile device to facilitate credential exchange. Steps for the exchange of credentials are as follows:-
3.1. Resident Intent for Wallet Exchange. At this step, the ANH in the aadhaar app explicitly expresses intent to share credentials with the wallet.
3.2 Issuer Config. The Aadhaar app makes a call to the backend for the issuer metadata and credential details. Issuer Config Request as follows:
3.3. Issuer Config Response. Issuer responds with the credential identifier and a nonce value, which will be used in the subsequent stage to correlate with the credential request.
3.4. Credential Offer. Aadhaar app makes the credential offer to the wallet through the credential manager API of Android OS. A similar process is being pursued with Apple to establish commonality in the flow.
Field
Meaning
Typical Use / Example
credential_issuer
The base URL of the credential issuer’s OpenID4VCI endpoint (the system issuing the VC).
https://issuer.uidai.gov.in
credential_configuration_ids
Array of credential “templates” that the wallet may request. These correspond to definitions published in the issuer’s metadata endpoint.
"aadhaar"
grants
Describes which OAuth2 grant mechanisms are supported for issuing the credential.
Usually one of:• pre-authorized_code (offline issuance)• authorization_code (online interactive issuance)
urn:ietf:params:oauth:grant-type:pre-authorized_code
A specific grant type meaning the wallet can directly request credentials using a pre-authorized code — no live login or user interaction needed.
Used for push-style or delegated issuance.
pre-authorized_code
A short-lived opaque token (nonce) issued by the credential issuer to identify a single issuance session.
Example: "2a1b2b1f-93b9-42f4-a77e-2e2ab4caa705"
When retrieving the Credential Offer from the Credential Offer URL, the application/json media type MUST be used. The Credential Offer cannot be signed and MUST NOT use application/jwt with "alg": "none".
3.7 Credential Request. In response to the Aadhaar App's credential offer, the wallet makes a credential request to the Aadhaar app via a deeplink call. The credential request is prepared as per the following steps:
Wallet extracts the nonce (also pre-authorization_code) shared by the aadhaar app as part of the credential offer. Nonce is used to generate attestation.
Wallet accesses the https://uidai.gov.in/.well-known/openid-credential-issuer/tenant to obtain the issuer metadata. Issuer metadata contains JSON metadata about the UIDAI-provided credentials. At this stage, the attribute of interest is credential_request_encryption. This information can also be exchanged offline, by performing a key exchange ceremony.
For each attestated_key in the request, the wallet generates the X.509 Certficate with the help of Android Key Store, base64 encodes it and encrypts it with the key provided in credential_response_encryption before including it in the credentials array. The response includes a credential_id (same as the one in the credential_request, if provided) along with the credential(s) to uniquely identify this credential for updates/notifications in the future.
Field
Purpose
Typical Values / Notes
credential_identifier
An optional instance-specific identifier that the holder or issuer uses to correlate a request.
A string that identifies a Credential Dataset that is requested for issuance. When this parameter is used, the credential_configuration_id MUST NOT be present.
A UUID or reference like "aadhaar_cred_req_01"
credential_configuration_id
Identifies which credential configuration (template) this request targets.
It MUST NOT be used otherwise if credential_identifier is populated.
"aadhaar", "passport", "vc_basic_profile", etc.
proof
One or more objects giving cryptographic evidence of key possession or device trust.
Each proof element can be attestation, jwt, cose, or sd-jwt.
proof_type
Type of proof provided.
"attestation" for key-attestation JWTs, "jwt" for signed proofs, etc.
attestation
The actual signed JWT (from your earlier example) proving that keys were generated in a secure enclave.
Compact JWS string like eyJhbGciOiJFUzI1NiIsInR5cCI6...
credential_response_encryption
Object containing information for encrypting the Credential Response. Presence of the parameter indicates that the wallet requires the credential in encrypted form.
"credential_response_encryption": {
"jwk": {
"kty": "RSA",
"kid": "42BC0B9502287D4A777152339EE6690E",
"use": "enc",
"alg": "RSA-OAEP-256",
"n": "jElU41Bi...",
"e": "AQAB"
},
"enc": "A256GCM",
"zip": "none"
}
Attestation in JWT format
credential_response_encryption parameter details
Field
Description
Example / Notes
jwk
The public key used to encrypt the credential response (in JWK format).
A standard RSA key.
kty
Key type.
"RSA" or "EC"
kid
Key ID — identifies this key uniquely.
"42BC0B95..."
use
Key usage.
"enc" → used for encryption, not signing.
alg
Key management algorithm.
"RSA-OAEP-256" (RSA-OAEP with SHA-256)
n / e
RSA modulus and exponent (base64url).
Public key values
enc
Content-encryption algorithm (for actual data).
"A256GCM" (AES-GCM 256-bit symmetric cipher).
zip
Compression method before encryption.
"none" (can be "DEF" for DEFLATE).
3.8 Credential Request. Credential request is sent as a query param in the deeplink. Aadhaar app will handle this deeplink and on receipt of the encrypted credential request, the aadhaar app requests the backend to validate the credential request.
3.9 Credential Response. In response to the credential request, the backend provides a validation response as per the following structure.
The actual credential request is crafted at the aadhaar app using already available credentials.
3.10 Wallet Backend Callback. At this stage, the Aadhaar app makes a callback to the wallet backend, presenting the credential.
Last updated