Appearance
Onboarding
Onboarding is owned by Central Auth. Platforms choose a mode in the platform registry; the gateway evaluates status on every login and embeds the result in the handoff exchange. Independently of the mode, the global profile requirements are enforced for every platform.
Modes
| Mode | After central callback | Who hosts the UI |
|---|---|---|
none | Immediate handoff (after the global profile requirements) | No platform onboarding gate |
platform | Immediate handoff (after the global profile requirements; platform status may be incomplete) | Platform UI |
central | Incomplete → identity UI onboarding; complete → handoff | Identity UI (identity-web), then /v1/auth/resume |
Mode comes from platforms.default_onboarding_mode. The optional onboardingMode query on /v1/auth/start must match that value when provided.
central additionally requires platforms.central_onboarding_enabled = true. Bootstrap exposes this to clients as onboarding.canCompleteCentrally.
Global profile requirements
Some profile data is needed from every user whatever platform they use, for example their name and date of birth. Platform admins configure it once as global profile requirements: in Onboarding Admin under Global profile requirements, or through /v1/admin/onboarding/global-fields (see Admin operations).
- A global field is always a canonical profile field (
firstName,dateOfBirth,nationalityCountryCode, …), identified by its profile key. Its value lives inuser_profiles, so a user enters it once for all platforms. - Each profile field is either collected or not, and required or optional. There is no built-in default set: nothing is required until an admin turns it on.
- The gateway enforces required global fields on every login: for every platform, every onboarding mode (including
noneandplatform) and whether or notcentral_onboarding_enabledis set. While one is missing,/v1/auth/callbackand/v1/auth/resumeredirect to the identity UI onboarding page instead of issuing a handoff. - Users who signed in before a field became required are asked at their next login. Running gateway and platform sessions are not interrupted, and introspection is unchanged.
- There is no requirement version: the global status is
COMPLETEexactly when every required global field has a value. - A required global field cannot be cleared through
PATCH /v1/profile/me; the gateway answers409 PROFILE_FIELD_REQUIRED.
Onboarding runs in two steps, each a page of the identity UI, and resume brings the user back to the gateway after each:
| Step | When | Page URL | Fields shown |
|---|---|---|---|
| 1. Global profile | A required global field is missing (any mode) | …/onboarding?platform={key}&resume={tx}&scope=global | Global fields without a value |
| 2. Platform | central mode and the platform status is not COMPLETE | …/onboarding?platform={key}&resume={tx} | Platform fields without a value |
Example: a new user signs in to IESF Card, which requires a full name, while the global requirements make the date of birth mandatory. The user first enters the date of birth, then, on the next page, the full name, and only then reaches IESF Card. A user who already gave their date of birth on another platform goes straight to the second page; in none or platform mode there is no second page.
The identity UI never asks again for what the user has already answered: on both pages it shows only the fields whose current value is empty (the gateway still returns every active field with its value, so platforms rendering their own UI can show the full form).
GET /v1/onboarding/{platformKey}/requirements lists the global fields first with scope: "GLOBAL" and platformId: null, then the platform's fields with scope: "PLATFORM". A platform PROFILE_FIELD that asks for a globally collected profile field is folded into the global one, which is then required if either of them is. The platform's status and complete count the global fields too. A platform CUSTOM_FIELD can no longer use a canonical profile key as its fieldKey.
The handoff exchange and POST /v1/session/bootstrap report the global result separately as profile: { status: "COMPLETE" | "INCOMPLETE", missingFields }.
Status model
Server-calculated statuses:
NOT_STARTEDIN_PROGRESSCOMPLETE
COMPLETE means every active required field has a value and user_platforms.completed_requirement_version equals the platform’s current requirement_version. Changing field definitions bumps requirement_version and moves previously complete memberships back to IN_PROGRESS.
On every login (and POST /v1/session/bootstrap), when no required field is missing the gateway records the completion for the current requirement_version itself, so the handoff reports COMPLETE even in none and platform mode, where no step calls POST /v1/onboarding/{platformKey}/complete. IN_PROGRESS therefore always comes with a non-empty missingFields.
Schema administration (/v1/platforms/{platformKey}/onboarding/fields) also works for inactive platforms, so the schema can be prepared before activation; the user-facing onboarding APIs answer 404 until the platform is active.
The handoff payload includes:
json
{
"status": "IN_PROGRESS",
"requirementVersion": 4,
"missingFields": ["dateOfBirth", "federationId"],
"canCompleteCentrally": true
}User-facing onboarding APIs
Authenticated with the gateway cookie or an identity user Bearer token. A platform calls them from its BFF, sending the exchanged gatewayToken as Cookie: iesf_auth_session=…, with its own Origin on writes. See Platform integration, step 6.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/onboarding/{platformKey}/requirements | Active fields + currentValue + requirementVersion + platformDisplayName |
GET | /v1/onboarding/{platformKey}/status | Calculated status + missingFields |
PUT | /v1/onboarding/{platformKey}/values | Submit field map; returns updated requirements |
POST | /v1/onboarding/{platformKey}/complete | Mark complete only if server status has no missing fields |
Completion with missing required values → 409 (Onboarding is incomplete: …).
Rendering guidance
- Render
fieldsinsortOrder - Map
fieldTypeto a known safe component - Treat
uiConfigas display hints only (no HTML / executable content) PROFILE_FIELDvalues update canonical profile columns;CUSTOM_FIELDvalues are stored as JSONB per definition
Identity UI implementation
The identity UI (identity-web) renders the central-mode step on the host of the environment that signed the user in:
text
{identity host}/env/{key}/onboarding?platform={platformKey}&resume={transactionId}The /env/{key} prefix selects the environment (default for the host's default one) and the page continues at /onboarding?…, so DEV and TEST logins show the environment ribbon. The page is the same centred card as sign-in: heading, schema-driven fields (grouped by uiConfig.section), and one Save and continue action. It supports all field types in the API schema, orders them by sortOrder, and applies only the safe width, section and help-text hints from uiConfig.
On submit, the page validates the values against the field rules, sends typed values to PUT .../values, then calls POST .../complete. It navigates to /v1/auth/resume?transaction=... only when the completion response is COMPLETE; the gateway re-evaluates status again before issuing the handoff. The page runs before the platform receives a session, so calls go to the Central Gateway with credentials: include and rely on the gateway HttpOnly cookie.
For the complete frontend flow, field mapping, deployment requirements, failure behavior, and operational checklist, see Central onboarding.
Cookie writes
PUT / POST with cookie auth require an allowlisted Origin: an entry in CORS_ORIGINS, an active identity environment's host, or the origin of a return URL registered on an active platform. Design platform-hosted onboarding as credentialed browser calls from an allowlisted origin.
Global profile APIs
| Method | Path | Purpose |
|---|---|---|
GET | /v1/onboarding/global/requirements | Active global fields with the current profile values |
PUT | /v1/onboarding/global/values | Validate and save global values to the canonical profile (cookie writes need an allowlisted Origin) |
GET | /v1/onboarding/global/status | COMPLETE or INCOMPLETE with missingFields |
There is no complete call: the gateway re-evaluates the global requirements on resume and on every later login.
Central mode resume
After the identity UI step completes, the browser navigates to:
http
GET /v1/auth/resume?transaction={transactionId}The gateway binds the transaction to the authenticated gateway-session user, re-runs bootstrap, and issues the handoff only when status is COMPLETE. Incomplete users are sent back to:
text
{identity host}/env/{key}/onboarding?platform={platformKey}&resume={transactionId}Schema administration (not for ordinary BFF login)
Field CRUD lives under /v1/platforms/{platformKey}/onboarding/fields and requires onboarding:schema:read / onboarding:schema:write (plus platform claim checks unless platforms:admin). These are operational APIs, not part of the login handoff.
Operators typically manage them from the IESF Card UI — see Admin operations (IESF Card).