Skip to main content
Installation

Enterprise SSO

Analysts sign in with their corporate account: Caddy → oauth2-proxy → the IdP (Entra ID / Okta / Keycloak / AD). Roles map from IdP groups; audit traces to a person.

The default shape is the gateway's own password login plus the Users page. Companies with an IdP switch to docker-compose.sso.yml: accounts come from the IdP and the gateway no longer holds passwords. Do not run both.

Architecture

SSO chain

oauth2-proxy is a mature OIDC reverse proxy: unauthenticated requests are redirected to the IdP, and after login the verified identity is injected as request headers for the gateway. The gateway implements no login of its own and trusts only those headers. This is safe because the gateway is reachable only inside the proxy chain (every /api/* needs RST_GATEWAY_SHARED_SECRET) and oauth2-proxy overwrites the headers from its own session, so a client cannot forge them.

Protocol-agnostic: any front proxy that injects identity headers works, so SAML / LDAP fit too.

Connecting your IdP

Register an application

A confidential client with callback URI https://<hostname>/oauth2/callback. Note client_id, client_secret and the issuer URL.

Fill .env

OIDC_ISSUER_URL=https://login.microsoftonline.com/<tenant>/v2.0
OIDC_CLIENT_ID=<client id>
OIDC_CLIENT_SECRET=<client secret>
OAUTH2_PROXY_SKIP_OIDC_DISCOVERY=false
OAUTH2_PROXY_COOKIE_SECRET=<openssl rand -base64 32>
OAUTH2_PROXY_REDIRECT_URL=https://<hostname>/oauth2/callback
OAUTH2_PROXY_COOKIE_SECURE=true
OAUTH2_PROXY_REVERSE_PROXY=true
CADDY_SITE_ADDRESS=<hostname>
RST_GATEWAY_SHARED_SECRET=<openssl rand -hex 32>
RST_SSO_ENABLED=true
RST_SSO_ENFORCE=true

Role mapping

RST_RBAC_ADMIN_GROUPS=soc-admins
RST_RBAC_ANALYST_GROUPS=soc-l1,soc-l2
RST_RBAC_VIEWER_GROUPS=auditors

The IdP's groups claim enters the identity; a person in several groups gets the highest tier. In none = no role (can write, cannot administer) - to enforce read-only, list the group in RST_RBAC_VIEWER_GROUPS.

Start

./deploy.sh and choose auth 2 = SSO; or by hand docker compose -f docker-compose.sso.yml up -d (without --profile bundled-idp).

Key variables

VariableNotes
OIDC_ISSUER_URL / OIDC_CLIENT_ID / OIDC_CLIENT_SECRETIdP issuer and client credentials
OAUTH2_PROXY_SKIP_OIDC_DISCOVERYfalse for a real IdP; true only for the bundled Keycloak demo
OAUTH2_PROXY_COOKIE_SECRETSession cookie encryption key
OAUTH2_PROXY_REDIRECT_URLMust match the IdP registration
RST_SSO_ENABLEDFrontend shows the current user + sign-out
RST_SSO_ENFORCEtrue: gated /api/* without an identity gets 401; guards against a proxy that forgets to inject headers
RST_SSO_USER_HEADER / RST_SSO_GROUPS_HEADEROptional, override header names when using another front proxy

Classic AD domains

Analysts sign in with AD / LDAP accounts: Keycloak does user federation against the directory, binds to LDAP at login, and issues OIDC to oauth2-proxy as usual. Microsoft AD specifics: vendor=ad, connectionUrl=ldaps://dc.corp.local:636, usernameLDAPAttribute=sAMAccountName, uuidLDAPAttribute=objectGUID, userObjectClasses=person, organizationalPerson, user, a service account as bindDn. Add a group-ldap-mapper to map AD security groups into the groups claim for role mapping.

Demo

The archive's docker-compose.sso.yml bundles a Keycloak + OpenLDAP (--profile bundled-idp) for demos: analyst / analyst123 (Keycloak local), analyst.ldap / Ldap123! (LDAP federation). Its realm is a starter template - client secret, redirectUris: ["*"], sslRequired: none are demo values; tighten them or use your own IdP before production.

How the gateway uses the identity

  • Audit events carry the SSO identity in user, traceable to a person.
  • The top-right corner shows the current user; sign-out goes through /oauth2/sign_out.
  • The Account page cannot change the password; it lives in the IdP.

On this page