Skip to main content
A customer may want their staff to sign in to your app through the company’s own identity provider. There are two routes. An app whose sign-in is the backend Pramaan provisions (auth.backend.*) has no SAML. It can use the generic OpenID Connect route.

Through your own sign-in service

Set the enterprise connection up in your own sign-in service, then check each session with auth.token.verify as you already do. Pramaan checks the session token. Your sign-in service checked the enterprise identity. Membership, roles and linking accounts by email stay your app’s decisions, and an email domain alone grants nothing.

Generic OpenID Connect

Pramaan checks the identity; your app creates the user and the session.
  1. Save the connection once per customer with auth.enterprise-connection.create: your label for the customer, the issuer address, the client id and secret their administrator gave you, and your app’s exact redirect addresses. It needs approval. The secret is write-only, and no result carries the issuer or the client id. Who among your customers may set a connection up is your app’s own check.
  2. Start sign-in with auth.enterprise.start. Your server makes a fresh state, nonce and PKCE code verifier, keeps them in the visitor’s session, and sends state, nonce and the S256 codeChallenge. Redirect the visitor to the authorizationUrl you get back.
  3. When the visitor returns, compare state with the session’s. Stop if it differs.
  4. Redeem the code with auth.social.exchange: providerKey: "enterprise", the connectionRef, code, the same redirectUri, the state as it came back to your callback, pkceVerifier and expectedNonce. Only a sign-in you started is redeemed, once, within 10 minutes. Pramaan refuses a state that is not the one the sign-in was started with, so a mismatch is caught even if step 3 is forgotten; a refused state uses nothing up. Still make the comparison in step 3: only your app sees the visitor’s session.

Rules for your app

  • An identity is connectionRef plus subjectId, never subjectId alone. Keep the ref that create returned and key identities by your own id for that connection: a list row’s ref is another string for the same connection.
  • emailVerified is exactly what the identity provider stated. When it is false, do not link the sign-in to an existing account by that email and do not grant access because of it.
  • A verified email is still only what one customer’s identity provider says, and that provider can state any address. Never use the email to find or link an account from another connection or another way of signing in: find the account by connectionRef plus subjectId only.
  • The issuer must be an https address on a public host name, and its discovery document must name it exactly. The addresses that document names must be on the issuer’s own host, or on a host you listed in endpointHosts when you created the connection.
  • state is for enterprise sign-in only: required with connectionRef, and refused as an unknown field without it.
  • Redirect addresses are matched exactly. A code is used once: after an error, start again.