Secure DigiLocker Callbacks and Account Binding
Bind a DigiLocker callback to the correct application and user. Use exact redirects, one-time state, PKCE, and server-side checks before attaching results.
Bind each DigiLocker attempt to the signed-in account before the browser leaves your application. Store that binding on the server. Check it again before you attach the result.
OAuth guidance covers exact redirect matching and protection against code interception and injection. The DigiLocker requester specification documents the authorization code and PKCE flow. OAuth 2.0 Security Best Current Practice. Requester v2.4 specification
Store a short-lived attempt
| Value | What it protects |
|---|---|
| Local user and application | Identifies the intended account and caller |
| Provider and environment | Identifies the configuration for the exchange |
| Random state | Correlates the callback with the attempt |
| PKCE verifier | Binds code exchange to the client that began the flow |
| Expected redirect URI | Keeps the exchange on the registered path |
| Expiry and used status | Limits use and prevents replay |
For an identity response, validate its signature and applicable claims. Bind a nonce when your contract supports or requires it and your flow sends one. Keep the issuer and signing keys in approved configuration.
Process the callback in order
- Find the pending attempt using the returned state.
- Check the application, user binding, environment, and expiry.
- Reject mismatches without changing the user's account.
- Consume the attempt atomically to prevent concurrent reuse.
- Exchange the code through the configured backend.
- Validate the applicable token and permission response.
- Associate the result with the original account.
Design a new attempt for an exchange that fails after state consumption. A browser return can identify an attempt. The server verifies the binding and retrieves the authoritative outcome.
Test account switching and replay
In a synthetic case, a user starts a verification under account A. Before the callback, the browser switches to account B. The application must never attach A's result to B.
Send the same callback twice in another test. Only one request should reach the code exchange. Also test wrong state, expired state, a mismatched issuer, and a missing document permission.
Record the outcome with a bounded reason code. Keep callback query parameters and secret material out of access logs.
Use separate return handlers
If you host both sign-in and document verification, give each return path a clear purpose. A verification return should complete a verification task for an existing account. A login callback should follow the authentication flow.
Keep the distinction in mobile link handling and error screens. DigiLocker implementation guide.
Review callback binding with NamoID
NamoID engineers can help review the server-side attempt record and test account switching, replay, or mobile return paths. Share a synthetic request trace and your stack. Message the NamoID team in Slack