# Wallet Flow Specifications

## 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.&#x20;

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.&#x20;

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. &#x20;

{% @mermaid/diagram content="
sequenceDiagram
participant Holder as Holder
participant AadhaarApp as AadhaarApp
participant AndroidCredMan as AndroidCredMan
participant Wallet as Digital Wallet
participant WalletBackend as Digital Wallet Backend
participant Issuer as CIDR (UIDAI)

```
Note over Holder, Issuer: Pre-Auth Code Flow (Non Normative Flow)
Holder->>AadhaarApp: 1: User Intent for Wallet Share
AadhaarApp->>Issuer: 2. Request Issuer Config (Pre-Auth code, Secret, c_nonce, access_token, credential_request_encryption_key, redirect_uri)
Issuer->>AadhaarApp: 3. Issuer Metadata (Credential Offer)

Note over AadhaarApp,AndroidCredMan: Credential Offer Push
AadhaarApp->>AndroidCredMan: 4. Credential Offer
AndroidCredMan->>AndroidCredMan: 5. Generate txn_code
AndroidCredMan-->>Wallet: 6. Credential Offer

Wallet->>AadhaarApp: 7. redirect_uri (CredentialRequest)
AadhaarApp->>AadhaarApp: 8. CredentialRequest
AadhaarApp->>WalletBackend: 10. Wallet Backend Callback
```

" %}

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:

```
{
    "device_id" : "<device_id>" 
}
```

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.

```
{
    "credential_identifier" : "<credential_identifier>",
    "nonce" : "<nonce>",
}
```

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.

```
{
"credential_issuer": "https://uidai.gov.in",
  "credential_configuration_ids": [
    "aadhaar"
  ],
  "grants": {
    "urn:ietf:params:oauth:grant-type:pre-authorized_code": {
      "pre-authorized_code": "<<pre auth code >>" 	// nonce
    }
  }
}
```

| 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](https://docs.uidai.gov.in/readme/app-to-app-credential-flows/uidai-specifications/https:/uidai.gov.in\[/.well-known/openid-credential-issuer/tenant)]\(<https://issuer.example.com/.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.

```
{
   "credential_identifier": "random uuid",
   "credential_configuration_id": "aadhaar"  
   "proof": [{
      "proof_type": "attestation",
      "attestation":"<attestation_in_jwt_format>"
   }],
   "credential_response_encryption": "encryptionConfig"  
}
```

| Field                            | Purpose                                                                                                                                                                                                                                                                         | Typical Values / Notes                                                                                                                                                                                                                                                                                                     |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| credential\_identifier           | <p>An optional instance-specific identifier that the holder or issuer uses to correlate a request. </p><p>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.</p> | A UUID or reference like "aadhaar\_cred\_req\_01"                                                                                                                                                                                                                                                                          |
| credential\_configuration\_id    | <p>Identifies which credential configuration (template) this request targets.</p><p><br></p><p>It MUST NOT be used otherwise if credential\_identifier is populated.</p>                                                                                                        | "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.                                                                                                            | <p>"credential\_response\_encryption": {</p><p>  "jwk": {</p><p>    "kty": "RSA",</p><p>    "kid": "42BC0B9502287D4A777152339EE6690E",</p><p>    "use": "enc",</p><p>    "alg": "RSA-OAEP-256",</p><p>    "n": "jElU41Bi...",</p><p>    "e": "AQAB"</p><p>  },</p><p>  "enc": "A256GCM",</p><p>  "zip": "none"</p><p>}</p> |

Attestation in JWT format

```
{
   "typ": "keyattestation+jwt",
   "alg": "ES256",
   "x5c": ["MIIDQjCCA..."]   // Certificate Chain from the device Device key is part of the leaf of the chain
}.
{
   "nonce": "<nonce_fetched_from_nonce_endpoint>",
   "iat": 1516247022,
   "attested_keys": [{   // Key for authentication
      "kty": "EC",
       "crv": "P-256",
       "x": "TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc",
       "y": "ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ"
   }]
}.
{
Signature
}
```

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.&#x20;

```
//Headers: Session token to be used for authentication +authorization
//Body: Credential request object
{
    "uid": "123456789012",
    "encryted_credential_request":"<encrypted_credential_request>"
}
```

3.9  **Credential Response.**  In response to the credential request, the backend provides a validation response as per the following structure.

```
{
    "credential_response": "encrypted + signed credential response"
}
```

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.

```
{
    "credential_identifier":"id"
    "credentials": [{
      "Credential": "LUpixVCWJk0eOt4CXQe1NXK....WZwmhmn9OQp6YxX0a2L"
    }]
}
```

\
\
\
\ <br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.uidai.gov.in/readme/app-to-app-credential-flows/uidai-specifications/wallet-flow-specifications.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
