> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qumo-deploy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Enforce Single Sign-On

> Require your organization's managed accounts to sign in through its identity provider, require MFA there, and keep a break-glass administrator.

# Enforce Single Sign-On

Once your organization's [OIDC connection](https://docs.qumo-deploy.com/guides/sso/overview.md) is active, its people can
sign in through your identity provider (IdP), but they can still use Google or GitHub. The
organization's **single sign-on policy** closes that door and sets what your IdP must prove:

* **Enforced SSO**: managed accounts sign in only through your IdP.
* **MFA policy**: an SSO sign-in is refused unless the IdP says a second factor was used.
* **Break-glass administrator**: one Organization Admin who can still sign in with Google or
  GitHub, and Qumo two-factor authentication, for when your IdP is down.

In the console the policy is the **Policy** section of **Organization settings → Single
sign-on** (`/organization/sso`), below the connection. With the API it is
`GET` and `PUT /v1/organizations/{id}/sso/policy`, which need the
`organization.sso_policy_get` and `organization.sso_policy_update` permissions, held by
Organization Admin (token scope `organization:admin`).

> [!NOTE]
>
> The policy is kept on the connection and applies **only while the connection is active**. A
> draft or disabled connection enforces nothing, and deleting the connection deletes its
> policy. Changing the connection's issuer, client ID, scopes or claims puts it back to
> draft, which suspends the policy until a test login passes and you activate it again.
> Rotating the client secret of an active connection does not.

Tightening the policy needs a plan with SSO (Pay as you go or Enterprise; `402`
otherwise): turning enforcement on, a stricter MFA policy, or withdrawing an accepted `acr`
value. Relaxing it (enforcement off, a looser MFA policy, more accepted `acr` values) can be
saved on any plan, even while the organization is suspended. So can choosing, changing or
removing the break-glass administrator, deliberately: it is a safety control you must always
be able to use, even after dropping to Free, and signing out the previous administrator's
sessions is a security consequence, not a paid feature. Turning enforcement on also needs the connection active
(`409`); a policy that was already enforcing when the connection was disabled can still be
saved.

## Enforced SSO

With enforcement on, a **managed account** (one whose email is at one of the organization's
verified domains) that signs in with Google or GitHub is sent back to the sign-in page with
`?login_error=sso_required`, and no session is created. The sign-in page asks for the work
email, which goes to your IdP. Accounts at other domains are not affected.

Turn it on in the console with the **Enforce single sign-on** switch and **Save policy**; the
console asks you to confirm first. The switch is unavailable until the connection is active
(the API answers `409`, `activate the connection before enforcing single sign-on`). With the
API, send the whole policy:

```bash theme={null}
curl -X PUT "https://api.qumo-deploy.com/v1/organizations/$ORG_ID/sso/policy" \
  -H "Authorization: Bearer $QUMO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enforce_sso": true,
    "mfa_policy": "none",
    "accepted_acr_values": [],
    "break_glass_user_id": null
  }'
```

### What is signed out

Turning enforcement on signs the managed accounts out of every session your IdP did not
create: browser and CLI sessions from Google, GitHub or a Qumo TOTP sign-in. Their sessions
from your IdP, and the break-glass administrator's sessions, are kept. The answer says how
many sessions were deleted (`revoked_sessions`), and the console shows the count.

Sign-ins still on their way are stopped too: a Qumo TOTP challenge started with Google or
GitHub, and a CLI device code approved from such a session. The same happens whenever more
accounts come under enforcement: the connection becoming active, a new domain verified, or
the break-glass exemption ending (moved to someone else, or its holder no longer an
Organization Admin).

Tightening the MFA policy works the same way: the SSO sessions it now covers whose identity
provider sent no proof of MFA are signed out, with the CLI sessions and personal tokens that
came from them.

Enforcement follows login routing: a domain that is frozen (its verification lapsed past the
grace period) routes no logins, so it enforces nothing either, and its accounts can sign in
with Google or GitHub until the domain is verified again.

A CLI sign-in (`qumod login`) approved from a session your IdP created inherits that
sign-in: enforcement keeps it, it carries the same IdP claims, and it ends no later than the
browser session that approved it, nor 12 hours after the IdP authenticated the user.

Their personal access tokens are revoked too, unless they were minted from a session your IdP
created: new tokens can be minted from an SSO session and keep working. Identities (service
accounts) and their tokens are not affected. To cut off an account entirely, deactivate it
(`POST /v1/organizations/{id}/managed-accounts/{userID}/deactivate`) instead.

