Goalkeeper Docs
Concepts

Authentication

The application authentication contract and provider interface.

Goalkeeper exposes one provider-neutral authentication contract to the browser. The REST API owns the canonical routes and user shape while an injected AuthBackend owns the provider-specific session lifecycle.

Browser contract

RoutePurpose
GET /v1/auth/configReturn the configured browser authentication method
GET /v1/auth/sessionReturn the canonical user and organization context
GET /v1/auth/loginBegin login and continue to a same-origin URL
POST /v1/auth/loginSign in with the built-in email provider
POST /v1/auth/registerRegister an email principal
POST /v1/auth/verify-emailConsume an email verification token after browser confirmation
GET /v1/auth/callbackComplete login and continue to the application
POST /v1/auth/logoutEnd the session and return the next browser URL

An authenticated session contains the provider-neutral application identity and organization context required by the web client:

{
  "user": {
    "id": "user-id",
    "displayName": "Example User",
    "email": "user@example.com"
  },
  "activeOrganizationId": "organization-id",
  "organizations": [
    {
      "id": "organization-id",
      "name": "Example User",
      "role": "owner"
    }
  ]
}

The web application does not depend on provider-specific claims, tokens, or SDK types. Application-owned organization data is resolved after the authentication provider returns the canonical user, so custom providers do not need to manage Goalkeeper memberships.

Provider interface

Self-hosted operators can supply an AuthBackend to createApiHandler. The provider is responsible for initiating login, validating callbacks, resolving its authenticated principal to the canonical application user, issuing and revoking the session cookie, and coordinating logout.

This keeps authentication mechanisms behind a provider interface. Replacing the provider does not change the browser routes, the protected page, or the application user model.

If a provider accepts JWT access tokens, it validates their signature, algorithm, key ID, issuer, audience, and expiry before constructing an AuthSession. JWT key rotation and issuer-specific claims stay inside the provider.

Built-in email provider

The default self-hosted configuration uses the built-in email provider. Principals, Argon2id password hashes, opaque session hashes, and email-verification token hashes are stored in PostgreSQL. Verification tokens are single-use and expire after 24 hours. Login uses one invalid-credentials response for unknown, incorrect, and unverified accounts.

Verification links open the web application's /verify-email page with the token in the URL fragment. The page removes the fragment from browser history and requires explicit confirmation before it sends the token to the API. This prevents automated link scanners from consuming verification tokens.

The local email-delivery adapter logs the verification message and link to the API terminal. It is disabled in production. To verify a local principal without opening and confirming the link, run:

bun run auth:verify-email -- user@example.com

Open /home to exercise the protected application. Unauthenticated requests are sent to /sign-in; logout from the sidebar account menu revokes the persisted session and returns there. /account remains a compatibility redirect to the Profile settings page.

API Token settings at /settings/api-tokens provide API token management. See Organizations for bootstrap and switching.