Skip to content

Single sign-on (SSO)

With SSO enabled, the sign-in page asks for an email or username first and sends each person to the right place: straight to your identity provider, or to a password (see Email-first sign-in, 1.16.0). People authenticate with your identity provider; CompassDocs validates the response and signs them in — no separate password to manage. Accounts can be created automatically on first sign-in, and existing accounts are matched by a confirmed email (see How accounts are matched).

CompassDocs speaks two protocols, and you can run either or both at once (the sign-in page offers each configured method):

  • OpenID Connect (OIDC) — first-class for Microsoft Entra ID, with a one-click setup, and works with any spec-compliant OIDC provider.
  • SAML 2.0 — for Okta, OneLogin, Google Workspace, Active Directory Federation Services (ADFS), Entra SAML apps, and any other SAML IdP.

Not sure which to pick? If your IdP offers both, OIDC is a touch simpler to wire up. Otherwise use whichever your IdP supports — the end-user experience and the account model are identical.


OpenID Connect (Microsoft Entra ID & others)

Section titled “OpenID Connect (Microsoft Entra ID & others)”

On Settings → Single sign-on, click Set up automatically with Microsoft, then sign in at microsoft.com/devicelogin with the code shown, as a tenant admin (Global Administrator or Application Administrator). CompassDocs creates the app registration — with the redirect URI already set — plus a 24-month client secret and the service principal, and fills in and enables the configuration for you. The one-time sign-in token is discarded afterward; CompassDocs keeps no standing Microsoft permission.

The panel shows the secret’s expiry date — set a reminder to rotate it before then. Prefer to do it by hand (or your tenant blocks the device-code flow)? Follow the manual steps below.

In the Microsoft Entra admin center → Identity → Applications → App registrations → New registration:

  • Name: e.g. CompassDocs
  • Supported account types: Accounts in this organizational directory only (single tenant)
  • Redirect URI: choose Web and enter https://YOUR-COMPASSDOCS-HOST/api/ee/sso/callback

After creating it, note the Application (client) ID and Directory (tenant) ID from the Overview page.

Then under Certificates & secrets → New client secret, create a secret and copy its value immediately (it’s only shown once).

That’s all — sign-in uses plain OpenID Connect, so no API permissions or admin consent are required. (If you also use the Microsoft 365 directory sync, that’s a separate app registration with its own permissions.)

Under Settings → Single sign-on, enter the Tenant ID, Client ID, and Client secret (the secret is write-only — once saved, it’s never shown again). Then choose your policies:

  • Create accounts on first sign-in — new people get an account automatically, with the role you pick (default viewer). Turn it off to allow only people you’ve already added.
  • Allowed email domains — your email domains (e.g. acme.com, acme.co.uk). They do two jobs: only those domains may sign in through this provider, and since 1.16.0 an email at one of them goes straight to SSO from the sign-in page, even for a new colleague who has no account yet. Leave blank to allow any account your IdP authenticates; then the sign-in page sends only existing SSO accounts to SSO, and everyone else is asked for a password. Set your domains unless you have a reason not to.
  • Enable “Sign in with Microsoft” — turns single sign-on on. The button’s words follow the provider: Sign in with Microsoft, Sign in with Google, or Sign in with single sign-on for any other OIDC provider (a custom authority).
  • SSO only — everyone signs in through your identity provider; the sign-in page offers no password step, except the break-glass address, which anyone with a password, administrators included, can still use (see Locked out?).

Use Test sign-in to run the flow yourself before rolling it out.

