Skip to content
Open the app

Single sign-on, end to end

This guide follows a single sign-in from a student clicking "sign in with my university" to landing in their workspace, and shows what each party — the student, the institution's identity provider, and First Six — contributes along the way. It is the cross-cutting companion to the developer-focused OIDC flow.

The principle: no password ever reaches us, identity is proven by the institution's own IdP, and a sign-in only ever links to someone who already exists.

1. The student starts the sign-in

The student picks "sign in with my university". The request hits /auth/sso/{slug}/start, which generates the state, nonce, and PKCE verifier, stores them in HttpOnly cookies, and redirects the student to their institution's identity provider. The student never types a password into First Six.

2. The institution's IdP authenticates them

The student authenticates with their university the way they always do — including any MFA the institution enforces. First Six is not in this part of the loop at all; the IdP redirects back to /auth/sso/{slug}/callback with an authorization code.

Why PKCE

The PKCE verifier is a one-time secret the server generated at step 1. Even if the authorization code were intercepted, it can't be redeemed without that verifier — so a stolen code is useless on its own.

3. First Six verifies the response

The callback validates the state (CSRF protection), exchanges the code using the PKCE verifier and the client secret, and verifies the returned id_token against the IdP's JWKS — checking the issuer and audience. Only a response that passes every check proceeds.

The client secret lives server-side, not in the database

Only the public connection details (issuer, client id, discovery URL, scopes) live in the tenant's config. The OIDC client secret is held in server-side environment configuration, so it is never readable by the clients that can read the rest of the config.

The verified identity is linked to a First Six record that already exists — provisioned earlier through SIS sync. This is the rule that makes the whole onboarding order matter: SSO attaches a login to a known student or staff member; it never conjures a new one.

No roster, no sign-in

If the person isn't already in the system, there is nothing to link to and the sign-in fails. That is by design — it prevents anyone outside the synced roster from gaining an account. It also means the roster sync has to run before SSO goes live (see onboarding an institution).

5. The session, scoped by the database

On a successful link, an HttpOnly session cookie is minted. That cookie is the only thing that persists — and every later read is authorized through it by row-level security, so the student can only ever see their own institution's data. The isolation lives in the database, not in app code (see how your data is protected).

6. The student lands

The student arrives in their branded workspace and the experience begins. From their point of view it was one click and their usual university login; everything above happened in the redirect.

What this flow guarantees

  • No password reaches First Six; the institution's IdP is the sole authenticator.
  • A stolen authorization code is useless without the server-held PKCE verifier.
  • A sign-in can only attach to an existing, synced record — never create a new one.
  • Every read after sign-in is fenced to the right tenant by the database.

Common questions

Can IT test SSO before exposing it to students?

Yes. The connection can be verified before launch without students seeing it — see testing SSO before launch.

What if a student exists in the IdP but not in First Six?

The sign-in fails, because SSO links to an existing record and never creates one. Run SIS sync so the roster is present first.

Does First Six store the student's password?

No. Authentication happens entirely at the institution's IdP. First Six only ever receives a verified token, never a password.

Was this helpful?
Need more help?

The fastest answer is usually one question away.

Edit this page on GitHub