Sake.Auth.Clients (Sake v0.4.3)

Copy Markdown View Source

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

create(config, attrs)

@spec create(Sake.Auth.Config.t(), map()) ::
  {:ok, Sake.Auth.Client.t(), String.t() | nil} | {:error, map()}

delete(config, id)

@spec delete(Sake.Auth.Config.t(), String.t()) :: :ok

get(config, id)

@spec get(Sake.Auth.Config.t(), String.t()) :: {:ok, Sake.Auth.Client.t()} | :error

list(config)

@spec list(Sake.Auth.Config.t()) :: [Sake.Auth.Client.t()]

resolve(config, id)

@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.