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:

https://<site-address>/auth/sso/oidc/callback

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.

SSO_ENABLED=true
SSO_OIDC_ISSUER_URL=https://login.corp.example.com
SSO_OIDC_CLIENT_ID=proliferate
SSO_OIDC_CLIENT_SECRET=<client-secret>
 
# Provisioning policy (see below)
SSO_JIT_POLICY=create_member
SSO_ALLOWED_DOMAINS=corp.example.com
 
# Shown on the sign-in button; defaults to "Company SSO"
SSO_DISPLAY_NAME="Acme SSO"

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:

ValueBehavior
create_memberAccounts 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_userOnly people who already have a Proliferate account can sign in through SSO. No new accounts are created.
disabledThe 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.
Warning:

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_EMAILS admin 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:

SSO_ALLOWED_DOMAINS=corp.example.com,subsidiary.example.com

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:

SSO_OIDC_ALLOW_PRIVATE_PROVIDER_URLS=true

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.

Info:

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).

VariablePurpose
SSO_ENABLEDTurns the deployment SSO connection on.
SSO_OIDC_ISSUER_URLYour identity provider's issuer URL; endpoints are read from its discovery document.
SSO_OIDC_CLIENT_IDClient ID of the OIDC client you registered.
SSO_OIDC_CLIENT_SECRETClient secret of that client.
SSO_JIT_POLICYdisabled (default), existing_user, or create_member.
SSO_DEFAULT_ROLERole given to JIT-created members; defaults to member.
SSO_ALLOWED_DOMAINSComma-separated email domains allowed to sign in via SSO; empty allows all.
SSO_DISPLAY_NAMELabel on the sign-in button; defaults to Company SSO.
SSO_LOGIN_POLICYoptional (default); required is not supported yet.
SSO_OIDC_SCOPESRequested scopes; defaults to openid email profile.
SSO_OIDC_TOKEN_ENDPOINT_AUTH_METHODToken endpoint auth method; defaults to client_secret_basic.
SSO_OIDC_CALLBACK_BASE_URLOverrides the base URL used to build the callback; defaults to the API base URL.
SSO_OIDC_ALLOW_PRIVATE_PROVIDER_URLSDefault 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.

On this page