# `AttestoPhoenix.Controller.TokenController`
[🔗](https://github.com/XukuLLC/attesto_phoenix/blob/v0.19.0/lib/attesto_phoenix/controller/token_controller.ex#L1)

OAuth 2.0 token endpoint (RFC 6749 §3.2).

Handles `POST /oauth/token`. This module owns the HTTP and protocol-framing
concerns only: it resolves the host `%AttestoPhoenix.Config{}`, applies the
no-store cache headers (RFC 7234 §5.2), authenticates the client (RFC 6749
§2.3), lifts the request and the relevant conn facts into a plain
`AttestoPhoenix.AuthorizationServer.Token.Request`, calls the conn-free core
`AttestoPhoenix.AuthorizationServer.Token.issue/2`, emits the audit events the
core returns as data, and renders the RFC 6749 §5.1 success body or the
RFC 6749 §5.2 error body. It carries no business-domain logic; every grant,
claim, and policy decision lives in the core or behind a
`AttestoPhoenix.Config` callback.

## Grant types

  * `authorization_code` (RFC 6749 §4.1.3) with mandatory PKCE (RFC 7636).
  * `refresh_token` (RFC 6749 §6) with rotation and reuse detection
    (RFC 6749 §10.4, OAuth 2.0 Security BCP).
  * `client_credentials` (RFC 6749 §4.4).
  * OAuth token exchange (RFC 8693).

## Client authentication

Accepts HTTP Basic credentials (RFC 6749 §2.3.1, RFC 7617), request-body
credentials (RFC 6749 §2.3.1), and `private_key_jwt` assertions (RFC 7523 /
OIDC Core §9). Presenting more than one client-authentication method is
rejected (RFC 6749 §2.3). Confidential clients must authenticate; a client
identified without a secret/assertion is admitted only when the host's
`:client_public?` callback marks it public, in which case it relies on PKCE
(RFC 7636) instead.

## Responses

Success renders the RFC 6749 §5.1 body; failure renders the RFC 6749 §5.2
error body. Both carry no-store cache headers (RFC 7234 §5.2) so credentials
are never cached by an intermediary. A `use_dpop_nonce` error carries the
fresh `DPoP-Nonce` header (RFC 9449 §8) verbatim in its `:headers`.

## Configuration

All host policy is resolved through `AttestoPhoenix.Config`; nothing is
hardcoded here. See `AttestoPhoenix.AuthorizationServer.Token` for the
grant/claim policy callbacks the core reads, and `AttestoPhoenix.Config` for
the authoritative definitions and defaults.

# `create`

```elixir
@spec create(Plug.Conn.t(), map()) :: Plug.Conn.t()
```

Token endpoint action (RFC 6749 §3.2).

Authenticates the client, delegates the grant to the core, emits the returned
audit events, and renders either the RFC 6749 §5.1 success body or an
RFC 6749 §5.2 error. Every response carries no-store cache headers
(RFC 7234 §5.2).

---

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