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.

spinner

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/tenantarrow-up-right 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