Identity Providers
Providers are the upstream identity systems BluAuth federates sign-in to. Each provider you configure here becomes a button on the hosted login page for users of the OAuth clients it's bound to. Users click the button, BluAuth redirects upstream, the upstream provider authenticates the user, and BluAuth issues a local session plus a downstream OIDC token.
Providers live at /admin/providers. Every provider record carries connection config (client ID, secret, endpoints), display config (label, icon, style), and trust config (JWKS, ID-token verification flags).
Provider types
| Type | When to use | Notes |
|---|---|---|
google | Google Workspace or consumer Google | Preset — endpoints auto-filled. |
microsoft | Entra ID / Azure AD, single- or multi-tenant | Preset. Set tenantId or leave blank for multi-tenant. |
okta | Okta as a preset with discovery | Specify orgDomain. |
github | GitHub Enterprise or consumer | Preset. |
oidc | Any generic OpenID Connect provider (Auth0, Keycloak, Ping, custom) | You provide discovery URL or issuer URI. |
saml | SAML 2.0 providers (legacy tenants only) | You provide metadata URL or XML. |
Configuring a preset provider
For Google, Microsoft, Okta, and GitHub, BluAuth ships presets that pre-fill endpoints. You provide only:
- Client ID and Client Secret from the upstream provider's admin console.
- Allowed scopes — defaults to
openid profile email. Tighten or widen as needed. - Display name (optional) — the button label. Defaults to the provider type's name.
- Tenant ID (Microsoft only, optional) — lock to a specific Entra tenant; leave blank for multi-tenant.
- Org domain (Okta only) — e.g.
acme.okta.com. BluAuth builds the issuer URL from this.
Save. The provider is created disabled — flip Enabled on the detail page once you've tested it.
Configuring a generic OIDC provider
For providers BluAuth doesn't preset:
- Set type to
oidc. - Provide either:
- Discovery URL (
discoveryUrl) — the full URL ending in/.well-known/openid-configuration. BluAuth fetches it and stores the metadata. - Issuer URI (
issuerUri) — BluAuth appends/.well-known/openid-configurationand fetches. Works for most standard providers.
- Discovery URL (
- Provide Client ID and Client Secret.
- Save. BluAuth attempts discovery. If it fails, the form surfaces the error (DNS, 404, bad TLS, etc.) so you can fix and retry.
OIDC endpoint resolution precedence
For OIDC providers, BluAuth resolves endpoints in this order when making a request:
- Manual override fields on the provider record —
authorizationUrl,tokenUrl,userInfoUrl,jwksUrl,endSessionUrl. If set, these always win. - Stored discovery metadata — the snapshot BluAuth fetched when you last ran discovery.
- Issuer-derived fallback URLs — a guess based on the issuer URI, for legacy Okta-style providers that don't publish discovery.
Manual overrides are rarely needed; use them only for providers with nonstandard endpoint paths.
Refresh discovery
The provider detail page has a Refresh discovery button. It re-fetches the upstream /.well-known/openid-configuration and updates the stored metadata without changing the record. Use after an upstream provider changes endpoints or rotates its JWKS key set.
View effective endpoints
The detail page also has View effective endpoints — this shows the resolved URLs BluAuth will actually use at request time, including whichever precedence tier they came from. Confirm before cutover.
Configuring SAML
SAML support is legacy-only. For new integrations, push for OIDC — SAML configuration is heavier, harder to debug, and the upstream ecosystem is deprecating it.
To configure:
- Set type to
saml. - Provide either:
- Metadata URL — BluAuth fetches the IdP metadata XML and caches it.
- Metadata XML — paste directly if the IdP doesn't publish metadata on a public URL.
- Provide the Entity ID (your service's SAML entity) — BluAuth's default is
urn:bluauth:{tenant}. - Upload the Signing certificate if you need to sign AuthnRequests.
- Save.
Strict ID-token verification
The validateIdTokenSignature flag (OIDC providers only) forces BluAuth to verify upstream id_token signatures against the discovered (or overridden) JWKS before accepting the login. Leave it on for new providers. Turn it off only for legacy integrations where the upstream doesn't publish a JWKS — and even then, push the vendor to fix it.
Secrets and encryption
Provider client secrets are encrypted at rest with AWS KMS before being written to the database. Consequences:
- They are never readable through the admin API or UI — the UI shows only a Last updated timestamp and a Rotate action.
- Rotating a secret uploads the new value and encrypts it; the old value is overwritten. No history.
- In local development without AWS credentials, secret storage succeeds but the round-trip back out will fail — meaning local dev can configure providers but can't actually complete an upstream sign-in against them. Use
pnpm devwith real AWS creds if you need end-to-end local testing.
Display: button text, style, and icons
Every provider has three display fields that shape how it renders on the hosted login page.
Button text
The Button Text field overrides the default button label. Defaults:
google→ "Continue with Google"microsoft→ "Continue with Microsoft"okta→ "Continue with Okta"github→ "Continue with GitHub"oidc→ the provider's display name or "Continue with SSO"saml→ the provider's display name or "Continue with SSO"
Override when the tenant has a specific voice — e.g. "Sign in with your Acme account" for a tenant Okta that users know by a different internal name.
Style variant
The Style Variant field (styleVariant) controls how much brand chrome the button carries:
auto(default) — BluAuth picks based on provider type. Google and Microsoft get their brand colors; generic OIDC stays neutral.neutral— match the theme's surface. No brand coloring.brand— force the provider's brand colors and icon regardless of type.
neutral is the right choice for tenants whose design system doesn't accommodate external brand colors (the Precision Curator system, for example, rarely wants Google-red sitting in an emerald palette). Flip to neutral and upload a custom icon if you still want the provider recognizable.
Icon
By default, BluAuth uses Lucide icons chosen by type (Chrome for Google, GitHub for GitHub, key-round for OIDC, file-lock for SAML, shield for unknown). Upload a custom icon (under 512 KB, SVG preferred) to replace the default. See the assets guide for upload mechanics.
Testing a provider before enabling
New providers are created disabled. Before you flip Enabled:
- Bind the provider to a test OAuth client (preferably one with a restricted user base — a staging app, not production).
- Open the hosted login for that client in a browser.
- Click the provider button.
- Complete the upstream flow with a test account.
- Verify:
- You land back at BluAuth's callback with no error.
- A user record is created (or linked, if the user existed).
- The user's email and name are populated from the provider.
- The user is redirected to the client's default post-login URL.
If any step fails, check the provider detail page's Recent events panel — every auth attempt writes provider.authorize.* events with error details.
Only flip Enabled after the test passes. Enabled providers show on the hosted login for every client they're bound to, immediately.
Binding providers to clients
A provider becomes visible to users only when it's bound to an OAuth client. Manage bindings at /admin/clients/:id/providers — the provider list there shows every configured provider and a checkbox to include it in the client's login page.
This lets you offer different provider mixes per tenant from the same BluAuth instance:
- Client A (internal tool) — Google, Okta, local password.
- Client B (partner app) — only SAML (partner IdP).
- Client C (consumer launch) — Google, Microsoft, local password.
See the clients guide for the binding UI.
Ordering
Providers appear on the hosted login in the order configured on the client binding page. Drag the rows to reorder — the order persists immediately. Put the most-used provider first; users click the top button ~60% of the time.
The local password (email/password) field is always shown below provider buttons; you cannot reorder it into the provider list.
Disabling without deleting
Flip Enabled off on the provider detail page to hide it from the hosted login without deleting the record. Useful when:
- An upstream provider is temporarily down and you want to avoid click-through errors.
- You're rotating a client secret and want a quiet window.
- You're deprecating a provider over time — disable first, communicate, then delete.
Disabled providers remain in the database and are still returned by the admin API, but they do not render on the hosted login for any client.
Deletion
Deleting a provider is permanent — it also removes every binding to OAuth clients. Users who previously signed in via that provider retain their session until it expires; they cannot re-authenticate via the deleted provider. Their linked identity row stays on the user record until the admin deletes it manually.
Prefer Disable over Delete unless you're cleaning up a record that was created in error.
Common failure modes
| Symptom | Likely cause |
|---|---|
| "Invalid redirect_uri" on callback | Upstream provider's allowed redirect URIs don't include <bluauth>/oauth2/callback |
| Discovery succeeds but token exchange fails | Client secret wrong or rotated upstream — rotate in BluAuth |
id_token rejected after successful upstream login | validateIdTokenSignature is on and the upstream JWKS isn't reachable |
| Users complete sign-in but get looped back to login | Scope misconfigured — ensure allowedScopes includes at least openid, profile, email |
| Provider button shows but clicking does nothing | Provider is disabled, or binding to this client was removed |
| Google button shows even when user expected only Okta | Provider bound to a client other than the one you expected — check /admin/clients/:id/providers |
Next
- Clients — bind providers to OAuth clients.
- Users — see linked provider identities on user records.
- Theme studio — assets — upload custom provider icons.