1 Authentication
Kyle Mendell edited this page 2026-10-27 15:06:39 -05:00

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_url as https://<public-host>/oidc/callback. Register that URL with your identity provider — the SSO page in the web UI shows the exact value.
  • claims_to_roles maps IdP claim values to overpass roles, so group membership in your IdP drives access here.
  • Use client_secret_env to read the client secret from an environment variable instead of writing it into the file.
  • allow_private_network permits 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 okta opens 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_url so the redirect URI overpass builds matches what's registered with your IdP. See Behind a reverse proxy.