Turning enforcement off again is recorded in the audit log at high severity
(`organization.sso_enforcement_disable`), as every change to the policy is recorded as
`organization.sso_policy_update`.

## MFA policy

An SSO sign-in does not ask for Qumo's own two-factor code: your IdP's policies apply. The MFA
policy makes Qumo check that the IdP actually reports a second factor:

| `mfa_policy` | Who must prove MFA |
| :- | :- |
| `none` | Nobody (the default). |
| `admins` | Organization Admins of the organization. |
| `all` | Everyone signing in through the connection. |

A sign-in proves MFA when its ID token has an `amr` value that names a factor beyond a
password (`mfa`, `mca`, `otp`, `hwk`, `swk`, `sc`, `fpt`, `face`, `iris`, `retina` or
`vbm`, from RFC 8176), or an `acr` value in `accepted_acr_values`. Missing claims prove
nothing: Qumo never assumes MFA happened. A sign-in without proof goes back to the sign-in
page with `?sso_error=mfa_required`.

`accepted_acr_values` holds up to 10 values your IdP uses for a multi-factor
authentication context (in the console, one per line under **Accepted acr values**). Leave it
empty to rely on `amr`.

How each IdP reports MFA:

| IdP | What it sends | Recommendation |
| :- | :- | :- |
| [Okta](https://docs.qumo-deploy.com/guides/sso/okta.md) | `amr` lists the methods used, for example `["pwd", "mfa", "otp"]`, or `["hwk"]` for a security key. | Rely on `amr`; no acr values needed. |
| [Microsoft Entra ID](https://docs.qumo-deploy.com/guides/sso/microsoft-entra-id.md) | `amr` is `["pwd", "mfa"]` when MFA was done. `acr` is `"1"` or `"0"` in v1 tokens and may be absent in v2 tokens. | Rely on `amr`; don't accept `acr` values. |
| [Google Workspace](https://docs.qumo-deploy.com/guides/sso/google-workspace.md) | Neither `amr` nor `acr` in its ID tokens. | Keep the MFA policy at `none` and enforce 2-Step Verification in the Google Admin console. |

> [!WARNING]
>
> **Google Workspace and an MFA policy don't mix.** Google's ID tokens never carry `amr` or
> `acr`, so with an MFA policy of `admins` or `all` every sign-in it applies to is refused with
> `mfa_required`, whatever Google itself checked. The console warns when the connection's issuer
> is `https://accounts.google.com` and an MFA policy is chosen.

Before turning on an MFA policy, check what your IdP sends: decode the ID token of a test
sign-in at your IdP and look at its `amr` and `acr` claims.

## Break-glass administrator

If your IdP is down while SSO is enforced, nobody at your verified domains can sign in. A
**break-glass administrator** is one Organization Admin exempt from enforcement: they can
still sign in with Google or GitHub.

* They must be an **Organization Admin** of the organization, and have **two-factor
  authentication (TOTP)** on in their Qumo account. Otherwise the save is refused with
  `422` (`the break-glass user must be an Organization Admin of this organization`, or
  `the break-glass user must have two-factor authentication (TOTP) on`).
* Every break-glass sign-in continues to Qumo's TOTP challenge. Without TOTP on at sign-in
  time, the sign-in is refused with `?login_error=break_glass_requires_totp`.
* Each use of the exemption is recorded in the audit log at high severity as an attempt
  (`organization.sso_break_glass_attempt`), before the TOTP code is checked: an attempt is worth
  knowing about. Your [notification policies](https://docs.qumo-deploy.com/guides/notification-webhooks.md) alert on it, and
  every other Organization Admin is emailed about the attempt. When the TOTP code passes and the
  session exists, a second high-severity entry records the completed sign-in
  (`organization.sso_break_glass_login`).
* Enforcement can be turned on without a break-glass administrator, but the console warns: if
  your IdP has an outage, no managed account can sign in until support steps in.
* The exemption lasts only while they hold Organization Admin. Designating one is itself a
  high-severity audit event (`organization.sso_break_glass_designate`).

In the console, choose them under **Break-glass administrator**, which lists the
organization's Organization Admins. With the API, set `break_glass_user_id` to their user id
(`null` for none).

Choose someone who keeps their TOTP device safe, and test the sign-in once after designating
them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.