Relying party documentation

Sign in with eID — integration standard

OpenID Connect via the SXM Identity Broker. Your application integrates with the broker; citizens authenticate on the national eID login experience (multi-factor).

Standard v1.1Updated 26 October 2026OpenID Connect 1.0 · OAuth 2.1 · PKCE S256

1. Purpose

Relying party applications (portals, line-of-business systems, partner services) implement Sign in with eID using the national identity platform. Your app receives OIDC tokens from the SXM Identity Broker; it does not handle eID passwords directly in production.

2. Architecture

Citizen browserYour RP (/login)SXM Identity BrokerSint Maarten eID (MFA)Your RP (callback)

After callback (server)

Exchange code (token endpoint)GET UserInfo (access_token)Persist sub + claims
ComponentRole
Your RPOAuth 2.0 / OIDC client; token exchange, UserInfo, local session
SXM Identity BrokerAuthorization server; code, access_token, id_token; UserInfo for profile and scope eid claims
Sint Maarten eIDUpstream IdP — citizen credentials and MFA
eID platform (onboarding)Provisions your OAuth application after approval

3. Prerequisites

  • RP registration submitted (Register RP or RP portal).
  • Admin approval and sandbox OAuth application on the broker.
  • HTTPS redirect URIs for non-local environments.
  • Authorization Code flow with PKCE (S256).
  • Stable subject identifier storage (sub claim) in your user database.

4. OpenID Connect contract

Load broker metadata from discovery (replace host if your onboarding email specifies a different environment):

Discovery URL
https://localhost:9443/oauth2/oidcdiscovery/.well-known/openid-configuration
PurposeEndpoint
Authorizationhttps://localhost:9443/oauth2/authorize
Tokenhttps://localhost:9443/oauth2/token
UserInfohttps://localhost:9443/oauth2/userinfo
End sessionhttps://localhost:9443/oidc/logout
JWKShttps://localhost:9443/oauth2/jwks
RequirementValue
Grant typeauthorization_code
PKCERequired — S256
Token endpoint authclient_secret_post (unless platform specifies otherwise)
Scopes (standard)openid profile email eid

4.1 After callback

On your redirect URI, validate state, then perform the server-side steps shown in the architecture diagram: exchange the authorization code at the token endpoint (include code_verifier), call UserInfo with the broker access_token, and create or update the local user from sub plus approved claims.

5. Required routes

MethodPathPurpose
GET/loginStart SSO — authorize with prompt=login
GET/login/ssoSilent SSO — prompt=none (portal launcher)
GET/auth/callbackOAuth redirect URI — validate state, exchange code
POST/logoutClear local session; optional broker end-session
GET/auth/sloOptional front-channel logout target (200 HTML)

Between login and callback, store state and code_verifier in a server session or short-lived encrypted cookie. Map users by sub, not email alone.

6. Configuration

Store credentials in environment variables or a secrets manager — never commit client secrets.

VariableDescription
WSO2_BASE_URLBroker public base URL
WSO2_CLIENT_IDFrom onboarding
WSO2_CLIENT_SECRETFrom one-time credential link
WSO2_REDIRECT_URIMust byte-match broker registration
WSO2_SCOPEe.g. openid profile email eid
WSO2_USERINFO_URLBroker UserInfo — typically https://localhost:9443/oauth2/userinfo
WSO2_LOGOUT_URLBroker end-session URL
WSO2_POST_LOGOUT_REDIRECT_URIRegistered post-logout redirect
WSO2_OAUTH_PROMPTlogin for explicit sign-in — not consent

7. Prompt and consent

Scenarioprompt
User clicks Sign in with eIDlogin
Portal switcher / silent SSOnone
Never send from RPconsent

8. Portal switcher widget

After admin approval, your application appears automatically in the eID citizen header launcher and in sibling government portals — no manual link registration. Citizens open {PortalBaseUrl}/login/sso (prompt=none) to switch portals with an existing broker SSO session.

RequirementDetail
GET /login/ssoSilent SSO with prompt=none; fall back to /login on login_required
Redirect URI originBecomes PortalBaseUrl for the launcher (derived at approve time)
RP header widgetGET {eID API}/api/public/government-services?excludeClientId={your WSO2 client_id}
My eID tileLink to {EID frontend}/citizen/profile — same-origin, not SSO
Never sendprompt=consent from your RP

Full step-by-step copy-paste guides: Laravel and ASP.NET Core (steps 12–16). Production reference: COCI/Tax portal-switcher + EidGovernmentPortalCatalog.

Laravel — catalog env

EID_* .env (excerpt)
# Government service launcher (dynamic catalog from eID)
EID_API_BASE_URL=http://localhost:5026
EID_FRONTEND_URL=http://localhost:3000
EID_CITIZEN_PORTAL_PATH=/citizen/profile
GOVERNMENT_PORTAL_ID=my-rp

ASP.NET Core — Eid settings

appsettings.json (excerpt)
{
  "Eid": {
    "ApiBaseUrl": "http://localhost:5026",
    "FrontendUrl": "http://localhost:3000",
    "CitizenPortalPath": "/citizen/profile"
  },
  "Wso2": {
    "ClientId": "YOUR_WSO2_CLIENT_ID"
  }
}

Smoke test public catalog

curl
curl -s "http://localhost:5026/api/public/government-services?excludeClientId=YOUR_WSO2_CLIENT_ID" | jq '.portals[] | {label, ssoLoginUrl}'

9. Security

  • HTTPS for redirect and post-logout URIs outside local dev.
  • Validate state on every callback.
  • PKCE on every authorization request.
  • Protect client secret — vault or env only.
  • Do not log tokens or secrets in production.
  • HttpOnly, secure session cookies where applicable.

10. Testing checklist

  • Discovery document loads from broker host.
  • /login redirects with client_id, code_challenge, code_challenge_method=S256.
  • Callback rejects wrong state.
  • Token exchange succeeds with code_verifier.
  • UserInfo GET https://localhost:9443/oauth2/userinfo returns 200 with Bearer access_token.
  • When scope eid is granted, UserInfo includes approved eid bundle (e.g. eid, citizen_status, rp_token).
  • User record created/updated with stable sub (and persisted claims per your allow-list).
  • /login/sso uses prompt=none only.
  • GET /api/public/government-services returns your tile after RP approval (excludeClientId = your WSO2 client_id).
  • Logout clears local session; broker logout if implemented.

11. Example authorization URL

GET authorize (structure)
https://localhost:9443/oauth2/authorize
  ?response_type=code
  &client_id={YOUR_CLIENT_ID}
  &redirect_uri={URL_ENCODED_CALLBACK}
  &scope=openid%20profile%20email%20eid
  &state={RANDOM_STATE}
  &code_challenge={PKCE_CHALLENGE}
  &code_challenge_method=S256
  &prompt=login

Identity data

Identity arrives in the broker ID token and/or UserInfo. For most RPs, UserInfo is the practical source for profile fields and scope eid claims after token exchange.

  • Map sub to your local user key — it is stable; email alone is not sufficient.
  • Store eid when approved — the citizen's eID card number, distinct from sub.
  • Full scope/claim matrix, UserInfo curl, and JSON examples: Claims & identifiers (UserInfo API).

Next steps