This documentation is available as Markdown. For the complete index, see llms.txt. Skip to content

Sign-in

For the complete documentation index, see llms.txt

Opening https://<box>/ sends you to the identity provider the box is configured with. After sign-in you land on Environments, pick one and open its viewer. Every sign-in, refusal and sign-out is a line in the box’s audit trail.

Single sign-on

A box authenticates against one OpenID Connect provider: authorization code flow with PKCE, state and nonce, the ID token verified against the issuer’s published keys. Two presets exist:

  • google — Google Workspace. The account chooser is always shown, and the token’s hd claim is checked against the Workspace domains you allow. A personal Google account is refused (“this is not a Google Workspace account”), and so is an account whose email Google reports as unverified.
  • generic — Okta, Azure AD, Keycloak, Auth0 and any other compliant provider. An email the provider marks unverified is refused.

The redirect URI is fixed: https://<box>/_guard/login/callback. Register exactly that at your provider — a mismatch shows up as redirect_uri_mismatch at sign-in.

For Google Workspace, your administrator creates the OAuth client and — so that groups can decide roles — a service account with domain-wide delegation over two read-only scopes (groups and user status). unotest walks you through this at onboarding.

Groups → roles

Which groups a person is in comes from one of two sources:

  • a groups claim in the ID token (Okta, Azure AD, Keycloak, Auth0);
  • the Google Directory API, because Google does not put groups in a token. This is also the only source that can offboard someone while their session is open.

Your group → role mapping is deny by default:

  • A group that is not mapped grants nothing. Someone who signs in successfully but belongs to no mapped group is refused — not admitted with reduced rights.
  • Someone in two mapped groups gets the stronger role.
  • Group names match case-insensitively.
  • Nested groups are not followed: list the groups people are directly in.

Without any group mapping, every SSO user is readonly.

An email-domain allowlist can be added as an extra check; membership is still what decides.

Re-checks and offboarding

Every 15 minutes (configurable) the box re-asks the directory whether each open session is still entitled:

  • Removed from every mapped group, suspended or deleted → the session ends, recorded as session.revoked.
  • Moved to a group with a different role → the live session’s role changes in either direction, recorded as role.changed.
  • Directory unreachable → the session is left alone and re-checked next time. An outage at your provider never signs your company out.

A login is stricter than a re-check: if the directory cannot be reached while someone is signing in, they are refused rather than admitted on trust.

Sessions

Sessions are held on the box, not in the cookie: the cookie carries an opaque signed id, the record lives in the guard. That is what lets an administrator end a session, and what makes a role change or a disable take effect immediately. A session expires after 24 hours by default.

The session store is in memory. After the box restarts, an SSO user is signed in again silently; a break-glass user retypes their password.

Login routes are rate-limited per client address (10 attempts per minute by default). A successful login resets the counter.

Break-glass account

A box may carry one or more local accounts with scrypt-hashed passwords. They exist for the day the identity provider is unreachable and are reachable from https://<box>/_guard/login/static; with SSO configured, /_guard/login goes straight to your provider.

A break-glass account is an administrator by default. A local readonly account is allowed too — intended for a box without a directory, where it is the only way to hand someone view-only access; a box with a directory should grant readonly through group mapping instead.

Removing an account from the box’s configuration ends its sessions at the next re-check.

Seats

Your licence names a number of seats. A seat is held by anyone who has signed in within the last 30 days (configurable) and is not disabled — the count is rolling, so a contractor who signed in once in March stops consuming a seat on their own.

When every seat is taken:

  • someone who does not already hold a seat is refused with “This box has no free seats. Ask your administrator to free one or raise the licensed seat count.” and the refusal is recorded as seat.denied;
  • everyone who already holds a seat keeps working, including on re-login.

The Administration page shows seats <used>/<total> in use. To free a seat, disable the person — see Administration.

What is recorded

EventWhen
login.succeededA sign-in completed; carries the provider, the role granted and the client address.
login.refusedCredentials rejected, an account disabled on this box, or the directory refused the person; carries the reason.
seat.deniedNo free seat; carries seats and seatsUsed.
logoutThe person signed out.
session.revokedA session ended by a re-check, by an administrator, or because its provider was removed from the configuration.
role.changedA live session’s role moved (directory change or administrator override).

The full list of events is in Administration.