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

OpenID Connect Discovery 1.0 - OpenID Provider Metadata endpoint.

Serves the OpenID Provider configuration document at
`/.well-known/openid-configuration` (OpenID Connect Discovery §4) so that
Relying Parties can discover the OpenID Provider: the issuer, the endpoint
URLs, the response/grant types it supports, the signing algorithms it uses
for ID Tokens, and the scopes and claims it can return.

The document is assembled by `Attesto.OpenIDDiscovery.metadata/2`; this
controller contributes transport concerns only and adds no policy of its
own. Every protocol member - the issuer, the token endpoint
(`token_endpoint`), the JWKS location (`jwks_uri`), the PKCE challenge
methods (`code_challenge_methods_supported`, fixed to `S256` per RFC 7636
§4.2), the DPoP algorithms (`dpop_signing_alg_values_supported`, RFC 9449),
and the OIDC-fixed members (`subject_types_supported`,
`id_token_signing_alg_values_supported`, `claim_types_supported`) - is
derived by the core builder from the protocol configuration.

The capability members reflect exactly what the server supports:
`grant_types_supported` is read from `AttestoPhoenix.Config.grant_types_supported/1`
(every grant the token endpoint dispatches by default — `authorization_code`,
`refresh_token`, `client_credentials`, and OAuth token exchange — narrowed when
the host configures `:grant_types_supported`, and the token endpoint enforces the
same set); `token_endpoint_auth_methods_supported`
lists the client-authentication methods it accepts (`client_secret_basic`,
`client_secret_post`, `private_key_jwt`, and `none` for PKCE-using public
clients). The OpenID Connect request-parameter flags
(`request_parameter_supported`, `request_uri_parameter_supported`, both
OpenID Connect Discovery §3) reflect the authorization endpoint precisely:
signed request objects (`request`, JAR/RFC 9101) are consumed when the host
supplies `:client_jwks`; arbitrary OIDC `request_uri` references are not
advertised even though PAR request URNs are resolved through `/oauth/par`. The
`claims_parameter_supported` flag (OpenID Connect Discovery §3 / OpenID
Connect Core §5.5) is host-configurable and defaults to `false`, since the
authorization endpoint does not consume the `claims` parameter unless the
host wires it.

The host-specific members - the `authorization_endpoint` (RFC 6749 §3.1)
and `userinfo_endpoint` (OpenID Connect Core §5.3), both host-owned and
hence not mounted by `AttestoPhoenix.Router`; the supported scopes
(`scopes_supported`, to which the core builder adds the reserved `openid`
scope per OpenID Connect Core §3.1.2.1); the supported claims
(`claims_supported`); the supported ACR values (`acr_values_supported`,
OpenID Connect Discovery §3) and UI locales (`ui_locales_supported`,
OpenID Connect Discovery §3), each advertised only when the host configures
a non-empty list; the `claims_parameter_supported` flag; and the dynamic
registration endpoint (`registration_endpoint`, RFC 7591, advertised only
when registration is enabled) - are read from `AttestoPhoenix.Config` and
passed through, never hardcoded here.

The response carries no secrets and is identical for every caller, so it is
served unauthenticated. OpenID Connect Discovery §4 permits caching of the
configuration response, so a public, cacheable `Cache-Control` header is
set.

## Wiring

The router pipeline must place the `AttestoPhoenix.Config` under
`conn.private[:attesto_phoenix_config]` (the same key the other endpoints
read) and the derived `Attesto.Config` under
`conn.private[:attesto_protocol_config]`. Both are required; a missing value
raises rather than serving a partial document, because a partial discovery
document would misdirect Relying Parties to endpoints that may not exist.

# `show`

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

Render the OpenID Provider Metadata document as JSON.

Fails closed with `RuntimeError` when either required configuration value is
absent from `conn.private`, since serving a document that omits required
members would misdirect Relying Parties.

---

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