Smart CityOne account. Your city services.

DEVELOPER INTEGRATION · VERSION 1.0.0

← Integration guide

Browser 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.

  1. Start in the app. Generate a random verifier (43–128 URL-safe characters) and its base64url SHA-256 challenge without padding. Send return_uri and code_challenge to your backend's POST /api/v1/sso/begin/. Keep the verifier temporarily in that browser tab or the native sign-in operation.
  2. Redirect to SSO. Open the returned authorization_url. Your backend independently generates its own verifier, state and nonce. It requests response_type=code, scopes openid profile email offline_access and code_challenge_method=S256 from https://identity.city.digikraft-technologies.com/o/authorize/.
  3. 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.
  4. Validate identity. Verify the ID token's RS256 signature against the published JWKS, exact iss, your client ID in aud, timestamps, nonce and verified email. Require sid; check azp for a multi-audience token. Link by issuer/subject and provision a citizen only when absent.
  5. 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.
  6. Finish in the app. Remove callback parameters from the browser URL immediately. Send the handoff as code with the original app code_verifier to POST /api/v1/sso/exchange/. The backend returns local access and refresh tokens 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.