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.

Managed trusted-proxy provider

The standalone API includes a vendor-neutral redirect provider for managed deployments. Select it with AUTH_PROVIDER=trusted_proxy and configure:

AUTH_PROXY_SECRET=<at-least-32-byte-shared-secret>
AUTH_PROXY_ISSUER=managed-deployment-identifier
AUTH_PROXY_AUDIENCE=goalkeeper-environment-identifier
AUTH_PROXY_LOGIN_URL=https://example.com/_auth/login
AUTH_PROXY_LOGOUT_URL=https://example.com/_auth/logout

The proxy authenticates the provider session and injects two private-hop headers: a base64url JSON assertion in x-goalkeeper-auth-assertion and its HMAC-SHA-256 signature in x-goalkeeper-auth-signature. The assertion version is 1 and contains iss, aud, Unix iat, the exact uppercase request method, exact path plus query in path, sessionId, and the canonical user fields.

The backend accepts assertions for at most 30 seconds, permits no more than five seconds of future clock skew, verifies the signature before returning a session, and binds the assertion to the exact request method and path. The proxy must strip both headers from every client request before signing its own values. The API must not be directly reachable around that proxy, and the shared secret must be unique to the deployment.

Provider SDKs, access tokens, refresh tokens, and cookies remain in the managed proxy. Goalkeeper persists only its own organization and product data keyed by the canonical provider-qualified user ID.

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.