Directory. / developers

Registration & validation

Activation is a functional check, not a form review

POST /admin/institutions/{id}/activate does not just record that an institution claims to support DCR and publish a JWKS. It makes two real outbound calls and only flips the institution to Active if both succeed.

Dynamic client registration check

Directory issues itself a short-lived, cached client certificate from its own CA (never exposed through any route) and a signed software statement, then makes a real mutual-TLS POST to the institution's declared dcrRegistrationUri, following the shape of RFC 7591 (Dynamic Client Registration). A response containing a client_id is treated as proof the endpoint actually implements DCR — not just that the URL resolves.

JWKS check

A plain GET against the declared jwksUri must return a non-empty JWK Set. This is the same key material other participants would use to validate the institution's signed requests, so an unreachable or empty JWKS fails validation.

Outbound request safety

Both checks go through an SSRF guard that resolves the target host and rejects private, loopback and link-local addresses by default — a Directory instance is a trusted internal caller from the perspective of anything it validates, so it must not be usable as an open proxy against its host's own network. This can be relaxed per-deployment for ecosystems where declared endpoints legitimately live on private networks.

Idempotency & retries

Activation has no cooldown and no side effects beyond the status transition — it is safe to call again after fixing a failing endpoint. A response with a non-empty errors array names which of the two checks failed.

Rate limiting

POST /register, POST /login and POST /password-reset are all rate-limited per source IP (in-memory by default, Redis-backed if the deployment needs to run more than one replica) — independently of each other, so exhausting one doesn't affect the others.