Sake.Auth.Config (Sake v0.4.3)

Copy Markdown View Source

The authorization configuration given to {Sake, auth: [...]}.

secret is the Sake secret (secret_key_base: of the Sake child, else config :sake, :secret_key_base), which Sake puts here when it starts, as given: an {m, f, a} is called when the secret is used. It signs the consent form's request and the DPoP nonces.

device: turns on the device authorization grant (RFC 8628), for clients with no browser: true, or [expires_in: seconds, interval: seconds] (how long a device code lasts, 600 by default, and how long a client waits between two polls of the token endpoint, 5 by default). It is off by default: the verification page has to be mounted inside the host's signed-in pipeline first (see Sake.Auth.DeviceVerification). It needs the Sake secret.

par: turns on pushed authorization requests (RFC 9126): true, or [required: boolean, expires_in: seconds]. A client then pushes its authorization request to POST {oauth_path}/par, authenticated as at the token endpoint, and sends the person to the authorize endpoint with the request_uri it got back, good once, for expires_in seconds (60 by default). required: true refuses every authorization request that was not pushed, as a client registered with require_pushed_authorization_requests has its own refused. It is off by default, and the metadata then says nothing about it.

acr_values: lists the authentication context classes the host's login can sign a person in with (["pwd", "mfa"], say: the acr values Sake.Auth.Subject.authentication/1 returns), for the metadata's acr_values_supported (RFC 9470). An authorization request's acr_values are then narrowed to those, and a request that names none of them is refused with invalid_request. Without it, the metadata says nothing and any acr_values are taken as they come.

openid: turns on OpenID Connect: true, or [id_token_ttl: seconds] (how long an ID token lasts, the access token's lifetime by default). The token endpoint then answers a grant whose scopes include openid with an id_token as well, GET {oauth_path}/jwks publishes the signing keys, {oauth_path}/userinfo returns the person's claims, and /.well-known/openid-configuration describes it all. The openid, profile and email scopes are the authorization server's own: no server declares them. It is off by default, and needs the jose package and signing_keys:.

signing_keys: are the keys ID tokens are signed with: a list of [kid: "2026-10", pem: pem] (or maps with those keys), each a PEM private key, RSA (2048 bits or more, signing RS256), P-256 (ES256) or P-384 (ES384), with a kid of its own. The first one signs, and all of them are published at the JWKS endpoint, so a key is rotated by putting the new one first, and dropped once the ID tokens it signed have expired. Only with openid:.

Summary

Functions

Whether every access token must be DPoP-bound (dpop: [required: true]).

The OpenID Connect scopes, with descriptions, with openid:: the authorization server's own, which no server declares; none without it.

Whether client's authorization requests must be pushed: with par: [required: true], or a client registered with require_pushed_authorization_requests. Never without par:.

Every scope an authorization request may ask for: the servers' (see scopes/1), then the OpenID Connect ones (see openid_scopes/1).

The Sake secret as a binary: secret is kept as Sake was given it, and an {m, f, a} is called here, when the secret is used, never when Sake starts (it may name an endpoint that starts after Sake).

All scopes the configured servers declare, with descriptions.

Types

t()

@type t() :: %Sake.Auth.Config{
  access_token_ttl: term(),
  acr_values: term(),
  allow_insecure: term(),
  cimd: term(),
  consent: term(),
  dcr: term(),
  device: term(),
  dpop: term(),
  issuer: term(),
  max_assertion_lifetime: term(),
  name: term(),
  oauth_path: term(),
  openid: term(),
  par: term(),
  refresh_token_ttl: term(),
  remember_consent: term(),
  resources: term(),
  secret: term(),
  servers: term(),
  signing_keys: term(),
  store: term(),
  store_state: term(),
  subject: term(),
  trusted_issuers: term(),
  unused_client_ttl: term()
}

Functions

authorize_url(c)

device_authorization_url(c)

device_url(c)

dpop_required?(arg1)

@spec dpop_required?(t() | Sake.Auth.External.t()) :: boolean()

Whether every access token must be DPoP-bound (dpop: [required: true]).

jwks_url(c)

new(opts)

@spec new(keyword()) :: t()

openid_scopes(config)

@spec openid_scopes(t()) :: [{String.t(), String.t()}]

The OpenID Connect scopes, with descriptions, with openid:: the authorization server's own, which no server declares; none without it.

par_required?(map, client)

@spec par_required?(t(), Sake.Auth.Client.t()) :: boolean()

Whether client's authorization requests must be pushed: with par: [required: true], or a client registered with require_pushed_authorization_requests. Never without par:.

par_url(c)

register_url(c)

request_scopes(config)

@spec request_scopes(t()) :: [{String.t(), String.t()}]

Every scope an authorization request may ask for: the servers' (see scopes/1), then the OpenID Connect ones (see openid_scopes/1).

resolve_secret(secret)

@spec resolve_secret(binary() | {module(), atom(), list()}) :: binary()

The Sake secret as a binary: secret is kept as Sake was given it, and an {m, f, a} is called here, when the secret is used, never when Sake starts (it may name an endpoint that starts after Sake).

revoke_url(c)

scopes(map)

@spec scopes(t() | Sake.Auth.External.t()) :: [{String.t(), String.t()}]

All scopes the configured servers declare, with descriptions.

token_url(c)

userinfo_url(c)