Clients the host registers itself (for its own CLIs or partners).
{:ok, client, secret} = Sake.Auth.Clients.create(Sake.Auth.config(), %{name: "Ops CLI", redirect_uris: ["http://127.0.0.1:8765/callback"]})confidential: true returns a secret once; store it where the client
can read it. scopes: limits what the client may request.
A machine client — a service that calls your endpoint as itself, with
the client credentials grant — needs no redirect URI, and must be able
to authenticate: with a secret, or with a key it holds (jwks:, a JWK
Set of its public keys, or jwks_uri:, where to fetch them; the
client then signs a JWT for each token request, private_key_jwt).
Keys need the optional jose dependency.
{:ok, client, nil} =
Sake.Auth.Clients.create(config, %{
name: "Nightly report",
grant_types: ["client_credentials"],
jwks: %{"keys" => [public_jwk]},
scopes: ["reports:read"]
})grant_types: (default ["authorization_code", "refresh_token"]) may
also list "client_credentials" (with the subject module's
Sake.Auth.Subject.client_principal/1) and
"urn:ietf:params:oauth:grant-type:jwt-bearer", for grants from a
Sake.Auth.TrustedIssuer, and
"urn:ietf:params:oauth:grant-type:device_code", for a CLI or a
device with no browser (with device: in the auth config); a client
without "authorization_code" needs no redirect URI.
dpop_bound_access_tokens: true (RFC 9449 §5.2) refuses the client's
token requests that carry no DPoP proof, so all its tokens are bound
to a key it holds.
require_pushed_authorization_requests: true (RFC 9126 §6), with
par: in the auth config, refuses the client's authorization requests
that it did not push first.
Summary
Functions
Finds a client by id: a CIMD URL is fetched, anything else is looked up in the store.
Functions
@spec create(Sake.Auth.Config.t(), map()) :: {:ok, Sake.Auth.Client.t(), String.t() | nil} | {:error, map()}
@spec delete(Sake.Auth.Config.t(), String.t()) :: :ok
@spec get(Sake.Auth.Config.t(), String.t()) :: {:ok, Sake.Auth.Client.t()} | :error
@spec list(Sake.Auth.Config.t()) :: [Sake.Auth.Client.t()]
@spec resolve(Sake.Auth.Config.t(), term()) :: {:ok, Sake.Auth.Client.t()} | {:error, :invalid_client | :not_allowed | :unreachable | :invalid_document}
Finds a client by id: a CIMD URL is fetched, anything else is looked up in the store.