6.9 KiB
Org Single Sign-On (OIDC) Setup
Let your team sign in to lean-ctx Cloud through your own identity provider (Okta, Microsoft Entra ID, Google Workspace, or any OIDC-compliant OP). Self-serve, no support ticket. Configure it once on the billing page, verify your domain via DNS, and optionally require SSO for everyone in the org.
Plan: Self-serve OIDC SSO is available on Business ($149/mo) and Enterprise plans. SAML SSO with SCIM provisioning is Enterprise-only. The org owner configures it; members just sign in.
Grandfather note: orgs that configured OIDC while it was Team-gated (pre-GL #533) keep their existing SSO working. New SSO setup requires the
sso_oidcentitlement (Business or Enterprise).
How it works
- You register a lean-ctx app in your IdP and paste the issuer, client ID and client secret into Account → Billing → Single sign-on.
- You prove you own the email domain by adding one DNS-TXT record.
- Members go to the login page, click Continue with SSO, enter their work email, and get redirected to your IdP. On return they have a normal lean-ctx session — no password, account auto-provisioned and added to your org (just-in-time).
- Optional: flip Require SSO so password logins for your domain are refused. The org owner always keeps password access (break-glass) so a misconfigured IdP can never lock you out.
The redirect URI to register in every IdP is:
https://api.leanctx.com/api/auth/sso/callback
Required scopes: openid email profile. Response type: code (Authorization
Code flow with PKCE — lean-ctx adds PKCE automatically).
Step 1 — Create the app in your IdP
Okta
- Admin → Applications → Create App Integration.
- Sign-in method: OIDC – OpenID Connect. Application type: Web Application.
- Sign-in redirect URI:
https://api.leanctx.com/api/auth/sso/callback. - Assign the people/groups who should have access.
- Copy Client ID and Client secret. Your issuer is
https://<your-org>.okta.com(Okta → Security → API → Authorization Servers; use theIssuer URI).
Microsoft Entra ID (Azure AD)
- Entra admin → App registrations → New registration.
- Redirect URI (type Web):
https://api.leanctx.com/api/auth/sso/callback. - Certificates & secrets → New client secret, copy the value.
- Overview → copy the Application (client) ID.
- Issuer:
https://login.microsoftonline.com/<tenant-id>/v2.0.
Google Workspace
- Google Cloud Console → APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Application type: Web application.
- Authorized redirect URI:
https://api.leanctx.com/api/auth/sso/callback. - Copy Client ID and Client secret.
- Issuer:
https://accounts.google.com.
Any spec-compliant OIDC provider works. lean-ctx reads the issuer's
/.well-known/openid-configurationfor endpoints and JWKS, so you only need the issuer URL — not individual endpoint URLs.
Step 2 — Configure lean-ctx
- Sign in as the org owner and open Account → Billing.
- In Single sign-on (OIDC), fill in:
- Email domain — e.g.
acme.com(the domain of your members' work email). - Issuer URL — from step 1.
- Client ID / Client secret — from step 1.
- Email domain — e.g.
- Save configuration. The secret is sealed (encrypted at rest) and never shown again; leave the field blank on later edits to keep the stored one.
Step 3 — Verify your domain
After saving, lean-ctx shows a DNS-TXT record. Add it at your DNS provider:
| Field | Value |
|---|---|
| Type | TXT |
| Name / Host | _leanctx-sso.acme.com |
| Value | leanctx-sso-verify=<token shown in the dashboard> |
Then click Verify domain. lean-ctx checks the record over DNS-over-HTTPS (Cloudflare, then Google). DNS can take a few minutes to propagate — if it isn't visible yet, wait and retry.
Domain verification is required before SSO accepts any login. It guarantees that only the org which controls a domain can authenticate its addresses, and that no two orgs can claim the same domain.
Step 4 (optional) — Require SSO
Once the domain is verified, toggle Require SSO for everyone in the org. While enabled:
- Password login and registration for your domain are refused.
- The org owner is always exempt (break-glass) — you can still sign in with your password if the IdP is down.
Turn it off any time to re-enable passwords.
What members experience
- Login page → Continue with SSO → enter work email.
- Redirect to your IdP, authenticate (and MFA, if your IdP enforces it).
- Back on lean-ctx, signed in. First-time users are created automatically (email pre-verified, no password) and added to your org.
- They run
lean-ctx login/ configure the MCP key exactly as a password user would — the session is identical.
Security model
- Authorization Code + PKCE (S256) on every flow, even with a confidential client secret.
- ID-token verification: JWKS signature,
iss,aud,exp, and a per-flownonce. Tokens signed withHS*/noneare rejected outright (alg-confusion defense) — only RSA/PS/ECDSA are accepted. - Asserted email must be under your verified domain, re-checked at the
callback.
email_verified:falsefrom the IdP is rejected. - Client secret is encrypted at rest (ChaCha20-Poly1305), decrypted only for the token exchange, never cached on the edge.
- No API keys in URLs: after a successful login the browser exchanges a single-use, 60-second handoff code for the session key.
- Owner break-glass: enforcement never applies to the owner's email.
Full protocol contract: docs/contracts/org-sso-oidc-v1.md.
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| Continue with SSO says no IdP found | Domain not configured or not verified yet. Finish steps 2–3. |
sso_error=verify_failed after IdP |
ID token failed validation. Check the issuer URL is exact and the client ID matches the IdP app. |
sso_error=idp_denied |
The IdP rejected the user (not assigned to the app, or consent denied). Assign the user/group. |
sso_error=expired |
The login took longer than 10 minutes, or the handoff code expired. Just start again. |
| Domain won't verify | TXT record not yet propagated, wrong host (_leanctx-sso.<domain>), or wrong value. Re-check and retry — DoH reads can lag your DNS edit by minutes. |
| A user can't sign in but others can | Their email domain differs from the verified domain, or the IdP reports email_verified:false. |
| Owner locked out with SSO required | Owners are exempt by design — use your password. If a non-owner needs in, turn off Require SSO temporarily. |
Still stuck? hello@leanctx.com or the
Discord community.