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

`POST /oauth/introspect` - OAuth 2.0 Token Introspection (RFC 7662), with the
signed-JWT response of RFC 9701 (FAPI 2.0 Message Signing §5.5).

This is the thin interface over the conn-free core `Attesto.Introspection`:
it authenticates the calling client, lifts the `token` (and optional
`token_type_hint`) off the request, asks the core whether the token is active,
and renders the response - negotiating, by the `Accept` header, between the
plain JSON response (RFC 7662 §2.2) and a signed JWT
(`Attesto.SignedIntrospection`, `application/token-introspection+jwt`,
RFC 9701). No introspection policy is decided here: activeness, claim
selection, and the no-existence-oracle discipline are all the core's
(`Attesto.Token` signature/temporal/audience verification for access tokens,
the `Attesto.RefreshStore` for refresh tokens). The endpoint only captures the
authenticated caller and hands the host's optional `:introspection_authorize`
policy (RFC 7662 §4 / RFC 9701 §5) to the core, which enforces it fail-closed.

## Client authentication (RFC 7662 §2.1)

The endpoint authenticates the caller exactly as the token endpoint does,
through the shared `AttestoPhoenix.ClientAuthentication` core
(`client_secret_basic` / `client_secret_post` / `private_key_jwt`). Failure
is fail-closed `invalid_client` (as the token and PAR endpoints, the shared
`ClientAuthentication` core returns these with HTTP 400). The authenticated
`client_id` is the audience of a signed response (RFC 9701 §5).

## Caching (RFC 6749 §5.1)

Every response carries `Cache-Control: no-store` and `Pragma: no-cache`.

## Configuration

Reads `AttestoPhoenix.Config` from the application environment (the same
source the token endpoint uses): `:load_client` / `:verify_client_secret`
(client authentication), `:keystore` / `:issuer` (signing the RFC 9701
response), and `:refresh_store` (consulted for opaque refresh tokens).

# `create`

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

Handle `POST /oauth/introspect` (RFC 7662 §2.1).

Authenticates the client, introspects the presented token, and renders the
RFC 7662 response - as JSON, or as an RFC 9701 signed JWT when the caller's
`Accept` requests `application/token-introspection+jwt`.

---

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