ObjectStack open source ships two built-in social sign-in implementations, both wired by os serve from deployment env vars:
Google OAuth: configure in Setup → Authentication, or from
GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET deployment env vars
GitHub OAuth: configure from GITHUB_CLIENT_ID and
GITHUB_CLIENT_SECRET deployment env vars
Additional providers should be contributed by product or enterprise packages through
the auth:configure hook. Those packages can add better-auth socialProviders
or OIDC/generic OAuth providers without forking @objectstack/plugin-auth.
The Studio login and registration pages automatically render Continue with ...
buttons for every enabled provider returned by /api/v1/auth/config.
The providers below are examples for enterprise or product packages, not built-in
open-source settings. A package can register them by listening to auth:configure
and mutating the draft auth config.
The env-var names shown below (e.g. MICROSOFT_CLIENT_ID, APPLE_CLIENT_ID) are
illustrative for an extension package's own reader code — unlike GOOGLE_* and
GITHUB_*, the framework does not read them out of the box, so an extension
must wire them in its auth:configure handler.
Under Certificates & secrets, create a new client secret.
MICROSOFT_CLIENT_ID=your-azure-app-client-idMICROSOFT_CLIENT_SECRET=your-azure-client-secret# Optional: restrict to a single tenant (default: "common" — all Microsoft accounts)# MICROSOFT_TENANT_ID=your-tenant-id
Admin-managed OIDC SSO ships in the open framework: @objectstack/plugin-auth
registers external IdPs through @better-auth/sso, and admins add them without
code from Setup → SSO Providers (see the ADR-0069 note below). The
oidcProviders config shown here is the in-process path for framework or product
packages that prefer wiring providers in code, or contributing them through
auth:configure.
Admin-managed external IdP (ADR-0069). Recent releases add a
per-environment external-IdP path built on @better-auth/sso and surface an
sso flag in the public /auth/config (features.sso) so a client can show
an enterprise-login button when SSO is configured. Admins register providers
without code from Setup → SSO Providers — both OIDC (Okta, Entra,
Auth0, Keycloak, …) and SAML 2.0 (see SAML 2.0
below). The oidcProviders extension shown here remains the in-process path
for framework/enterprise packages that prefer wiring providers in code.
SAML 2.0 is provided natively by @better-auth/sso (the same package behind the
OIDC path) — no custom plugin or extension is needed. Admins register a SAML
IdP from Setup → SSO Providers → Register SAML Provider, which posts to the
env-side bridge at POST /api/v1/auth/admin/sso/register-saml.
User enters their work email (or clicks the enterprise-login button).
Client calls POST /api/v1/auth/sign-in/sso with { email, callbackURL }.
The email domain is matched to the registered provider; the response is a
redirect to the IdP's entryPoint carrying a signed SAMLRequest.
The IdP authenticates the user and POSTs a SAML assertion back to the SP ACS
URL; @better-auth/sso (samlify) validates the signature/timestamp, then
creates a session and redirects to callbackURL.
Signature, timestamp, and replay validation are handled by @better-auth/sso
(samlify). You only supply the IdP's signing certificate at registration time.
Expected response (abbreviated — getPublicConfig() also returns disableSignUp/requireEmailVerification on emailPassword and additional features keys such as multiOrgEnabled, oidcProvider, deviceAuthorization, and admin):
OS_AUTH_SECRET must be set to a random string in production (a long random value of 32+ characters is recommended). AUTH_SECRET and BETTER_AUTH_SECRET are accepted as deprecated legacy aliases and emit a deprecation warning. If no secret is set, the auth plugin is skipped in production.
OS_AUTH_URL (or OS_BASE_URL as a fallback) must match the domain registered with each provider; it determines the base URL used to build OAuth callback URLs.
Never commit client secrets to source control — use a secrets manager in production.
The redirect URI registered with each provider must match exactly: https://<your-domain>/api/v1/auth/callback/<provider-id>.