Documentation
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:
| Claim | Value |
|---|---|
iss | the issuer URL |
sub | the Everlock user |
aud, client_id | the client the token was issued to |
jti | a random identifier, unique per token |
iat, exp | issue time, and expiry one hour later |
scope | the granted scopes: those requested that the client is registered for |
name | the user's display name, under the profile scope |
email | the 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:
| Claim | Value |
|---|---|
iss | the issuer URL |
sub | the Everlock user |
aud | the client the login was for |
iat, exp | issue time, and expiry one hour later |
auth_time | when the user last entered their password |
nonce | the nonce of the authorize request, when it had one |
name, preferred_username | under the profile scope |
email | under 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
| Purpose | CLI flag / env | Default |
|---|---|---|
| Start the backend | --backend-oauth-http / EVERLOCK_BACKEND_OAUTH_HTTP | off; /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_STORE | everlock-oauth |
| Vhost the provider is served on | --backend-oauth-http-vhost / EVERLOCK_BACKEND_OAUTH_HTTP_VHOST | unset |
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)