Documentation

Last updated: 2026-11-12

Provider model and configuration reference

This page covers Everlock's OAuth 2 and OpenID Connect provider model.

The OAuth backend runs behind frontend-http and uses an Everlock versioned-storage store for client registrations, signing keys, and issued tokens.

What it provides

  • issues access and ID tokens against Everlock users

  • stores clients and keys in a dedicated versioned store

  • holds authorization codes in memory for ten minutes; a code redeems once, and only for the client and redirect URI it was issued to, with the PKCE verifier when the request had a challenge

  • login flow runs through the HTTP frontend

  • the standard /authorize, /token, /jwks, and discovery endpoints

  • Everlock user authentication during the login step

  • its own vhost, which the issuer URL is derived from (see Configuration)

  • an RSA signing key generated on first use and kept in the store, with tokens signed RS256 and the public half served from the JWKS endpoint

Tokens

Access tokens are JWTs in the profile of RFC 9068, with the header typ: at+jwt. They are valid for one hour and carry:

ClaimValue
issthe issuer URL
subthe Everlock user
aud, client_idthe client the token was issued to
jtia random identifier, unique per token
iat, expissue time, and expiry one hour later
scopethe granted scopes: those requested that the client is registered for
namethe user's display name, under the profile scope
emailthe user's email, under the email scope and when set

A resource server can verify them locally against the JWKS endpoint or ask /oauth/userinfo, which releases the same claims by the same scopes and leaves out a claim the user doesn't have.

ID tokens come with every login that was granted openid, in the id_token field of the token response. They are the proof of the login for the application itself, with the header typ: JWT, and carry:

ClaimValue
issthe issuer URL
subthe Everlock user
audthe client the login was for
iat, expissue time, and expiry one hour later
auth_timewhen the user last entered their password
noncethe nonce of the authorize request, when it had one
name, preferred_usernameunder the profile scope
emailunder the email scope, when set

An application checks the signature against the JWKS endpoint, that iss is the issuer, that aud is its own client id, and that nonce is the value it sent.

The login session is a separate token in the everlock-oauth-session cookie, valid for 30 minutes on the /oauth path, with the header typ: everlock-session+jwt. It only lets /oauth/authorize skip the login form. Each endpoint accepts only its own kind: neither an access token nor an ID token counts as a login, and only an access token is accepted at /oauth/userinfo.

Configuration

PurposeCLI flag / envDefault
Start the backend--backend-oauth-http / EVERLOCK_BACKEND_OAUTH_HTTPoff; /backends enable oauth-http turns it on and persists that
Versioned store for clients and the signing key--backend-oauth-http-store / EVERLOCK_BACKEND_OAUTH_HTTP_STOREeverlock-oauth
Vhost the provider is served on--backend-oauth-http-vhost / EVERLOCK_BACKEND_OAUTH_HTTP_VHOSTunset

The vhost is also the server setting oauth.http.vhost, which wins over the flag and applies at the next restart:

/server settings set oauth.http.vhost auth.example.com

The provider answers only on its vhost. Without one it serves no endpoint, and clients can still be managed with /oauth client. A public vhost gets its certificate like every backend's, and plain HTTP requests for it redirect to HTTPS. The provider owns /oauth, /.well-known/openid-configuration and /.well-known/jwks.json on its vhost, so a site or other backends share the host (Virtual hosts); the setting refuses a host where another backend owns one of those paths.

The issuer URL — the iss of every token and the base of the discovery document — follows the vhost and what the HTTP frontend actually serves: https://<vhost> once it has an HTTPS listener bound, http://<vhost> otherwise. The port is the one that listener is bound on, left out when it is the scheme's default (443 for HTTPS, 80 for HTTP); a listener bound on several ports counts as the default when that is among them and as the lowest port otherwise. When the listeners change, the issuer follows without a restart.

With HTTPS bound on 0.0.0.0:443 and the vhost auth.example.com, the issuer is https://auth.example.com; with only the default plain listener (0.0.0.0:8080), it is http://auth.example.com:8080. Clients compare iss with the issuer they were configured with, so tokens issued before a listener change carry the old one.

The startup log names the issuer as it stands when the backend starts, before the HTTP frontend binds; until then it is derived from the --frontend-http-listen-https / --frontend-http-listen-http settings:

backend-oauth-http registered (host: auth.example.com, issuer: https://auth.example.com)
oauth oidc backend