Overview
Every Aarokya endpoint is authenticated with a JSON Web Token passed asAuthorization: Bearer <jwt>. Tokens come from one of two issuers:
App-user token
Issued by
POST /auth/token. A partner platform’s backend exchanges a worker’s phone number and id-proof for a short-lived app JWT. This is the token mobile apps use.OIDC token
Minted by Keycloak. Platform and benefit-provider service accounts (via
client_credentials), and admin / dashboard users (via login) authenticate this way.Issuing an App-User Token
A partner backend authenticates as its platform service account and callsPOST /auth/token. Aarokya validates the platform, find-or-creates the user by phone number, and returns an app JWT. See the Auth module for the full flow and the Platform module for provisioning the service-account credential.
1
Authenticate as the platform service account
The partner exchanges its platform credential
basic_token with Keycloak (client_credentials grant) for a service-account JWT. The handler gates on actor.require_platform_service().2
Exchange a phone number for an app token
Response 200
3
Hand the app token to the client
The mobile app receives the
access_token from its own backend (not from Aarokya directly) and uses it as a Bearer token. The path user_id on user-scoped routes must match the token’s user.id_proof.proof_type accepts AADHAAR, PAN, PASSPORT, DRIVING_LICENSE, or VOTER_ID. id_proof is consumed only when the user is first created; on repeat calls it is ignored.App Token Reference
App JWT
Signature: RS256, verifiable with Aarokya’s public key.Claims:
actor_type: "app", a user_info block (user_id, phone_number, phone_country_code, names), status, platform_id, plus iss / aud / iat / exp.Expiry: configurable (auth.app.expiry_hours).Usage: Authorization: Bearer <token> on every user-scoped request.Token renewal
App tokens are short-lived and stateless. When one expires, the client requests a fresh one from its own backend, which re-calls
POST /auth/token.status claim (ONBOARDING, ACTIVE, or DEACTIVATED) drives the client’s onboarding UI. A freshly created user is ONBOARDING until POST /users/{user_id}/complete_onboarding succeeds.
Renewal
Because tokens are minted server-side by the partner backend, renewal is a backend concern, not a device concern: Implement proactive renewal: when the app token is close to itsexp, request a new one from your backend before the next API call rather than waiting for a 401.
Token Storage — Client
Store the app token in platform-secure storage and keep it off disk in plaintext. The token is a bearer credential: anyone holding it can act as the user until it expires.iOS
Keychain with
kSecAttrAccessibleWhenUnlockedThisDeviceOnly. In-memory is fine for the lifetime of the session.Android
EncryptedSharedPreferences (API 23+), which is backed by the Android Keystore.React Native
react-native-keychain with ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY — Keychain on iOS, Keystore-backed storage on Android.Web / PWA
Keep the token in memory (JS variable / app state). Never use
localStorage or sessionStorage — both are exposed to XSS.Error Responses
Authorization failures on a specific resource (wrong scope, not the owner, admin-only) surface as that domain’s own error code — see Errors.
Security Checklist for Client Developers
Token storage
- iOS: Keychain with
kSecAttrAccessibleWhenUnlockedThisDeviceOnly - Android:
EncryptedSharedPreferences(API 23+) - Web: in memory only — never
localStorage/sessionStorage
Token transmission
- Always use HTTPS in production
- Never log tokens
- Never put tokens in URLs or query parameters
Renewal
- Fetch a fresh token from your backend before
exp - Do not embed long-lived platform service-account credentials in the client
Scope
- Use the
user_idfrom the token for user-scoped paths - Clear the stored token on logout and on app reinstall