# `Sake.Auth.Config`
[🔗](https://github.com/hattoriai/sake/blob/v0.4.3/lib/sake/auth/config.ex#L1)

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 `c: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:`.

# `t`

```elixir
@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()
}
```

# `authorize_url`

# `device_authorization_url`

# `device_url`

# `dpop_required?`

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

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

# `jwks_url`

# `new`

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

# `openid_scopes`

```elixir
@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?`

```elixir
@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`

# `register_url`

# `request_scopes`

```elixir
@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`

```elixir
@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`

# `scopes`

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

All scopes the configured servers declare, with descriptions.

# `token_url`

# `userinfo_url`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
