Happier Docs
Server

Auth

Overview of server authentication and policy configuration.

This guide is for server operators. It explains the core auth model and the policy env vars that control signup/login enforcement.

For provider-specific setup guides, see:

Choosing an auth setup (private vs public servers)

What you should configure depends mostly on who can reach your server.

Private server (Tailscale/VPN/LAN only)

If your server is only reachable from a private network (for example via Tailscale), you often don’t need provider-based auth:

  • Recommended: keep anonymous signup enabled (default) and rely on network access control.
  • Make sure your server is not reachable from the public internet (firewall / security group / reverse proxy).

Example config:

AUTH_ANONYMOUS_SIGNUP_ENABLED=true
AUTH_SIGNUP_PROVIDERS=
AUTH_REQUIRED_LOGIN_PROVIDERS=

Optional (private servers): you can also enable GitHub/OIDC in addition to anonymous signup, to offer multiple signup options:

AUTH_ANONYMOUS_SIGNUP_ENABLED=true
AUTH_SIGNUP_PROVIDERS=github
AUTH_REQUIRED_LOGIN_PROVIDERS=

Public server (reachable from the internet)

If your server is publicly reachable, leaving anonymous signup enabled makes it easy for anyone to create an account. In that setup, it’s usually better to require an identity provider:

  • Recommended: disable anonymous signup
  • Recommended: require a provider for ongoing access (AUTH_REQUIRED_LOGIN_PROVIDERS)
  • Optional: restrict eligibility with allowlists (for example “must be in GitHub org X”)

Example (GitHub):

AUTH_ANONYMOUS_SIGNUP_ENABLED=false
AUTH_SIGNUP_PROVIDERS=github
AUTH_REQUIRED_LOGIN_PROVIDERS=github

Then follow the provider setup guide:

Standard authentication (device-key accounts)

Happier uses a device-key account model (each account is tied to a device secret).

  • Default behavior: users can create accounts via device-key signup (POST /v1/auth).
  • You can optionally require external providers (GitHub and/or OIDC) for signup and/or ongoing access.
  • External providers are not “password login”: if a user is trying to access an existing Happier account from a new device/browser, they still need to restore the account (for example via Add your phone / Restore account), then connect providers from settings.

Keyed vs keyless (how providers show up in the UI)

The same OAuth provider (for example GitHub or an OIDC provider) can appear in the UI in two different roles:

  • Keyed provisioning (“Continue with GitHub”): creates a device-key account.
    • Users must back up a secret key and restore on new devices/browsers.
    • This is the standard Happier model and works on E2EE-only servers.
  • Keyless login (“Sign in with GitHub”): signs in to a keyless/plain account (no device keys).
    • Sign-in can be seamless across devices, but it is intended for enterprise deployments and usually paired with plaintext storage.

Server operators control which role(s) are enabled via /v1/features (policy + feature env vars). Clients should not guess.

Auth methods (discovery)

Clients should treat GET /v1/features as the source of truth for “what auth flows are available”.

Happier advertises auth entrypoints via:

  • capabilities.auth.methods[] (preferred; method + action + mode)
  • plus legacy surfaces like capabilities.auth.signup.methods[] for older clients

Each method can advertise multiple actions:

  • login (sign in to an existing account)
  • provision (create an account)
  • connect (link an identity provider to an already-authenticated account)

And each action declares its account key mode:

  • keyed: device-key account (default Happier model)
  • keyless: no device keys (enterprise mode; typically paired with plaintext storage)

Keyless authentication (enterprise)

Some deployments want accounts to exist without device keys (for example: company-managed identity, server-side indexing/search, and simpler multi-device behavior).

Happier currently supports keyless login via:

  • mTLS auth
  • keyless OAuth login (GitHub/OIDC) when enabled by feature env vars

Keyless account auto-provisioning is intentionally guarded:

  • enable keyless accounts: HAPPIER_FEATURE_E2EE__KEYLESS_ACCOUNTS_ENABLED=1
  • allow plaintext storage (required for keyless accounts): HAPPIER_FEATURE_ENCRYPTION__STORAGE_POLICY=optional|plaintext_only
  • for OAuth keyless login:
    • enable: HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_ENABLED=1
    • allowlist providers: HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_PROVIDERS=github,okta,...
    • allow first-login account creation: HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_AUTO_PROVISION=1
  • for mTLS keyless login: see mTLS auth

Recommended hardening for plaintext/keyless deployments:

  • seal plaintext account settings at rest: HAPPIER_FEATURE_ENCRYPTION__PLAIN_ACCOUNT_SETTINGS_AT_REST=server_sealed (default)
  • seal plaintext account connected-service credentials at rest: HAPPIER_FEATURE_ENCRYPTION__PLAIN_ACCOUNT_CREDENTIALS_AT_REST=server_sealed (default)

Note: HAPPIER_FEATURE_ENCRYPTION__DEFAULT_ACCOUNT_MODE controls only the default mode for keyed accounts and new sessions when the storage policy is optional. It does not gate keyless auto-provisioning.

OAuth keyless provisioning choice (optional encryption servers)

When the server storage policy is optional, new users coming back from OAuth (GitHub/OIDC) may be prompted to choose:

  • End-to-end encrypted (E2EE): creates a device-key account; users must back up a secret key to restore on new devices.
  • Not encrypted (plaintext): creates a keyless/plain account; sign-in is seamless across devices, but the server can read stored content.

