Skip to content

Commit 8dd9991

Browse files
committed
feat: add cimd documentation
-adds the documentation for how client id metadata document feature in hydra works.
1 parent eb06fc1 commit 8dd9991

File tree

2 files changed

+773
-2
lines changed

2 files changed

+773
-2
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
id: client-id-metadata-document
3+
title: Use client ID metadata documents
4+
sidebar_label: Client ID metadata
5+
slug: client-id-metadata-document
6+
---
7+
8+
## Overview
9+
10+
Client ID Metadata Document (CIMD) lets Hydra treat a `client_id` as an HTTPS URL that points to a metadata document. Hydra
11+
fetches that document to populate client settings such as redirect URIs, token endpoint auth method, and JWKS. The feature follows
12+
the draft OAuth Client ID Metadata Document specification. See the current draft for details in the
13+
[IETF document](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/).
14+
15+
CIMD modes control acceptance of URL-based client identifiers:
16+
17+
- `disabled`: CIMD is off and Hydra only accepts string or UUID client IDs (default).
18+
- `optional`: Hydra accepts both URL client IDs and non-URL client IDs (typical starting point).
19+
- `enforced`: Hydra only accepts URL client IDs.
20+
21+
Discovery stays disabled by default. Enabling CIMD does not expose discovery unless you also enable discovery in your deployment.
22+
23+
## Enable CIMD in Hydra
24+
25+
1. Upgrade Hydra to a build that includes CIMD and apply the accompanying migrations.
26+
2. In the Hydra configuration, enable CIMD and pick the mode:
27+
28+
```yaml
29+
oauth2:
30+
client_id_metadata_document:
31+
enabled: true
32+
mode: optional # disabled | optional | enforced
33+
cache:
34+
min_ttl: 5m
35+
max_ttl: 30m
36+
http:
37+
timeout: 5s
38+
max_size: 1048576 # bytes
39+
clients:
40+
http:
41+
disallow_private_ip_ranges: true
42+
private_ip_exception_urls:
43+
- https://metadata.example.internal/client.json
44+
```
45+
46+
3. Adjust HTTP safety limits to match your environment:
47+
- `oauth2.client_id_metadata_document.http.timeout` controls the metadata fetch timeout.
48+
- `oauth2.client_id_metadata_document.max_size` rejects responses larger than this value.
49+
- `clients.http.disallow_private_ip_ranges` blocks metadata fetches to private networks. Add allowed hosts to
50+
`clients.http.private_ip_exception_urls` when needed.
51+
4. Set cache bounds with `oauth2.client_id_metadata_document.cache.min_ttl` and `oauth2.client_id_metadata_document.cache.max_ttl`
52+
to avoid over-fetching while keeping metadata fresh.
53+
5. Enable discovery only if you want to expose CIMD through the well-known endpoint. CIMD works without discovery.
54+
55+
## Configuration reference
56+
57+
Use these configuration keys to control CIMD behavior. Defaults are shown for reference; confirm them against your release.
58+
59+
- `oauth2.client_id_metadata_document.enabled`: Enables CIMD feature. Default: `false`.
60+
- `oauth2.client_id_metadata_document.mode`: `disabled` | `optional` | `enforced`. Default: `disabled`.
61+
- `oauth2.client_id_metadata_document.cache.min_ttl`: Minimum cache TTL for fetched metadata. Default: `5m`.
62+
- `oauth2.client_id_metadata_document.cache.max_ttl`: Maximum cache TTL for fetched metadata. Default: `24h`.
63+
- `oauth2.client_id_metadata_document.http.timeout`: HTTP client timeout for CIMD fetches. Default: `5s`.
64+
- `oauth2.client_id_metadata_document.max_size`: Maximum response body size for a metadata fetch. Default: `5KB`.
65+
- `clients.http.disallow_private_ip_ranges`: Enforces SSRF protection by disallowing private IP ranges. Default: project-global
66+
setting.
67+
- `clients.http.private_ip_exception_urls`: Explicit allowlist entries when private IP ranges are disallowed.
68+
69+
## Discovery and well-known exposure
70+
71+
Hydra serves `.well-known/openid-configuration` and `.well-known/oauth-authorization-server` by default. CIMD-specific fields
72+
appear in those documents only when CIMD is enabled. If CIMD is disabled, the well-known responses remain unchanged.
73+
74+
When CIMD is enabled, Hydra adds details to the discovery documents:
75+
76+
- Indicates CIMD support (for example, as a capability entry alongside other Hydra extensions).
77+
- States that `client_id` can be an HTTPS URL referencing a metadata document when `mode` is `optional`, and must be when `mode`
78+
is `enforced`.
79+
- Notes JWKS requirements for `private_key_jwt` clients (publish `jwks` or `jwks_uri`).
80+
- Explains CORS validation uses resolved metadata, so URL-based `client_id` values participate in CORS decisions.
81+
- Documents security constraints: HTTPS-only, path required, no fragment, SSRF and allowlist enforcement, timeout, and maximum
82+
response size limits.
83+
- Mentions metadata caching with minimum and maximum TTLs; exact values remain deployment-specific unless you choose to expose
84+
them.
85+
86+
Discovery visibility is separate from operational behavior. Fetching and validation follow `enabled`, `mode`, and the safety
87+
limits above, regardless of whether discovery is exposed.
88+
89+
## Prepare the client metadata document
90+
91+
Publish a client metadata document at the HTTPS URL you plan to use as `client_id`. The URL must use HTTPS, include a path, and
92+
omit fragments. The document must satisfy these rules:
93+
94+
- Provide `redirect_uris` that follow RFC 8252 rules. Loopback and `localhost` redirects are allowed per the specification.
95+
- For `private_key_jwt` clients, include `jwks` or `jwks_uri` so Hydra can validate assertions.
96+
- Include the token endpoint auth method in `token_endpoint_auth_method` when the client is not using the default
97+
`client_secret_basic`.
98+
- Keep the document within the configured `max_size` and ensure the server responds within the configured timeout.
99+
100+
Example document:
101+
102+
```json
103+
{
104+
"redirect_uris": ["https://app.example.com/callback", "http://localhost:8080/callback"],
105+
"token_endpoint_auth_method": "private_key_jwt",
106+
"jwks": {
107+
"keys": [
108+
{
109+
"kty": "RSA",
110+
"kid": "client-key-1",
111+
"e": "AQAB",
112+
"n": "...base64-modulus..."
113+
}
114+
]
115+
},
116+
"client_name": "Example CIMD client"
117+
}
118+
```
119+
120+
## How CIMD works at runtime
121+
122+
When Hydra receives a `client_id` that is a valid HTTPS URL, it fetches the metadata document and applies these checks:
123+
124+
- Enforces HTTPS, rejects URLs without a path, and rejects URLs that include fragments.
125+
- Applies SSRF protections using `clients.http.disallow_private_ip_ranges` and `clients.http.private_ip_exception_urls`.
126+
- Honors `oauth2.client_id_metadata_document.http.timeout` and `oauth2.client_id_metadata_document.max_size`.
127+
- Validates redirect URIs against RFC 8252 rules.
128+
- Requires JWKS or `jwks_uri` for `private_key_jwt` clients.
129+
130+
A successful fetch populates the client settings and records `client_id_metadata_fetched_at`. Cache TTLs from the CIMD
131+
configuration prevent repeated fetches; subsequent requests reuse cached metadata until the TTL expires. Concurrent fetches for
132+
the same URL are safe.
133+
134+
CORS, device flow, logout, and token handlers rely on the same client lookup logic, so URL-based `client_id` values work across
135+
those paths.
136+
137+
## Operate and verify
138+
139+
- Default behavior does not change until `oauth2.client_id_metadata_document.enabled` is set to `true`.
140+
- If you set `mode` to `enforced`, Hydra rejects non-URL client IDs.
141+
- Keep cache TTLs aligned with how often client operators update their metadata documents.
142+
- If you disallow private IP ranges, configure exception URLs for trusted metadata hosts before enabling CIMD for those clients.
143+
- Run your CI or staging environment with timeouts and maximum size values that match production to catch oversized or slow
144+
metadata responses early.
145+
146+
## Test the setup
147+
148+
Use these checks in your deployment tests:
149+
150+
- Verify a URL `client_id` is accepted when CIMD is `optional` and rejected when CIMD is `disabled`.
151+
- Confirm Hydra rejects metadata fetches that exceed the configured timeout or maximum size.
152+
- Verify SSRF protections by confirming requests to private IP ranges fail unless listed in
153+
`clients.http.private_ip_exception_urls`.
154+
- Confirm `private_key_jwt` clients are rejected when the metadata document omits `jwks` or `jwks_uri`.
155+
- Run auth, token, device, and logout flows with URL `client_id` values to confirm end-to-end behavior.
156+
- If you enable discovery, verify the well-known endpoint reflects CIMD as expected.

0 commit comments

Comments
 (0)