Table of contents
overpass supports local password accounts and OIDC sign-in, for both the web UI and the CLI.
On a fresh installation, open /setup in the browser and use the one-time
claim code printed by the control plane to create the first administrator. The
normal first-run flow does not require opctl; the command-line examples below
are for additional users, recovery, and automation.
Local accounts
Create accounts with opctl:
opctl users add alice --logins alice,deploy --roles admin # prompts for a password
opctl users add bob --logins bob --roles access --no-password # OIDC-only
Passwords are hashed with argon2id. A user without a password (--no-password)
can only sign in via OIDC.
OIDC
overpass speaks standard OIDC with PKCE. Configure a connector either in the config file — declared there it is authoritative and read-only in the UI — or in the web UI under SSO, which persists it in the server-managed config directory with the client secret encrypted under the cluster master key.
auth:
oidc:
- name: okta
issuer_url: https://acme.okta.com
# Set only when discovery/token/key endpoints resolve to private or
# Tailscale addresses:
# allow_private_network: true
client_id: 0oaEXAMPLE
client_secret_env: OVERPASS_OKTA_SECRET # read from this env var
scopes: [openid, profile, email, groups]
claims_to_roles:
- claim: groups
value: engineers
roles: [access]
- claim: groups
value: sre
roles: [admin]
- The redirect URI is not configurable: overpass always derives it from your
public_urlashttps://<public-host>/oidc/callback. Register that URL with your identity provider — the SSO page in the web UI shows the exact value. claims_to_rolesmaps IdP claim values to overpass roles, so group membership in your IdP drives access here.- Use
client_secret_envto read the client secret from an environment variable instead of writing it into the file. allow_private_networkpermits RFC1918 and CGNAT/Tailscale endpoints for split-horizon or private IdPs. It is disabled by default. Link-local destinations remain blocked, and plain HTTP remains restricted to explicit loopback development issuers.
Per-connector provisioning is tuned in the web UI (SSO → edit connector)
or, for file-declared connectors, with the same fields in YAML
(username_claim, display_name_claim, login_claim, default_roles):
the login claim supplies unix logins, the display name claim feeds the
UI, default roles apply when no mapping matches — and the username
claim picks which ID-token claim the account username is keyed on (e.g.
preferred_username or email). Left empty it uses sub, the only claim the
OIDC spec guarantees stable and non-reassignable; if you switch it after
people have signed in, their next sign-in creates a fresh account under the
new key. OIDC accounts are bound to the connector that first provisioned them,
so the same sub or username from another connector cannot reuse the account.
When keyed on email, the token must carry email_verified: true; a missing or
false verification claim is refused.
Existing OIDC sessions without a connector binding are invalidated after an upgrade that introduces this check; users sign in again through their original connector. Local password sessions are unaffected.
Signing in
- Web UI — OIDC connectors appear as sign-in buttons on the login page.
- CLI —
op login <proxy> --oidc oktaopens your browser, completes the ceremony, and retrieves the end-to-end encrypted certificate from the proxy. The browser and CLI may be on different machines, so this also works from an SSH session or a headless host; copy the printed URL into any browser.
Warning
Behind a reverse proxy, set
public_urlso the redirect URI overpass builds matches what's registered with your IdP. See Behind a reverse proxy.