DEVELOPER INTEGRATION · VERSION 1.0.0
← Integration guideConnect a new application
Use one confidential connection per program and environment. The browser or mobile client talks to its own backend.
1. Register the application
Give the SSO team your unique application code, display name, HTTPS portal URL and exact backend callback. Also provide every browser return URL, mobile callback scheme and any origin that will call the registration API. Production callbacks must use HTTPS; wildcards are unsupported.
An authorized administrator runs this from the identity server. Replace the illustrative domain and names with your approved application values:
python manage.py connect_application \
--code new-program --name "New program" \
--portal https://new-program.example/ \
--callback https://api.new-program.example/api/v1/sso/callback/ \
--output /private/new-program-client.json
The command writes a client ID and secret once to a new private file. Existing application codes or output files are refused. Public client registration is unavailable. SSO administrators can enable or disable the connection in Applications; new connections currently require this server-side command.
2. Configure the program backend
Set these environment variables on the backend only. Generate a separate Fernet encryption key and preserve it across releases. Values in angle brackets are placeholders, not usable credentials.
CITY_SSO_ENABLED=true
CITY_SSO_ISSUER=https://identity.city.digikraft-technologies.com
CITY_SSO_CLIENT_ID=<issued-client-id>
CITY_SSO_CLIENT_SECRET=<issued-client-secret>
CITY_SSO_REDIRECT_URI=https://api.new-program.example/api/v1/sso/callback/
CITY_SSO_RETURN_URIS=https://new-program.example/,com.yourorganisation.newprogram://callback
CITY_SSO_ENCRYPTION_KEY=<private-fernet-key>
Each return URI must match exactly, including path and trailing slash. A native URI is the app return address, never the OAuth provider callback. Register its scheme in Android/iOS. Use a unique scheme for each app.
3. Wire the shared integration
Our source package includes integration/django/city_sso/, integration/web/cityIdentity.ts and integration/flutter/city_identity/. The web helper provides beginSmartCity/resumeSmartCity; Flutter provides CityIdentity.signIn/resume. Helpers call your program API under /api/v1/.
For Django, install the integration dependencies (djangorestframework, djangorestframework-simplejwt, PyJWT[crypto], requests and cryptography), add city_sso to INSTALLED_APPS, include its URLs, then run migrations:
# settings.py
CITY_SSO_ADAPTER = 'your_app.sso.CitizenAdapter'
# urls.py
path('api/v1/sso/', include('city_sso.urls'))
# Run from the program backend
python manage.py migrate
The local user model needs is_active, auth_version and Django password methods. Implement is_citizen(user), has_collision(claims) and create_citizen(claims). Provision the least privileged citizen profile only. Call validate_identity(user, token) in JWT authentication and require_local_login(user) in legacy password sign-in. Use require_central_registration() to stop duplicate local citizen registration. Preserve identity_session and auth_version during local token refresh.
Other backend stacks must implement the same protocol and program API contract. Do not add a direct password grant or put the confidential secret in a frontend.
4. Pass acceptance checks
- Sign the same verified citizen into two programs without registering again; provision only when a program is first used.
- Reject a wrong verifier, replayed code, expired handoff, unregistered redirect, wrong issuer/audience or invalid signature.
- Require explicit proof of an existing local account before linking. Confirm a citizen cannot enter staff routes.
- Test password recovery, suspension, application disable, local logout and central session revocation.
- Check mobile callbacks, responsive account pages and unavailable-email/identity-service messages. Use isolated fixtures, never deployment citizens.
For a custom registration screen, the SSO operator must also add its exact HTTPS origin to IDENTITY_CORS_ALLOWED_ORIGINS. Hosted registration needs no cross-origin API setup. CORS is allowed only for the public enrollment endpoints.