When the provider is enabled for both modes (keyed provisioning + keyless auto-provisioning), the client should show the choice. When only one mode is available, the client should auto-select it (no extra screen).

On plaintext_only servers, clients should automatically choose plaintext. On required_e2ee servers, clients should not offer plaintext/keyless choices.

E2EE-only (public server) + GitHub required

HAPPIER_FEATURE_ENCRYPTION__STORAGE_POLICY=required_e2ee

AUTH_ANONYMOUS_SIGNUP_ENABLED=false
AUTH_SIGNUP_PROVIDERS=github
AUTH_REQUIRED_LOGIN_PROVIDERS=github

Keyless-only (enterprise) + plaintext-only + GitHub required

HAPPIER_FEATURE_ENCRYPTION__STORAGE_POLICY=plaintext_only
HAPPIER_FEATURE_E2EE__KEYLESS_ACCOUNTS_ENABLED=1

AUTH_ANONYMOUS_SIGNUP_ENABLED=false
AUTH_SIGNUP_PROVIDERS=
AUTH_REQUIRED_LOGIN_PROVIDERS=github

HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_ENABLED=1
HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_PROVIDERS=github
HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_AUTO_PROVISION=1

Optional encryption (enterprise) + OAuth provisioning choice (GitHub)

HAPPIER_FEATURE_ENCRYPTION__STORAGE_POLICY=optional
HAPPIER_FEATURE_E2EE__KEYLESS_ACCOUNTS_ENABLED=1

AUTH_ANONYMOUS_SIGNUP_ENABLED=false
AUTH_SIGNUP_PROVIDERS=github
AUTH_REQUIRED_LOGIN_PROVIDERS=github

HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_ENABLED=1
HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_PROVIDERS=github
HAPPIER_FEATURE_AUTH_OAUTH__KEYLESS_AUTO_PROVISION=1

Optional: allow users to switch existing accounts (e2ee ↔ plain) when storage policy is optional:

HAPPIER_FEATURE_ENCRYPTION__ALLOW_ACCOUNT_OPTOUT=1

Upgrade notes (operator guidance)

  • Clients first is usually safe for keyed accounts (device-key model), because older servers still accept the core /v1/auth login flow.
  • Do not enable plaintext_only until you have clients that support plaintext storage (older clients will fail because encrypted writes are rejected).
  • If you enable keyless OAuth auto-provisioning, ensure your clients are new enough to understand the keyless flows advertised by /v1/features (otherwise users may see missing buttons or failed sign-in attempts).

OAuth return URL (required for GitHub/OIDC self-hosting)

If you enable any external OAuth providers (GitHub and/or OIDC), the server must know where to redirect the browser back to the client app after OAuth completes.

  • If you use the hosted web app, you don’t need to set anything (default is https://app.happier.dev).
  • If you self-host the web app (or you’re using a local dev UI), you must configure one of:
    • HAPPIER_WEBAPP_URL (most common for web)
    • HAPPIER_WEBAPP_OAUTH_RETURN_URL_BASE (often used for mobile deep links or custom paths)

Otherwise, users will be redirected to the wrong place (or the redirect may be rejected as unsafe).

Auth policy (env vars)

Use these env vars to control who can create accounts and whether provider identity is enforced for ongoing access.

Signup / login policy

  • AUTH_ANONYMOUS_SIGNUP_ENABLED (default true)
    • If false, anonymous account creation is disabled (POST /v1/auth will return 403 signup-disabled for new users).
  • AUTH_SIGNUP_PROVIDERS (CSV, default empty)
    • Enables provider-based signup (e.g. github, okta).
  • AUTH_REQUIRED_LOGIN_PROVIDERS (CSV, default empty)
    • Enforces providers for ongoing access (e.g. github, okta).

What enforcement applies to

When AUTH_REQUIRED_LOGIN_PROVIDERS is set, eligibility is enforced for:

  • Authenticated HTTP routes (via the authenticate pre-handler)
  • Socket.IO handshake (/v1/updates)

If a required provider is missing:

  • Requests are rejected with 403 provider-required.

Offboarding / eligibility checks

If you use allowlists (GitHub org allowlists or OIDC allow rules), the server can re-check eligibility periodically and cache results on the identity record.

  • AUTH_OFFBOARDING_ENABLED
    • Defaults to true when any membership-based allowlists are configured (GitHub org allowlist and/or OIDC allow rules); otherwise false.
  • AUTH_OFFBOARDING_INTERVAL_SECONDS (default 86400, clamp 60–86400)
  • AUTH_OFFBOARDING_STRICT (default false)
    • When true, the server fails closed if it cannot re-check eligibility due to upstream downtime (enterprise lock-down mode).

Common configurations (examples)

Default (anonymous signup)

AUTH_ANONYMOUS_SIGNUP_ENABLED=true
AUTH_SIGNUP_PROVIDERS=
AUTH_REQUIRED_LOGIN_PROVIDERS=

GitHub-only signup + GitHub required for login

See GitHub auth for full setup steps.

OIDC-only signup (example: Okta) + OIDC required for login

See OIDC auth for provider configuration.

On this page