Any spec-compliant OIDC provider works. Under Advanced, set the custom OIDC authority to your provider’s issuer (e.g. https://your-org.okta.com/oauth2/default) — CompassDocs reads everything else from the provider’s discovery document. The redirect URI to register with the provider is the same: https://YOUR-HOST/api/ee/sso/callback.


SAML 2.0 (Okta, OneLogin, Google Workspace, ADFS & others)

Section titled “SAML 2.0 (Okta, OneLogin, Google Workspace, ADFS & others)”

SAML lives in its own panel on Settings → Single sign-on, below the Microsoft/OIDC one. On the sign-in page its button is labelled Single sign-on (SAML) by default — you can rename it (Login button label) — and its allowed email domains route people to it exactly as the OIDC ones do (see Email-first sign-in).

CompassDocs is the service provider (SP); your IdP is the identity provider. Setup is a two-way exchange: you give the IdP a couple of URLs, and the IdP gives you its sign-on URL, issuer, and signing certificate.

The panel shows two values, generated from your CompassDocs domain — copy them into your IdP when you create the app:

IdP field asks for… Use this value
Entity ID / Audience URI https://YOUR-HOST/api/ee/saml/metadata
ACS URL / Reply / SSO URL https://YOUR-HOST/api/ee/saml/acs

CompassDocs also publishes standard SP metadata XML at https://YOUR-HOST/api/ee/saml/metadata — many IdPs let you paste that URL to configure everything at once.

Set the IdP to release an email address as the NameID (or as an email / mail attribute) — that’s how people are matched to accounts. A display name (displayName, or givenName + surname) is used for the account name when present.

Back in the SAML panel, the fastest path is Paste your IdP’s metadata XML — download the IdP’s federation metadata (Okta, ADFS, and most others offer a metadata URL or file) and paste it. CompassDocs extracts the three values it needs:

  • IdP sign-on URL — where CompassDocs sends people to authenticate.
  • IdP issuer (entity ID) — must match the <Issuer> in the IdP’s responses; assertions from any other issuer are refused.
  • IdP signing certificate — the X.509 cert (PEM or bare base64) used to verify every assertion’s signature.

You can also fill these three fields by hand. Then set your policies — create accounts on first sign-in and default role, allowed email domains, and the login button label — and tick Enabled on the login page. Use Test sign-in to run the flow yourself first.

Provider Where to add the app
Okta Applications → Create App Integration → SAML 2.0
OneLogin Applications → Add App → search SAML Custom Connector (Advanced)
Google Workspace Admin console → Apps → Web and mobile apps → Add custom SAML app
ADFS Relying Party Trusts → Add → enter the SP metadata URL
Entra ID (SAML) Enterprise applications → New → Create your own application

In every case the SP values from step 1 are what the IdP needs, and CompassDocs maps the email NameID to an account exactly as OIDC does.


Since 1.16.0, once a provider is set up and enabled, the sign-in page asks one thing first: Email or username. Continue then decides where that person signs in, in this order:

  1. SSO only is on → everyone goes to your identity provider (with two providers, they choose).
  2. The email’s domain is in a provider’s allowed email domains → that provider, whether or not the person has an account yet. This is what sends a new colleague to SSO on their first day, so their account is created when they first sign in. If the OIDC and the SAML lists both name the domain, the person picks one.
  3. The email or username names an existing account that signs in with SSO (by its username, or the one account with that email) → its provider: a SAML account to SAML, any other (SCIM-provisioned accounts included) to OIDC when it’s on, else to SAML.
  4. Everything else (password accounts, identifiers nobody has, an email two accounts share) → the password step, under the email or username they typed. The password step accepts either.

With one provider the page says Redirecting to Microsoft (or Google, or single sign-on) and goes; if the browser hasn’t gone after three seconds, a link appears. With two, the person picks. Either way the sign-in comes back to the page they were heading for.

What people see on the way:

  • Use a password instead, under Continue, for administrators and for accounts that keep a password inside an SSO domain. It shows the password field without asking the server anything. It is hidden while SSO only is on.
  • Other ways to sign in: on every password step, the SSO buttons sit in a closed panel under the form, never beside the password field, and look the same for every account. After a wrong password, one sentence points there.
  • After an error from the identity provider, the page shows the error and never sends the person straight back: a single provider waits behind Continue.
  • The page remembers the last email or username used on that browser and fills it in next time, never submitting it, with Not you? Use another account (see Your account & security).
  • With the 1.16.0 Enterprise image, the email typed here travels to an OIDC provider as a hint (login_hint, plus domain_hint on a multi-tenant Microsoft authority and hd on Google when the domain is allowed), so Microsoft and Google don’t ask for it again. It is only a hint: CompassDocs signs in whoever the provider returns, and still checks the allowed domains.

What it never reveals. An unknown identifier and a password account get the same answer, byte for byte, so the page can’t be used to find out who has an account: it never says “no such account” or “welcome back”. Nothing about an account (its name, status or whether it has a password) is ever returned. Rules 1 and 2 read no account at all; only rule 3 does, and those lookups are rate-limited to 20 a minute and 100 an hour per address, with one auth.lookup_throttled audit entry when the limit engages (someone who reaches it can still use Other ways to sign in or Use a password instead). The lookup carries the email only in the JSON body of a request. When it sends someone to Microsoft or another OIDC provider, though, the URL that starts that sign-in carries the email as login_hint (see above), so a proxy or load balancer that logs query strings records it, and it appears in the provider’s sign-in address too; the SAML start URL carries no email. One thing is visible by design: outside your SSO domains, an identifier that names an SSO account goes to SSO where a password account gets a password field. That is the rate-limited rule 3, and listing your domains keeps your own people on rule 2, which reveals only your configuration.

A disabled account is routed like any other; its provider sends it back with “Your account is disabled.” Without SSO (every Community install, and an Enterprise install with no provider enabled) the sign-in page is one form for email or username and password, and makes no lookup at all.

This is identical for OIDC and SAML:

  1. A returning SSO user is recognized by their immutable directory ID (the OIDC subject, or the SAML NameID) — renames and email changes are safe. Since the 1.16.0 Enterprise image, if the account’s email is marked Unconfirmed and the provider asserts that same email, the mark is cleared.
  2. Otherwise, if exactly one account has the same email, the SSO identity is linked to it. The account keeps its role, and a local password (if set) keeps working alongside SSO. Since 1.16.0 an email is linked only when it is confirmed: an email a person typed on their own profile shows as Unconfirmed on Settings → Users, and SSO will not link it until an admin saves it there with Email… (anyone could otherwise type a colleague’s address and receive their first SSO sign-in). Confirm it only once you know the address is that person’s own, because the link gives the account to whoever signs in with it.
  3. Otherwise a new account is provisioned (if enabled). SSO-provisioned accounts have no password — they can only sign in through your IdP.

A first sign-in is refused, not provisioned, when an existing account has the email but can’t be linked. The sign-in page then says which of these it was, each in its own sentence:

  • the one account with the email has an address its owner typed and no admin has confirmed (link_unconfirmed): check whose address it is before you confirm it, and change or clear it if it isn’t theirs;
  • more than one account has the email (link_ambiguous): give each its own address, or clear it on all but one, with Email… (which refuses an address another account still uses);
  • the account is an administrator’s (link_admin): administrator accounts are never linked to SSO, so the administrator signs in with their username and password (Use a password instead, or /login?local=1 while SSO only is on);
  • the account is already linked to another identity provider (link_other_provider).

Each refusal is written to the audit log as Refused a single sign-on link (auth.sso_link_refused), with the email the provider asserted, the provider and the cause, and as its target the account that blocked the link when there is one (the 1.16.0 Enterprise image; before, the person saw one general sentence and nothing was recorded).

Roles are managed in CompassDocs (Settings → Users), not by the IdP — an admin can promote or disable any account, including SSO ones. Disabled accounts can’t sign in, even with valid IdP credentials.

Pair SSO with SCIM provisioning (enterprise) and Entra also manages the account lifecycle: new hires appear automatically, and departed employees are deactivated with their sessions revoked — no manual cleanup.

If SSO only is on and your IdP is down or misconfigured, an administrator, like anyone else with a password, signs in at:

https://YOUR-HOST/login?local=1

It is the classic form (Sign in with a password: email or username, password, then two-factor if the account has it), with Use single sign-on instead to go back. Bookmark it when you turn SSO only on; while it’s on, Settings → Workspace → Sign-in page shows the address with Copy link. Once in, fix the configuration, or turn SSO only back off from Settings → Single sign-on. The same address works when SSO only is off, but there Use a password instead on the sign-in page does the same job.

SSO only shapes the sign-in page; it doesn’t remove anyone’s password. Every account that has one (every local account, and a local account later linked to SSO) can still use it at /login?local=1. Scripts can sign in through the API too, with a username or an email:

Terminal window
curl -X POST https://YOUR-HOST/api/auth/login \
-H "content-type: application/json" \
-d '{"username":"admin","password":"…"}'
  • OIDC is authorization code + PKCE, with state and nonce checks bound to a short-lived, HTTP-only cookie. ID tokens are fully validated: RS256 signature against the provider’s published keys, issuer, audience, expiry, and nonce.
  • SAML responses are validated against the configured IdP signing certificate (audience and timestamps included), and each sign-in is bound to the exact request the browser started — a flow cookie carries the AuthnRequest ID and RelayState, and both must match, so replayed or unsolicited (IdP-initiated) responses are refused. The expected issuer is enforced even when a signature verifies. Since the 1.16.0 Enterprise image the flow cookie is SameSite=None; Secure on HTTPS, so it reaches the ACS on the IdP’s cross-site post; before, browsers could leave it off and the sign-in ended with “The sign-in attempt expired or was tampered with.”
  • The email-first step (POST /api/auth/lookup) takes a same-site JSON request only, sets no cookie, writes no audit entry per lookup and is never cached. The address that starts a provider’s sign-in is built by the server and always stays on your own host, so the provider’s flow cookie is always set by CompassDocs itself. A login hint is never trusted.
  • Both protocols mint the same session as a password login, honoring your session-timeout and secure-cookie settings.
  • Sign-ins, provisioned accounts, and settings changes all land in the audit log — auth.sso_login, user.sso_provisioned, and settings.sso / settings.saml, and since 1.16.0 a refused link, auth.sso_link_refused.