Accrue.Entitlements.Offline (accrue v1.5.1)

Copy Markdown View Source

Public, public-key-only verification support for versioned offline entitlement proofs.

Summary

Functions

Returns the bounded client-side action policy for a verified offline decision.

Returns the typed learner-facing guidance seed for a public proof state.

Rejects direct proof issuance.

Creates a one-time challenge for an authenticated device reconnect.

Renders public verification keys while enforcing retirement requirements derived from actual issued proofs.

Functions

action_policy(decision, action)

@spec action_policy(Accrue.Entitlements.Offline.Proof.Decision.t(), atom()) ::
  Accrue.Entitlements.Offline.Proof.ActionPolicy.t()

Returns the bounded client-side action policy for a verified offline decision.

challenge(account, installation_id, opts \\ [])

@spec challenge(Accrue.Entitlements.Account.t(), String.t(), keyword()) ::
  {:ok, Accrue.Entitlements.Offline.Challenge.Value.t()}
  | {:error, :unauthorized | :invalid_request}

guidance(state)

@spec guidance(:fresh | :stale_offline | :denied | :invalid) ::
  Accrue.Entitlements.Offline.Proof.Guidance.t()

Returns the typed learner-facing guidance seed for a public proof state.

issue(account, request, opts \\ [])

@spec issue(
  Accrue.Entitlements.Account.t(),
  Accrue.Entitlements.Offline.Issuer.Request.t(),
  keyword()
) ::
  {:error, :unauthorized}

Rejects direct proof issuance.

A compact entitlement proof is minted only after the authenticated reconnect flow has verified a one-time device proof-of-possession. Hosts must use reconnect/3; accepting an account and device id here would make either an allow proof or a deny tombstone forgeable without that admission boundary.

reconnect(account, request, opts \\ [])

@spec reconnect(
  Accrue.Entitlements.Account.t(),
  Accrue.Entitlements.Offline.Reconnect.Request.t(),
  keyword()
) :: {:ok, Accrue.Entitlements.Offline.Reconnect.Outcome.t()} | {:error, atom()}

reconnect_challenge(account, installation_id, opts \\ [])

@spec reconnect_challenge(Accrue.Entitlements.Account.t(), String.t(), keyword()) ::
  {:ok, Accrue.Entitlements.Offline.Challenge.Value.t()}
  | {:error, :unauthorized | :invalid_request}

Creates a one-time challenge for an authenticated device reconnect.

register_device(account, request, opts \\ [])

@spec register_device(
  Accrue.Entitlements.Account.t(),
  Accrue.Entitlements.Offline.Registration.Request.t(),
  keyword()
) ::
  {:ok, Accrue.Entitlements.Offline.Registration.Result.t()} | {:error, atom()}

replace_device(account, request, opts \\ [])

verification_keys(opts \\ [])

@spec verification_keys(keyword()) ::
  {:ok, %{required(String.t()) => [map()]}} | {:error, :config_invalid}

verification_keys_with_issued_retention(opts \\ [])

@spec verification_keys_with_issued_retention(keyword()) ::
  {:ok, %{required(String.t()) => [map()]}} | {:error, :config_invalid}

Renders public verification keys while enforcing retirement requirements derived from actual issued proofs.

Unlike verification_keys/1, this operation requires a Repo. Call it from the host's JWKS publication path; explicit keys and injected providers can use the pure renderer with precomputed :retention_requirements instead.

verify(compact, context, opts \\ [])

@spec verify(
  binary(),
  Accrue.Entitlements.Offline.Proof.VerificationContext.t() | map(),
  keyword()
) ::
  {:ok, Accrue.Entitlements.Offline.Proof.Decision.t()}