Enterprise SSO
Customers sign in with Okta, Entra ID, Google Workspace, Keycloak, ADFS and other identity providers (IdPs). Each provider is bound to one or more email domains. signInWithSSO({ email }) or { domain } picks the provider of that domain (a subdomain such as eng.acme.com matches acme.com; the most specific domain wins). The flow is SP-initiated and ends like OAuth with a normal PotaLab Base session.
// login page: "Continue with SSO"await base.auth.signInWithSSO({ email: "alice@acme.com", redirectTo: "https://app.example.com/auth/callback" })
// on /auth/callbackconst code = new URL(location.href).searchParams.get("code")!const { data, error } = await base.auth.exchangeCodeForSession(code)signInWithSSO also accepts domain or providerId, and skipBrowserRedirect to return the URL instead of navigating. Errors come back to redirectTo as ?error=<code>&error_description=....
Add a provider
Section titled “Add a provider”Providers are managed by the project owner in the dashboard or with the Management API (POST /v1/projects/{ref}/auth/providers/sso).
{ "kind": "oidc", "name": "Acme Okta", "issuer": "https://acme.okta.com", "client_id": "...", "client_secret": "...", "domains": ["acme.com"], "scopes": ["openid", "email", "profile"], "attribute_mapping": { "email_verified": "email_verified", "extra": { "department": "department" } } }Base runs OIDC discovery when you save and checks that the discovered issuer matches. The client secret is write-only. Register the returned callback_url as the redirect URI at your IdP.
{ "kind": "saml", "name": "Acme ADFS", "metadata_url": "https://.../FederationMetadata.xml", "domains": ["acme.com"] }You can pass metadata_xml instead of metadata_url. The IdP metadata must contain the signing certificate. Give your IdP admin the returned sp_metadata_url (or acs_url and sp_entity_id). Base requires signed assertions and the email NameID format. When the IdP rotates its certificate, PATCH .../sso/{id} with { "refresh_metadata": true } re-reads the metadata.
Use POST /v1/projects/{ref}/auth/providers/{id}/test to re-run discovery or the metadata download without changing anything.
Attribute mapping
Section titled “Attribute mapping”attribute_mapping supports email, email_verified, name, first_name, last_name, image and extra: { key: claim } (copied into the new user’s user_metadata). Defaults: OIDC email, email_verified, name, picture; SAML email (else the NameID), givenName plus surname or displayName.
Users and linking
Section titled “Users and linking”- An identity seen before signs in as its user.
- The asserted email must be inside the provider’s
domains, otherwiseemail_domain_not_allowed. - An existing user with the same email is linked only when the project allows linking, the IdP asserts a verified email (or the provider has
trust_email: true), and the local account’s email is verified. Otherwise sign-in is refused withemail_exists. - Otherwise the user is created just in time (
jit: true, the default) unlessjitisfalseor sign-ups are off (signup_disabled). - Banned users are refused (
user_banned).
Not supported
Section titled “Not supported”IdP-initiated SAML, SAML single logout, encrypted assertions, signed AuthnRequests, private_key_jwt client authentication, SCIM provisioning and domain-ownership verification.
Troubleshooting
Section titled “Troubleshooting”| Error | Meaning |
|---|---|
404 sso_provider_not_found |
no enabled provider for that domain or id |
?error=email_exists |
an account with that email exists and the linking rules did not allow linking |
?error=email_domain_not_allowed |
the IdP returned an email outside the provider’s domains |
?error=invalid_saml_response |
signature, audience, recipient, timestamps or request binding did not validate |
402 feature_not_in_plan |
your plan does not include SSO |