On this page
Single sign-on
Your people sign in to your workspace through your own identity provider, over OpenID Connect or SAML 2.0: Okta, Microsoft Entra ID, Google Workspace, Keycloak or any other that speaks either. It may sign in addresses at the domains your workspace proves it owns, and nothing else.
How it works#
An owner sets it up under Members & settings → Single sign-on, in three steps, each needing the one before. It is on the Pro plan.
- Prove your domains. Add each email domain your people use (
acme.com) and the TXT record it shows at your DNS provider. Colophon looks it up, and keeps looking: a record gone for a week and the domain lapses. One workspace holds a domain at a time, and public mail services (gmail.com and the like) cannot be added at all. - Connect your provider. Over OpenID Connect, register Colophon with it as a web application, then enter its issuer URL, the client ID and the client secret: Colophon reads the provider’s discovery document to find the rest, and keeps the secret encrypted. Over SAML 2.0, give it Colophon’s metadata and enter its entity ID, sign-on URL and signing certificate.
- Choose what it may do. Whether members at your domains must sign in through it, whether someone at your domains who signs in through it joins the workspace (and as what), and whether readers of your restricted sites may use it at the gate.
Every OpenID Connect application you register uses the same redirect URI:
https:/
Test sign-in on the settings page signs you in through the provider once without changing anything, to show the connection works. It has to have worked before members can be required to use it.
What your provider can and cannot do#
- It signs in addresses at your verified domains only. An address anywhere else is refused, and the refusal is in your audit log.
- An account belongs to the person the provider identifies (its
sub), not to an address. Someone renamed at your provider keeps their account. - It never takes over an account that already exists. Someone who signed up with Google or an emailed link before you set this up signs in that way once more, then chooses Continue with single sign-on: that links the two, and from then on either signs them in. Until they do, the provider asserting their address is refused.
- Each sign-in is checked as Colophon checks Microsoft’s: the issuer, the audience (your client ID), the signature against your provider’s published keys, the expiry, a one-time nonce and state, and PKCE. A sign-in cannot be replayed.
Requiring it#
With Require single sign-on for members on, a member whose address is at one of your domains acts in the workspace only on a session that came through the provider: in the dashboard, through colophon login, and in connected apps such as Claude (which they connect from a browser signed in that way). It takes effect on their next request: a session from Google or an emailed link is asked to continue through the provider instead. Members at other domains (a contractor at their own company) are not affected, and nor are API keys, which belong to the workspace rather than to a person. You can turn it on only from a session that came through the provider yourself, if your own address is at one of the domains.
Okta#
- In the Admin Console, Applications → Create App Integration: OIDC, Web Application.
- Grant type Authorization Code. Sign-in redirect URI: the one above. Assign the people or groups who should get in.
- Issuer:
https://<your-org>.okta.com, or with a custom authorization server, its issuer (https://<your-org>.okta.com/oauth2/default). The client ID and secret are on the app’s General tab.
Microsoft Entra ID#
- App registrations → New registration, Accounts in this organizational directory only, redirect URI (Web): the one above.
- Certificates & secrets → New client secret; note when it expires, since sign-in stops that day.
- Token configuration → Add optional claim, ID token,
email. Entra sends no address otherwise. - Issuer:
https://login.microsoftonline.com/<directory (tenant) ID>/v2.0. The multi-tenantcommonandorganizationsissuers are refused: your workspace trusts your directory, not every one.
Google Workspace#
- In Google Cloud, APIs & Services → OAuth consent screen, user type Internal, so only your organisation’s accounts can use it.
- Credentials → Create credentials → OAuth client ID, type Web application, authorised redirect URI: the one above.
- Issuer:
https://accounts.google.com.
Your Google Workspace people can already sign in with Continue with Google; this adds the option to require it, and makes the domain yours to vouch for.
Keycloak#
- In your realm, Clients → Create client, OpenID Connect, Client authentication on, Standard flow on.
- Valid redirect URIs: the one above.
- Issuer:
https://<keycloak>/realms/<realm>; the secret is on the client’s Credentials tab. Keycloak has to be reachable from the internet over https: Colophon does not fetch from private addresses.
Other providers#
Any OpenID Connect provider with a discovery document, the authorization code flow, a client secret (sent as HTTP Basic, or in the body when that is all it takes), RS256, PS256 or ES256 signatures, and an email claim. A provider that says email_verified: false is believed.
SAML 2.0#
Choose SAML 2.0 on the settings page. Colophon’s side is per workspace and never changes, since your subdomain never does:
| What your provider asks for | Value |
|---|---|
| Entity ID (audience, SP identifier), which is also the metadata URL | https:/ |
| ACS URL (reply URL, single sign-on URL) | https:/ |
| NameID | persistent. The email address works too, but then the account is tied to the address, and an address your provider later gives someone else reaches the old account |
| Attributes | email (or the provider’s usual email claim), and name if you like |
From your provider, enter its entity ID (issuer), its single sign-on URL, and its signing certificate. Colophon sends the request by redirect and takes the answer by POST, and checks:
- the signature against the certificate you entered, never one the response carries, on the assertion (by default), the response, or both, as you choose;
- that there is exactly one assertion, from your provider’s entity ID, for Colophon’s entity ID, sent to this ACS URL, inside its validity window (a minute’s slack either way, and at most five minutes old);
- that it answers the request this sign-in sent, from the browser that sent it, and that it is used once;
- a stable NameID: a transient one changes every sign-in, so nothing could be linked to it;
- and then everything above: your verified domains only, and never an account it was not linked to.
Sign-ins started from your provider’s own app launcher are refused unless you allow them; they answer no request of Colophon’s, so nothing ties them to the browser they arrive in. When you replace your provider’s certificate, paste the new one beside the old before it rolls over: each one is shown with its expiry.
- Okta: Applications → Create App Integration → SAML 2.0. Single sign-on URL: the ACS URL; Audience URI: the entity ID; Name ID format: Persistent (EmailAddress if you must: see NameID above); an attribute statement
email=user.email. The setup instructions on its Sign On tab show the issuer, the sign-on URL and the certificate. - Microsoft Entra ID: Enterprise applications → New application → Create your own → Single sign-on → SAML. Identifier: the entity ID; Reply URL: the ACS URL. Entra signs the assertion and sends the address as
emailaddress; the certificate is Certificate (Base64), the issuer is Microsoft Entra Identifier, the sign-on URL is Login URL. - Google Workspace: Admin console → Apps → Web and mobile apps → Add custom SAML app. ACS URL and Entity ID as above, Name ID format EMAIL, Name ID Primary email. Google shows the SSO URL, entity ID and certificate on the way.
- Keycloak: Clients → Create client → SAML, Client ID: the entity ID, Valid redirect URIs and Assertion Consumer Service POST Binding URL: the ACS URL, Sign assertions on, and an email mapper. The realm’s
/protocol/saml/descriptorlists its entity ID, sign-on URL and certificate.
Signing in#
People at your domains choose Use single sign-on on the sign-in page and enter their work address; Colophon finds your provider from its domain. A reader sent to sign in by one of your restricted sites sees Continue with your organisation’s sign-in when readers are allowed. See also Signing in and the audit log, which records every change here and every refusal.