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).
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
After callback (server)
| Component | Role |
|---|---|
| Your RP | OAuth 2.0 / OIDC client; token exchange, UserInfo, local session |
| SXM Identity Broker | Authorization server; code, access_token, id_token; UserInfo for profile and scope eid claims |
| Sint Maarten eID | Upstream 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):
https://localhost:9443/oauth2/oidcdiscovery/.well-known/openid-configuration| Purpose | Endpoint |
|---|---|
| Authorization | https://localhost:9443/oauth2/authorize |
| Token | https://localhost:9443/oauth2/token |
| UserInfo | https://localhost:9443/oauth2/userinfo |
| End session | https://localhost:9443/oidc/logout |
| JWKS | https://localhost:9443/oauth2/jwks |
| Requirement | Value |
|---|---|
| Grant type | authorization_code |
| PKCE | Required — S256 |
| Token endpoint auth | client_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
| Method | Path | Purpose |
|---|---|---|
| GET | /login | Start SSO — authorize with prompt=login |
| GET | /login/sso | Silent SSO — prompt=none (portal launcher) |
| GET | /auth/callback | OAuth redirect URI — validate state, exchange code |
| POST | /logout | Clear local session; optional broker end-session |
| GET | /auth/slo | Optional 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.
| Variable | Description |
|---|---|
| WSO2_BASE_URL | Broker public base URL |
| WSO2_CLIENT_ID | From onboarding |
| WSO2_CLIENT_SECRET | From one-time credential link |
| WSO2_REDIRECT_URI | Must byte-match broker registration |
| WSO2_SCOPE | e.g. openid profile email eid |
| WSO2_USERINFO_URL | Broker UserInfo — typically https://localhost:9443/oauth2/userinfo |
| WSO2_LOGOUT_URL | Broker end-session URL |
| WSO2_POST_LOGOUT_REDIRECT_URI | Registered post-logout redirect |
| WSO2_OAUTH_PROMPT | login for explicit sign-in — not consent |
7. Prompt and consent
| Scenario | prompt |
|---|---|
| User clicks Sign in with eID | login |
| Portal switcher / silent SSO | none |
| Never send from RP | consent |
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.
| Requirement | Detail |
|---|---|
| GET /login/sso | Silent SSO with prompt=none; fall back to /login on login_required |
| Redirect URI origin | Becomes PortalBaseUrl for the launcher (derived at approve time) |
| RP header widget | GET {eID API}/api/public/government-services?excludeClientId={your WSO2 client_id} |
| My eID tile | Link to {EID frontend}/citizen/profile — same-origin, not SSO |
| Never send | prompt=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
# 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-rpASP.NET Core — Eid settings
{
"Eid": {
"ApiBaseUrl": "http://localhost:5026",
"FrontendUrl": "http://localhost:3000",
"CitizenPortalPath": "/citizen/profile"
},
"Wso2": {
"ClientId": "YOUR_WSO2_CLIENT_ID"
}
}Smoke test public catalog
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
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=loginIdentity 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
subto your local user key — it is stable; email alone is not sufficient. - Store
eidwhen approved — the citizen's eID card number, distinct fromsub. - Full scope/claim matrix, UserInfo curl, and JSON examples: Claims & identifiers (UserInfo API).
Next steps
- Claims & identifiers — what data SSO releases and JSON examples.
- Quickstart — sandbox test in under 15 minutes.
- Onboarding — registration through production promotion.
- Laravel and ASP.NET Core copy-paste guides.