Gerege SSO¶
Production · Layer 2 — Authentication / SSO ·
Repo: sso-gerege-mn · sso.gerege.mn
The OAuth2 / OpenID Connect provider for the private-sector line. Ecosystem applications and third-party relying parties (RPs) sign citizens in here.
Gerege SSO on Nexus is a different thing
In 2026-08 a new repository named sso-gerege-nexus was forked from
Gerege Nexus, and it is also called "Gerege SSO". The behaviour
documented on this page describes the sso-gerege-mn code running in
production. The new fork has no domain of its own yet, so the contract on
sso.gerege.mn is unchanged — RPs need to adjust nothing.
Three roles¶
1. Identity provider¶
RPs can offer Sign in with Gerege. What is supported:
| Capability | Notes |
|---|---|
| Authorization code + PKCE (S256) | The primary flow; safe even for public clients |
| Rotating refresh token | With reuse detection — replaying an old token invalidates the whole chain |
client_credentials |
Machine-to-machine integration |
| Access token | Opaque — its contents are not visible to the RP |
id_token |
JWT signed with RS256 |
| Discovery | /.well-known/openid-configuration |
| UserInfo | /userinfo |
2. eID proxy¶
Applications never access eID Mongolia directly. The SSO proxies the authorised eID services and forwards them only to registered applications.
The reason: eID credentials then live in exactly one place, and the audit trail runs as a single chain. Hand eID credentials to every application and rotation, revocation and tracing who did what all become impossible.
3. The single place applications are registered¶
OAuth clients and client secrets are created only here and stored only here. Not even the Developer Portal creates clients — it only explains what to do and deep-links into the SSO console.
Why a single place?
If credentials live in two systems at once, sooner or later they diverge: a client deleted on one side keeps working on the other, a rotated secret never reaches the other side, and so on. There is no reliable alternative to a single source.
Sign-in methods¶
| Method | Notes |
|---|---|
| eID | The primary method — QR code / mobile deep link / push by national ID number |
| Secondary — the first link must be verified by eID so it binds to a real person |
There are no passwords. There is no email/OTP sign-in either. That is a deliberate decision: a password that does not exist cannot leak.
Adjacent services¶
The related gateways that run out of the same repository:
-
dan.gerege.mn— the DAN identification gateway. -
gsign.gerege.mn— the signing gateway. -
xyp.gerege.mn— legal-entity and state-registry lookups.
Sessions and logout¶
- A session is a JWT access + refresh pair; the refresh token rotates.
- Logout invalidates both the refresh and the access token (access deny-list).
- After logging out, the user lands back on the domain they started from —
they are not thrown at
/login. This rule keeps the RP's user flow intact.
A piece of architectural history — dropping Hydra¶
The SSO used to run Ory Hydra as its OIDC provider. That dependency has now
been removed entirely and the mechanisms that were needed were rewritten as
in-house Go code (usecases/oidc). The separate Hydra database was merged
into the main one.
The result:
- one fewer external dependency,
- two databases and two migration chains became one,
- OIDC behaviour is now under our own control (in particular, it can be tied tightly to the eID flow).
The same code as the platform¶
The SSO is not a separately written system — it runs on exactly the same
code base as the platform template. The only difference is one setting: with
AUTH_MODE=provider the sign-in card is rendered here; with client it
redirects to an upstream SSO. The identical Docker image boots into either
role.
More: Shared code · Authentication & authorization.
Integrating (becoming an RP)¶
The broad steps:
- Register the application — create a client in the SSO console and obtain
client_id/client_secret. Register the redirect URIs exactly. - Read discovery — take the endpoints from
/.well-known/openid-configuration. - Implement authorization code + PKCE.
- Exchange the token — code → access + refresh +
id_token. - Validate the
id_token— RS256 signature,iss,aud,exp. - Fetch the user's details —
/userinfo.
For the detailed flow and a checklist, see Authentication & authorization.
Register redirect URIs exactly
The most common mistake in OIDC. A redirect URI must match
character for character — the trailing /, http vs https and the
port all matter. Forget to update this list when a domain changes and login
fails silently.
Full documentation¶
Implementation-level documentation (endpoint schemas, database model, the admin
guide for RP registration) lives inside the sso-gerege-mn repository.