DEVELOPER INTEGRATION · VERSION 1.0.0
← Integration guideBrowser and mobile sign-in
Use the system browser on mobile and a top-level redirect on the web. Passwords belong only on Smart City Identity.
- Start in the app. Generate a random verifier (43–128 URL-safe characters) and its base64url SHA-256 challenge without padding. Send
return_uriandcode_challengeto your backend'sPOST /api/v1/sso/begin/. Keep the verifier temporarily in that browser tab or the native sign-in operation. - Redirect to SSO. Open the returned
authorization_url. Your backend independently generates its own verifier,stateandnonce. It requestsresponse_type=code, scopesopenid profile email offline_accessandcode_challenge_method=S256fromhttps://identity.city.digikraft-technologies.com/o/authorize/. - Process the HTTPS callback. The backend validates and consumes its pending state, checks any response
iss, then exchanges the authorization code at/o/token/using HTTP Basic client authentication and its own verifier. The callback expires after 10 minutes; provider authorization codes expire after 90 seconds. - Validate identity. Verify the ID token's RS256 signature against the published JWKS, exact
iss, your client ID inaud, timestamps,nonceand verified email. Requiresid; checkazpfor a multi-audience token. Link by issuer/subject and provision a citizen only when absent. - Return a handoff. The backend redirects to the allowlisted app URI with
sso_code, a one-use opaque code bound to the app challenge. It expires after 90 seconds. No access, refresh or ID token belongs in a redirect URL. - Finish in the app. Remove callback parameters from the browser URL immediately. Send the handoff as
codewith the original appcode_verifiertoPOST /api/v1/sso/exchange/. The backend returns localaccessandrefreshtokens for that program.
Example: app to program API
POST /api/v1/sso/begin/
Content-Type: application/json
{
"return_uri": "https://new-program.example/",
"code_challenge": "<base64url-sha256-of-app-verifier>"
}
POST /api/v1/sso/exchange/
Content-Type: application/json
{
"code": "<one-use-sso_code-from-callback>",
"code_verifier": "<original-app-verifier>"
}
Sessions, tokens and logout
Central access tokens last 15 minutes; the program session lasts at most 14 days. Refresh tokens rotate: save each replacement atomically and serialize concurrent refreshes. Central tokens stay encrypted in the program backend. Use the program's bearer tokens only with its own API; they are not interchangeable with SSO tokens.
The shared middleware checks central validity at least every 30 seconds when the program is used. A password reset, suspension or ended central browser session invalidates its connected sessions. An SSO outage returns HTTP 503; preserve local credentials and offer retry.
POST /api/v1/sso/logout/ ends the current program-side identity session; clear that app's local credentials too. It does not sign out the central browser or other programs. For central logout, send the user to their Smart City sessions page to end the relevant sessions. The central /logout/ form requires a CSRF-protected POST. RP-initiated logout and back-channel logout are not provided.
Existing accounts and errors
To link an existing citizen, first authenticate to that local account, then call begin/ with link: true and its bearer token. Matching email addresses alone never prove ownership. Once linked, the local password and older legacy tokens must no longer bypass SSO.
Callback sso_error values are cancelled, existing_account or unavailable. Show an actionable message and let the user restart. A wrong/replayed/expired handoff returns HTTP 401. Invalid app input returns HTTP 400; throttling returns HTTP 429.