OIDC SSO
Connect an OIDC identity provider to self-hosted Proliferate.
Proliferate connects to any OIDC identity provider: Okta, Entra ID, Google Workspace, Keycloak, or your own. Users sign in through your identity provider, and accounts are created in your organization automatically on first sign-in. There is no separate user-import step.
SSO is configured entirely through environment variables on the Proliferate server. It is an add-on: the base install works without it, and SSO runs alongside email & password and GitHub sign-in rather than replacing them.
Set up
Register Proliferate in your identity provider
Create an OIDC client (a standard "web application" using the authorization code flow) in your identity provider and set the redirect URI to:
Copy three values for the next step: the issuer URL, the client ID, and the client secret. Common issuer URLs:
- Okta:
https://<your-org>.okta.com(or your custom authorization server) - Entra ID:
https://login.microsoftonline.com/<tenant-id>/v2.0 - Google Workspace:
https://accounts.google.com
Configure the Proliferate server
Add the SSO variables to .env.static in your deploy bundle and apply with
./update.sh. The server reads the authorization, token, and JWKS
endpoints from the issuer's discovery document, so the issuer URL is usually
all it needs.
Verify
Open the desktop app pointed at your server. The sign-in screen offers a
"Continue with Acme SSO" option (your SSO_DISPLAY_NAME); clients discover
the connection through the public GET /auth/sso/discover probe. Sign in
through your identity provider and confirm you land in the app as a member of
your organization.
Automatic account creation (JIT provisioning)
SSO_JIT_POLICY controls what happens when someone your identity provider
authenticates does not have a Proliferate account yet:
| Value | Behavior |
|---|---|
create_member | Accounts are created on first sign-in and added to your organization with the SSO_DEFAULT_ROLE role (default member). The right choice for most installs. |
existing_user | Only people who already have a Proliferate account can sign in through SSO. No new accounts are created. |
disabled | The default. Every first-time SSO sign-in is rejected with a specific, actionable error (sso_jit_disabled: "ask an admin to enable JIT provisioning or invite you"), not a silent failure — so set this variable explicitly once you decide who should be let in. |
Because SSO_JIT_POLICY defaults to disabled, enabling SSO alone does not
let anyone in yet. Either set SSO_JIT_POLICY=create_member (or
existing_user), or pre-create/invite the accounts that should use SSO first.
Two guardrails apply to every SSO sign-in regardless of policy:
- The identity provider must return a verified email address; sign-ins without one are rejected.
- The
ADMIN_EMAILSadmin floor is asserted at every login, including SSO logins, so listed operators keep admin no matter which method they sign in with.
Allowed domains
SSO_ALLOWED_DOMAINS is a comma-separated list of email domains, checked on
every SSO sign-in. Leave it empty to accept any identity your provider
authenticates; set it to scope sign-in to your corporate domains:
This is separate from ALLOWED_EMAIL_DOMAINS, which gates email and password
self-registration. SSO arrivals do not go through the invite allowlist;
they are governed by the JIT policy and SSO_ALLOWED_DOMAINS instead.
Internal identity providers
By default, the issuer URL and every endpoint discovered from it must be HTTPS and resolve to a public IP address — a guard against SSRF through a misconfigured or malicious OIDC connection. If your identity provider is only reachable on an internal network (no public DNS, plain HTTP, or a private IP), set:
This disables that guard for all OIDC provider URLs, so only set it when you control network access to the identity provider — it is the deliberate trade-off for connecting an internal IdP.
Works alongside email & password
SSO is additive: enabling it does not turn off email & password or GitHub
sign-in. SSO_LOGIN_POLICY supports optional today; setting it to
required is rejected, and enforced SSO-only login is planned.
Keep email & password available as the break-glass path. If your identity
provider is down or misconfigured, an operator listed in ADMIN_EMAILS can
still sign in with a password and fix the connection.
Environment variable reference
Every variable also accepts a PROLIFERATE_ prefix (for example
PROLIFERATE_SSO_ENABLED).
| Variable | Purpose |
|---|---|
SSO_ENABLED | Turns the deployment SSO connection on. |
SSO_OIDC_ISSUER_URL | Your identity provider's issuer URL; endpoints are read from its discovery document. |
SSO_OIDC_CLIENT_ID | Client ID of the OIDC client you registered. |
SSO_OIDC_CLIENT_SECRET | Client secret of that client. |
SSO_JIT_POLICY | disabled (default), existing_user, or create_member. |
SSO_DEFAULT_ROLE | Role given to JIT-created members; defaults to member. |
SSO_ALLOWED_DOMAINS | Comma-separated email domains allowed to sign in via SSO; empty allows all. |
SSO_DISPLAY_NAME | Label on the sign-in button; defaults to Company SSO. |
SSO_LOGIN_POLICY | optional (default); required is not supported yet. |
SSO_OIDC_SCOPES | Requested scopes; defaults to openid email profile. |
SSO_OIDC_TOKEN_ENDPOINT_AUTH_METHOD | Token endpoint auth method; defaults to client_secret_basic. |
SSO_OIDC_CALLBACK_BASE_URL | Overrides the base URL used to build the callback; defaults to the API base URL. |
SSO_OIDC_ALLOW_PRIVATE_PROVIDER_URLS | Default false. Set true only for an internal/private/http identity provider; see Internal identity providers above. |
For providers without a discovery document, the endpoints can be set
manually: SSO_OIDC_DISCOVERY_URL, SSO_OIDC_AUTHORIZATION_ENDPOINT,
SSO_OIDC_TOKEN_ENDPOINT, SSO_OIDC_JWKS_URI, and
SSO_OIDC_USERINFO_ENDPOINT. Most installs never need these.