The OIDC flow
First Six authenticates students and staff through your institution's identity provider using OpenID Connect. The flow is implemented server-side (authorization code with PKCEProof Key for Code Exchange: a one-time secret the client generates so a stolen auth code can't be redeemed by anyone else.), so there is no third-party auth SDK in the browser and no password ever reaches us.
The flow
- Start
A sign-in hits
/auth/sso/{slug}/start, which sets the state, nonce, and PKCE verifier in HttpOnly cookies and redirects to your IdP's authorize endpoint. - Authenticate
Your IdP authenticates the user and redirects back to
/auth/sso/{slug}/callbackwith an authorization code. - Exchange and verify
The callback validates state (CSRF), exchanges the code using the PKCE verifier and client secret, and verifies the id_token against your IdP's JWKS (issuer and audience checked).
- Link and mint a session
The verified email/subject is linked to a First Six record, and an HttpOnly session cookie is minted. That cookie is the only thing that persists; every later read is authorized by it through row-level security.
Per-tenant configuration
Each institution has an sso_config object holding the public parts of the
connection:
{
"issuer": "https://login.microsoftonline.com/<tenant-id>/v2.0",
"client_id": "<application-client-id>",
"discovery_url": "https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration",
"scopes": "openid email profile"
}When discovery_url is set it resolves the authorize, token, and JWKS URLs for
you, so you usually only need the issuer, client id, discovery URL, and scopes
(which must include openid).
Only the public connection details live in the tenant config. The OIDC client secret is held in server-side environment configuration, not in the database, so it is never readable by the application clients that can read the rest of the config.
Microsoft Entra
For Microsoft Entra ID, the connection is:
- Register the app
Register First Six as an application in Entra and add the callback URL as a redirect URI. PKCE is mandatory for confidential clients on Entra.
- Collect the details
Take the Application (client) ID and your tenant id, and generate a client secret.
- Hand them to us
Give us the client id, the secret, and the tenant id (or the discovery URL). We store the secret server-side and put the rest in
sso_config.
Linking, not creating
This is the key behaviour to understand: a successful login links an identity to an existing record. It does not create one.
claim_sso_identity matches the verified email (or IdP subject) to a student or
staff row that already exists, and binds the auth identity to it. This is
just-in-time linkingJust-in-time linking: the account is connected at first login, but only if a matching record already exists.,
not just-in-time creation. If there is no matching row, the login fails. So the
roster has to be in place first, which is what
SIS sync is for. Provision the roster, then
turn on SSO.
Troubleshooting
A failed sign-in shows a plain SSO error: page carrying the specific
failure, worded below, so you can match what the user saw to the fix. IdP
errors are surfaced verbatim (capped in length) for the same reason.
The IdP shows an error before First Six ever loads
First Six was never reached, so this is the app registration. Nine times
out of ten the redirect URI: it must be exactly
https://<your-first-six-host>/auth/sso/{slug}/callback with your
institution's slug, character for character, including the scheme.
Check for a trailing slash, a www. difference, or a staging host left
in from testing.
SSO error: Token exchange failed
The page includes the IdP's own error text. invalid_client means
the client secret is wrong or has expired (Entra secrets expire; check
the app registration's Certificates and secrets blade and issue a new
one). invalid_grant usually means the authorization code was already
used or timed out: have the user start again from the sign-in page
rather than refreshing the callback URL.
SSO error: id_token verification failed
The token came back but did not verify. Check the config trio against
the app registration: the issuer must match what your discovery
document declares (for Entra, the tenant-specific v2.0 issuer, not
the common one), and the client_id must be the Application ID the
token is minted for, since it is checked as the token's audience.
SSO error: Nonce mismatch
The one-shot sign-in cookies did not survive the round trip. A stale tab replaying an old callback does this, as does a browser blocking cookies on the First Six domain. Start a fresh sign-in from the login page; if it repeats, check for an extension or policy stripping HttpOnly cookies.
The IdP sign-in succeeds but First Six cannot link the account
Linking, not creating: there was no roster row matching the identity
the IdP asserted. Either the student has not been synced yet (run
SIS sync first), or the email your
IdP asserts differs from the one on the roster: a personal alias, a
renamed account, or preferred_username differing from email.
The roster email and the asserted email must agree.
You are not authorised to sign in here.
The identity linked, but to a role this app refuses: a student account at the staff console door, or a non-owner at the operations console. That refusal is deliberate and happens before any session exists. Sign in to the app that matches the account.
Common questions
Do you support SAML?
The production path is OIDC. A SAML proof-of-concept exists, but converging a real SAML-federated institution onto the same identity-linking path is follow-up work. SAML is available per engagement: production SAML is enabled as part of an engagement that needs it, so raise it early in scoping if it's a hard requirement.
What happens if a user signs in before they're on the roster?
The login fails, because there's no record to link to. Run SIS sync first so every student resolves to a row, then enable SSO.
Which claim do you match on?
The verified email (or the IdP subject). Make sure the email your IdP asserts matches the email on the roster you sync.
Testing before you go live
You do not need your real IdP wired up to exercise this end to end. First Six ships a gated test identity provider (FakeU) that mints valid tokens against demo personas. See testing SSO before launch.
Next steps
Related
The fastest answer is usually one question away.