Guides / Single sign-on

Single sign-on

Connect your identity provider over SAML 2.0 or OIDC — setup, attribute mapping, certificate rotation, and what thump refuses to accept.

On this page

Single sign-on (SAML 2.0 and OIDC)

thump supports one identity provider per account, speaking either OIDC or SAML 2.0. Members whose email domain matches the connection sign in through your provider; everyone else keeps using GitHub, Google, or a passkey.

Both are on the free plan. Neither is brokered through a third-party identity service — thump talks to your IdP directly, so nothing about your logins leaves your Cloudflare account.

An account admin configures this at Settings → Single sign-on.


How a member signs in

  1. They enter their work email on the sign-in page.
  2. thump looks up the connection whose allowed email domains include that

domain.

  1. They're redirected to your identity provider.
  2. On return, thump verifies the response, provisions them into your account as

a member if they're new, and starts a session.

There's nothing to hand out — the sign-in page routes on the email domain alone. If no connection matches, the user falls back to normal sign-in.


SAML 2.0

What to give your identity provider

These are shown in Settings with copy buttons. They're derived from the URL your instance runs on, so a self-hosted deployment sees its own values.

FieldValue
Entity ID / Audience URIhttps://<your-instance>/auth/saml/metadata
Assertion Consumer Service (Reply) URLhttps://<your-instance>/auth/saml/acs
Name ID formatEmail address
BindingHTTP-POST

Service-provider metadata is served at /auth/saml/metadata if your provider prefers to import a file.

What thump needs from your identity provider

Paste the provider's metadata XML and thump reads all three values out of it. Or fill them in by hand:

FieldWhere to find it
Identity provider Entity IDOkta: "Identity Provider Issuer". Azure AD: "Microsoft Entra Identifier".
Sign-on URL (HTTP-Redirect)Okta: "Identity Provider Single Sign-On URL". Azure AD: "Login URL".
Signing certificateThe X.509 certificate the provider signs with. PEM or bare base64 both work.

The certificate is parsed when you save it, so a truncated paste fails on the settings page rather than at someone's first login attempt.

Attributes

thump needs an email address and would like a display name. It looks at, in order:

  1. The NameID, when its format is emailAddress.
  2. An attribute named email, emailaddress, mail, e-mail, or upn

matched on the last segment, so the Azure AD claim URIs (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress) and the LDAP OIDs (urn:oid:0.9.2342.19200300.100.1.3) work unchanged.

  1. The NameID, if it looks like an email address.

Display name comes from displayName, name, cn, or commonName by the same matching.

Certificate rotation

The signing certificate is a list. To rotate without downtime: add the new certificate alongside the old one, wait for your provider to cut over, then remove the old one. Any configured certificate may verify a response, so there is no window where logins fail.

IdP-initiated sign-in

Off by default. When enabled, members can start from your provider's app tile instead of thump's sign-in page.

It's off by default because it gives something up. A normal (SP-initiated) login carries an InResponseTo that names a request thump issued minutes earlier, and consuming that request is what makes a response single-use. An unsolicited response has no such request to bind to, so it's protected only by the assertion-ID replay cache. Turn it on if your users expect the app tile; leave it off otherwise.

What thump refuses

Every one of these has been someone's breach:

certificate embedded in the response's own KeyInfo is ignored entirely — trusting it would mean verifying a signature with a key the sender chose.

Reference URI must name the assertion thump goes on to read, and that ID must be unique in the document. This is what closes XML Signature Wrapping.

algorithm-confusion bypass, where an attacker MACs the document using your public certificate as the key.

bytes were signed.

instructions.** Comments enable the canonicalisation-splitting attacks (CVE-2017-11427 and relatives); DTDs enable XXE and entity expansion. No legitimate assertion contains any of them.

for every service provider on the internet.

recipient**, expired or not yet valid (two minutes of clock skew allowed), or replayed.

the signature is perfectly valid. An identity provider is trusted to authenticate its own users, not to assert arbitrary domains.

Not supported

your provider has assertion encryption on, turn it off for this app — everything is over TLS regardless. A response with an EncryptedAssertion fails with a message saying so rather than being silently ignored.

worth protecting; the response is what gets verified.

Troubleshooting

Sign-in failures come back to the sign-in page with a short code. The full reason is in your Worker logs (wrangler tail) — deliberately, because a detailed error on a public page is a tool for iterating towards a forgery.

CodeWhat happened
saml_bad_signatureThe response didn't verify. Usually a stale certificate after a provider-side rotation.
saml_wrong_audienceThe provider's Audience doesn't match the Entity ID in Settings.
saml_wrong_destinationThe provider's Reply URL doesn't match the ACS URL in Settings.
saml_unknown_requestThe login took longer than 10 minutes, or the response was replayed.
saml_replayedThis exact assertion was already redeemed.
saml_unsolicitedThe provider sent an unsolicited response and IdP-initiated sign-in is off.
saml_idp_refusedThe provider itself declined — usually the user isn't assigned to the app.
saml_no_emailNo attribute resolved to an email address. Map one in the provider.
saml_expired / saml_not_yet_validClock skew beyond two minutes, or a genuinely stale response.
domain_not_allowedThe verified email's domain isn't in the connection's allowed list.

OIDC

Authorization Code with PKCE against any OIDC provider (Okta, Azure AD, Google Workspace, Auth0, Keycloak…).

FieldValue
Redirect URIhttps://<your-instance>/auth/sso/callback
Grant typeAuthorization Code + PKCE
Scopesopenid email profile

thump needs the issuer URL (it fetches /.well-known/openid-configuration itself), a client ID, and a client secret. The secret is encrypted at rest with the instance vault key and is never returned by the API — leave the field blank when editing to keep the stored one.

id_tokens must be signed with RS256; the signature is checked against the provider's JWKS, along with the standard iss / aud / exp / nonce claims.


Provisioning members

Both protocols provision through the same path: on first successful sign-in the user is created and added to the connection's account as a member. Promoting someone to admin is done in Settings.

For lifecycle management — deactivating a member when they leave your directory — see SCIM 2.0 provisioning, which runs alongside either protocol.