Packages
attesto_phoenix
0.6.21
2.1.0
2.0.2
2.0.1
2.0.0
1.4.0
1.3.0
1.2.0
1.1.0
1.0.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.2
0.14.1
0.14.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
Phoenix/Ecto OAuth 2.0 / OIDC authorization server layer over attesto: authorization, token, PAR, revocation, discovery, JWKS, UserInfo, protected-resource plugs, and Ecto-backed token stores.
Current section
Files
Jump to
Current section
Files
guides/proxy_canonical_host.md
# Issuer, resource, and redirect URL correctness behind a proxy
Behind Fly, NGINX, a CDN, or any reverse proxy, the request the application
sees is not the request the client sent: the scheme is often plain HTTP after
TLS termination, and the `Host` header may be an internal name. OAuth and OIDC
URL correctness depends on the **canonical, client-visible** host and scheme,
not on whatever reached the application socket.
## Why this matters
* The **issuer** (`iss`) is minted into every token and published in the
discovery documents (RFC 8414 §2). It MUST be the canonical `https` URL
clients use. Deriving it from a live request behind a proxy can leak an
internal host or an `http` scheme.
* The **DPoP `htu`** (RFC 9449 §4.3) is the URL the client signed. If the
server computes `htu` from a proxied request it may not match what the
client signed, and valid proofs are rejected.
* **Redirect URIs** are exact-matched (RFC 6749 §3.1.2.3). A host/scheme
mismatch breaks the match.
## Configure the canonical identity, not the request
`AttestoPhoenix.Config`:
* `:issuer` - set this to the fixed canonical `https` issuer URL. The library
derives the discovery issuer and the advertised endpoint URLs from it (via
the `:oauth_path_prefix` / per-endpoint path resolvers), so it never needs
to reconstruct the host from a request. This is stable behind any TLS
terminator.
* `:trusted_proxies` - the list of trusted proxy CIDRs/IPs that controls
whether `X-Forwarded-*` headers are honored. Default `[]` (no forwarded
trust): nothing is taken from a `Forwarded` / `X-Forwarded-*` header unless
the immediate peer is in this list. Set it to your proxy's address range so
forwarded scheme/host are trusted only from your proxy and never from an
arbitrary client.
* `:require_https` - keep this `true` (the default) in production so the
endpoints enforce HTTPS.
* `:htu` - `(conn -> canonical_url_string)`. When the default derivation from
`:trusted_proxies` is not enough (an unusual proxy chain, a host rewrite),
override exactly how the DPoP `htu` is computed. Return the canonical URL
the client would have signed.
## Checklist
- [ ] `:issuer` is the fixed canonical `https` URL (no internal host).
- [ ] `:trusted_proxies` lists your proxy's address range, nothing wider.
- [ ] `:require_https` is `true`.
- [ ] Advertised endpoint paths match the mount via `:oauth_path_prefix` (see
the consumer migration guide).
- [ ] If proofs are rejected behind the proxy, set `:htu` to return the
canonical signed URL.