PehchanPe
OVSE · UIDAI

Credential Exchange Architecture

PehchanPe OVSE | Aadhaar App | Verifiable Credentials
System Design v1.0 — March 2026
10
Flow Steps
6
TS Modules
63
Scope Claims
5 min
JWT Expiry
🔐 RS256 Signing
JWT signed with RSA private key. Public key shared with UIDAI for verification. Keys rotated per CCA provisions.
⏳ Token Expiry
JWT valid for 5 minutes only. JTI claim prevents replay attacks. Each transaction gets unique txn ID.
✅ SD-JWT Verification
Response verified using UIDAI public key. Disclosure hashes validated against _sd field. PII handled per Aadhaar Act.
🔧 Technology Stack
Infrastructure and services powering the credential exchange
🔥
Firebase
Cloud Functions v2
🗄️
Firestore
NoSQL Database
🔑
RSA Keys
RS256 JWT Signing
📱
mAadhaar
Aadhaar App Intent
📷
QR Code
Base10 Encoded
🛡️
SD-JWT
Verifiable Credentials
Cloud Functions
Aadhaar App
Firestore Collections
Internal Processing
Verifier Portal
📋 Phase 1 — QR Code Generation
From verifier request to scannable QR code
Verifier Portal Requests Credential Exchange
🏢
Verifier Portal
Web Application
POST /generate-qr
generateQR CF
Build JWT Payload
SIGN RS256
🔐
RSA Private Key
JWT Signing
ENCODE
🗜️
qrEncoder
Base10 Encoding
QR Data Returned to Portal
🔢
Base10 String
Numeric QR Data
WRAP URL
🔗
Intent URL
maadhaar.com/getIntent
RESPONSE
📷
QR Code
Rendered on Portal
Cloud Function Endpoint: generateQR — accepts hintName + scope + lang, returns txn + intentUrl + qrData + expiresAt
📱
User Scans QR Code with Aadhaar App
Cross-device credential exchange via mAadhaar intent — user consents to share identity claims
📨 Phase 2 — Credential Callback & Verification
From Aadhaar App response to verified credential storage
Aadhaar App Posts SD-JWT to Callback
📱
Aadhaar App
SD-JWT Response
POST /callback
📨
ovseCallback CF
Parse Response
VERIFY
🔍
sdJwtVerifier
Signature Check
EXTRACT
📦
Credential Claims
Identity Data
Store Verified Credential & Acknowledge
📦
Verified Claims
Name, DOB, Photo...
STORE
🗄️
ovse_verifications
Firestore
200 OK
Aadhaar App
Acknowledged
Cloud Function Endpoint: ovseCallback — receives txn + response (SD-JWT) + errCode + errInfo + dateTime
🔄 QR Encoding Pipeline
JWT to QR-ready Base10 string transformation (per UIDAI spec)
🔐
Signed JWT
📝
ISO-8859-1 Bytes
🔚
Append 0xFF
🗜️
Gzip Compress
🔢
BigInt → Base10
📷
QR Code
🧾 JWT Token Structure
Credential request token per UIDAI specification
credential-req+jwt
Header
"alg": "RS256",
"typ": "credential-req+jwt",
"kid": "did:myaadhaarstage.uidai.gov.in:123#1"
"txn": "uuid-v4",              // Unique transaction ID
"i":   "credential",           // Intent type
"lang": "23",                  // Language (English)
"sc":  "00001100...01",         // 63-bit scope bitmap
"pop": 1,                      // Proof of possession
"m":   1,                      // Online face auth
"ac":  "aua_code",             // AUA code (UIDAI assigned)
"sa":  "client_id",            // ⏳ Client ID (awaiting)
"cb":  "https://domain/ovse/callback",
"aud": "https://myaadhaarstage.uidai.gov.in",
"iss": "https://myaadhaarstage.uidai.gov.in/v1/esignet",
"exp": iat + 300,              // 5 min expiry
"iat": timestamp,
"ht":  "Person Name",          // Profile selection hint
"jti": "uuid-v4"               // JWT unique ID
📦 System Modules
TypeScript modules in functions/src/
⚙️
config.ts
Centralized config — AUA codes, staging endpoints, default scope bitmap. Client ID placeholder.
New
🎯
scopeBuilder.ts
Human-readable claim names → 63-bit bitmap string per UIDAI credential spec.
New
🗜️
qrEncoder.ts
JWT encoding pipeline: ISO-8859-1 → delimiter → gzip → BigInt → Base10. Port of Python reference.
New
📷
generateQR.ts
Cloud Function: builds JWT, signs RS256, encodes to Base10, returns QR data + intent URL.
New
🔍
sdJwtVerifier.ts
SD-JWT signature verification, disclosure hash validation, credential claim extraction.
New
📨
index.ts
Enhanced callback handler — parses response, verifies SD-JWT, stores verified data in Firestore.
Modified
Cloud Function Endpoints: generateQR · ovseCallback — All via Firebase Hosting rewrites