# `AttestoPhoenix.AuthorizationServer.Token`
[🔗](https://github.com/XukuLLC/attesto_phoenix/blob/v0.19.0/lib/attesto_phoenix/authorization_server/token.ex#L1)

Token-endpoint grant processing (RFC 6749 §3.2), as conn-free core.

This is the single place that turns an authenticated client and a parsed
token request into either an RFC 6749 §5.1 response body or an
`AttestoPhoenix.OAuthError`, together with the list of audit events the
exchange produced. It owns every grant-state and claim-level decision the
token endpoint takes:

  * the grant dispatch (RFC 6749 §4) across `authorization_code`,
    `refresh_token`, `client_credentials`, and OAuth token exchange
    (RFC 8693);
  * authorization-code redemption and code-reuse family revocation
    (OAuth 2.0 Security BCP §4.13), via `Attesto.AuthorizationCode`;
  * refresh-token rotation and the initial offline-access refresh-token
    issuance gate (RFC 6749 §6 / OIDC Core §11), via `Attesto.RefreshToken`;
  * ID-Token minting with `at_hash`/`c_hash`/`nonce`/`auth_time`
    (OIDC Core §3.1.3.3 / §3.3.2.11), via `Attesto.IDToken`;
  * UserInfo / claims-parameter extra claims (OIDC Core §5.4 / §5.5);
  * scope resolution (RFC 6749 §3.3) and access-token claim assembly, via
    `Attesto.Token`.

## North star

`AttestoPhoenix.Controller.TokenController` parses the request off the
`Plug.Conn`, authenticates the client (RFC 6749 §2.3), lifts the conn facts
into a `%Request{}` of plain data, and calls `issue/2`. This module reads only
data, never touches a conn, and never emits an event: it returns the events as
data and the controller emits them. Policy is carried on the
`%AttestoPhoenix.Config{}` the caller passes in (host callbacks, stores, TTLs);
nothing is hardcoded here.

## Return value

`{:ok, response_map, events}` on success, where `response_map` is the
RFC 6749 §5.1 body (atom keys) and `events` is a list of
`%AttestoPhoenix.Event{}` the caller emits. `{:error, %OAuthError{}, events}`
on failure, where `events` carries the RFC 6749 §5.2 `:token_denied` audit
event (this module emits no event itself).

Failures that are a server/config fault rather than a client error (a mint
failure, a refresh-issuance failure) are surfaced as RFC 6749 §5.2
`invalid_request` without leaking detail; the underlying reason is logged.

# `response`

```elixir
@type response() :: %{required(atom()) =&gt; term()}
```

The RFC 6749 §5.1 token response body (atom keys).

# `issue`

```elixir
@spec issue(
  AttestoPhoenix.Config.t(),
  AttestoPhoenix.AuthorizationServer.Token.Request.t()
) ::
  {:ok, response(), [AttestoPhoenix.Event.t()]}
  | {:error, AttestoPhoenix.OAuthError.t(), [AttestoPhoenix.Event.t()]}
```

Process a token request, returning the response (or error) and the audit
events the exchange produced.

`config` is the validated `%AttestoPhoenix.Config{}` (also carried on the
`request` for the conn-free helpers); `request` is the
`AttestoPhoenix.AuthorizationServer.Token.Request` the controller built from
the request and the conn facts. See the module docs for the return shape.
This module emits no event itself: the caller emits the returned `events`.

---

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