oidc-provider.client-metadata
Client ID Metadata Document resolution per draft-ietf-oauth-client-id-metadata-document.
When a client’s client_id is an HTTPS URL, this namespace resolves it to a JSON metadata document containing the client’s configuration (redirect URIs, name, etc.), enabling verification without pre-registration.
Use create-metadata-resolving-store to wrap an existing oidc-provider.protocol/ClientStore with metadata document resolution. URL-based client IDs that are not found in the inner store are fetched, validated, and cached automatically. Metadata clients are always treated as public (no client_secret).
cache-get
(cache-get cache-atom url ttl-seconds clock)Returns the cached ClientConfig for url if present and not expired, else nil.
cache-put
(cache-put cache-atom url client-config clock)Stores a ClientConfig in the cache for url with the current timestamp.
create-metadata-resolving-store
(create-metadata-resolving-store inner-store opts)Creates a MetadataResolvingClientStore that wraps inner-store with Client ID Metadata Document resolution.
For non-URL client IDs, delegates directly to inner-store. For HTTPS URL client IDs not found in the inner store, fetches the metadata document from the URL, validates it, and returns the resulting ClientConfig.
The default fetch function blocks requests to private, loopback, and link-local addresses to prevent SSRF. Supply a custom :fetch-fn to override this behavior.
Options:
:fetch-fn—(fn [url] metadata-map), overrides the default HTTP fetch including SSRF protection:cache-ttl-seconds— how long to cache resolved metadata (default: 300):fetch-timeout-ms— HTTP request timeout (default: 5000):max-body-bytes— maximum metadata document size (default: 524288):clock—java.time.Clockinstance for testable time (default: system UTC)
fetch-metadata-document
(fetch-metadata-document url {:keys [fetch-timeout-ms max-body-bytes], :or {fetch-timeout-ms default-timeout-ms, max-body-bytes default-max-body-bytes}})Fetches a Client ID Metadata Document from url via HTTP GET.
Uses java.net.http.HttpClient with Accept: application/json, configurable timeout (:fetch-timeout-ms, default 5000), and max body size (:max-body-bytes, default 512KB). Redirect policy is NEVER. The response body is read in a streaming fashion with the size limit enforced during read, preventing memory exhaustion from oversized responses. Returns the parsed JSON map on success, or throws on failure.
metadata-document->client-config
(metadata-document->client-config document)Converts a wire-format metadata document to a kebab-case ClientConfig map.
Always sets :client-type to "public" since metadata document clients cannot have a client_secret. Applies RFC 7591 defaults for missing grant_types, response_types, and token_endpoint_auth_method.
private-address?
(private-address? hostname)Returns true when hostname resolves to a private, loopback, or link-local IP address.
Checks all A and AAAA records returned by DNS resolution using JDK methods isLoopbackAddress, isLinkLocalAddress, and isSiteLocalAddress, which cover 127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10, RFC 1918, and RFC 4193 ranges.
url-client-id?
(url-client-id? client-id)Returns true when client-id is an HTTPS URL, indicating it should be resolved as a Client ID Metadata Document.
validate-metadata-document
(validate-metadata-document document fetch-url)Validates a metadata document against ClientMetadataDocument schema and verifies that the client_id field matches the fetch-url the document was retrieved from.
Returns the document on success. Throws ex-info on validation failure or client_id mismatch.