The API behind single sign-on
Their IT department runs the identity provider. You are the relying party: you trust an id token, you map a sub to a local user, and you never see a password at all.
This is the one that gets asked for in procurement and is usually quoted as a quarter of work. It is mountSso plus a function that turns claims into a local user.
Back-channel logout is mounted for you. When their IdP says a session is over, it is over here too — which is the actual reason the requirement exists.
What you are carrying
@atlas/ssoOIDC discovery, PKCE, code exchange, id-token verification.
@atlas/dbState rows and the local user mapping.
@atlas/securityThe revocable session the back-channel logout kills.
@atlas/serverThe three routes it mounts.
Start it
bun add @wess/atlas
What it looks like
import { mountSso, ensureSsoStateTable } from "@atlas/sso"
await ensureSsoStateTable(db)
export const ssoRoutes = mountSso({
db,
issuerUrl: process.env.OIDC_ISSUER!,
clientId: process.env.OIDC_CLIENT_ID!,
clientSecret: process.env.OIDC_CLIENT_SECRET!,
// Claims in, your user out. This is the whole integration.
onAuthenticated: async (db, claims) => {
const user = await upsertUserBySub(db, claims.sub, claims.email)
return { localUserId: user.id, displayName: claims.name }
},
issueSession: (conn, user) => putSessionCookie(conn, user),
})