Files
yvgude--lean-ctx/docs/guides/org-sso-setup.md
T
wehub-resource-sync 26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

6.9 KiB
Raw Blame History

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_oidc entitlement (Business or Enterprise).


How it works

  1. You register a lean-ctx app in your IdP and paste the issuer, client ID and client secret into Account → Billing → Single sign-on.
  2. You prove you own the email domain by adding one DNS-TXT record.
  3. 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).
  4. 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

  1. Admin → Applications → Create App Integration.
  2. Sign-in method: OIDC OpenID Connect. Application type: Web Application.
  3. Sign-in redirect URI: https://api.leanctx.com/api/auth/sso/callback.
  4. Assign the people/groups who should have access.
  5. Copy Client ID and Client secret. Your issuer is https://<your-org>.okta.com (Okta → Security → API → Authorization Servers; use the Issuer URI).

Microsoft Entra ID (Azure AD)

  1. Entra admin → App registrations → New registration.
  2. Redirect URI (type Web): https://api.leanctx.com/api/auth/sso/callback.
  3. Certificates & secrets → New client secret, copy the value.
  4. Overview → copy the Application (client) ID.
  5. Issuer: https://login.microsoftonline.com/<tenant-id>/v2.0.

Google Workspace

  1. Google Cloud Console → APIs & Services → Credentials → Create Credentials → OAuth client ID.
  2. Application type: Web application.
  3. Authorized redirect URI: https://api.leanctx.com/api/auth/sso/callback.
  4. Copy Client ID and Client secret.
  5. Issuer: https://accounts.google.com.

Any spec-compliant OIDC provider works. lean-ctx reads the issuer's /.well-known/openid-configuration for endpoints and JWKS, so you only need the issuer URL — not individual endpoint URLs.


Step 2 — Configure lean-ctx

  1. Sign in as the org owner and open Account → Billing.
  2. 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.
  3. 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

  1. Login page → Continue with SSO → enter work email.
  2. Redirect to your IdP, authenticate (and MFA, if your IdP enforces it).
  3. Back on lean-ctx, signed in. First-time users are created automatically (email pre-verified, no password) and added to your org.
  4. 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-flow nonce. Tokens signed with HS*/none are 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:false from 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 23.
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.