Skip to content

Connect an app (RP)

This page covers both directions:

  1. Gerege App as a client — signing in through sso.gerege.mn (the RP side).
  2. A third-party app as a client — connecting to Gerege App's own OIDC provider.

A. Connecting Gerege App to Gerege SSO

In production Gerege App is registered on sso.gerege.mn as a confidential client.

Setting Value
client_id gerege-app-mn
redirect URI https://geregeapp.mn/sso/callback
post-logout https://geregeapp.mn/
scopes openid profile email
grant types authorization_code, refresh_token

Environment (backend.env):

SSO_ISSUER=https://sso.gerege.mn
SSO_CLIENT_ID=gerege-app-mn
SSO_CLIENT_SECRET=<secret>
SSO_REDIRECT_URI=https://geregeapp.mn/sso/callback
SSO_SCOPE=openid profile email

Flow:

  1. The user clicks "Sign in with Gerege SSO"/api/auth/sso/start.
  2. POST /v1/sso/start creates state (HMAC'd with SSO_STATE_KEY) and builds the authorize URL for sso.gerege.mn/oauth2/auth.
  3. The user authenticates with eID on the SSO.
  4. SSO redirects back to …/sso/callback?code&state.
  5. POST /v1/sso/callback exchanges the code, upserts the citizen by sso_sub and issues the app's own session (JWT).
Endpoint What
POST /v1/sso/start Build the authorize URL
POST /v1/sso/callback Code → tokens → local session
POST /v1/sso/native Mobile (PKCE, public client) flow
POST /v1/sso/logout RP-initiated logout

Logout redirects to sso.gerege.mn/oauth2/sessions/logout with id_token_hint and post_logout_redirect_uri.

Register the post-logout redirect

A client registered with only a login redirect will fail logout with "post_logout_redirect_uri is not whitelisted". Register the login and post-logout URIs together.

Getting invalid_client?

Either SSO_CLIENT_ID is not in the provider's client store, or the redirect URI does not match exactly. Check both.

B. Connecting a third-party app to Gerege App

When Gerege App's OIDC provider is enabled (OAUTH_ISSUER set), third-party apps can sign in through it.

1. Register a client

Admin → Applications → New app: name, redirect URIs, tags. Grant the gateway services you need (eid-proxy etc.) with checkboxes. You get a client_id and client_secret.

curl -X POST https://<issuer>/admin/api/v1/clients \
  -H 'Authorization: Bearer gsk_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "myapp",
    "client_name": "My app",
    "redirect_uris": ["https://myapp.mn/sso/callback"],
    "post_logout_redirect_uris": ["https://myapp.mn/"],
    "grant_types": ["authorization_code", "refresh_token"],
    "scope": "openid profile email"
  }'

2. Implement the flow

GET  https://<issuer>/.well-known/openid-configuration   ← every path from here
GET  https://<issuer>/oauth2/auth?…&code_challenge_method=S256
POST https://<issuer>/oauth2/token
GET  https://<issuer>/userinfo

Required: PKCE with S256. plain is not supported. Public clients (mobile, SPA) register with token_endpoint_auth_method: none and rely on PKCE.

3. Granting extra services

Sign-in works for every registered app through the base scopes (openid profile email) automatically. Extra services (such as the eID proxy) require a per-app grant, expressed as a service scope (svc:eid-proxy) in the client's allowed scopes.

Admin → Applications → the app → tick the service → Save.

See eID Service Proxy and API Gateway.

Common errors

Error Cause Fix
invalid_client Unknown client_id or mismatched redirect URI Check the registration
invalid_grant Code expired or code_verifier mismatch Check your PKCE
post_logout_redirect_uri is not whitelisted Logout URI not registered Add it to the client
403 calling a service Service not granted to the app Grant it in Admin
503 calling a service Service disabled in the gateway Admin → Gateway