AttestoPhoenix.Plug.RequireScopes (AttestoPhoenix v4.2.1)

Copy Markdown View Source

Phoenix alias for Attesto.Plug.RequireScopes.

Scope authorization is protocol logic, so the implementation remains in the core attesto package and uses Attesto.Scope grant-form algebra. This module exists to give Phoenix routers a stable AttestoPhoenix.Plug.* surface alongside AttestoPhoenix.Plug.Authenticate.

If reached without verified claims, this plug answers 401. When request-private :attesto_phoenix_config or an explicit :config option (a config struct or zero-arity resolver) is available, it completes :auth_denied before sending that response. Request-private configuration takes precedence. With no config, no audit sink is available. Authenticated scope refusals remain 403 and do not emit authentication-denial events.

RFC 9728 resource_metadata on the 403

Unlike AttestoPhoenix.Plug.Authenticate (which sources the resource_metadata pointer from AttestoPhoenix.Config), this plug is a thin, protocol alias that stays usable in a resource-server-only deployment with no host config. Its insufficient_scope (403) challenge therefore omits the pointer unless one is passed explicitly:

plug AttestoPhoenix.Plug.RequireScopes,
  scopes: ["read:reports"],
  resource_metadata: "https://api.example/.well-known/oauth-protected-resource"

This is intentional, not a discovery gap: a 403 is only reached after the request authenticated, so the client already received the pointer on the initial unauthenticated 401 from Authenticate, and RFC 9728 §5.1 makes the resource_metadata auth-param OPTIONAL on a challenge.