Certificates & mTLS
Certificate lifecycle and sender-constrained tokens
Directory operates its own certificate authority and, on top of it, sender-constrained (RFC 8705) session and service-credential tokens.
Certificate issuance
POST /admin/institutions/{id}/certificates issues an X.509 certificate (RSA-2048, valid for both ServerAuth and ClientAuth) signed by the Directory's root CA. The private key is returned once, in the response body, and never stored — losing it means issuing a new certificate, not recovering the old one.
curl -X POST https://directory.open.dev.br/admin/institutions/{institutionId}/certificates \
-H "Authorization: Bearer {sessionToken}"
{
"certPem": "-----BEGIN CERTIFICATE-----...",
"keyPem": "-----BEGIN RSA PRIVATE KEY-----...",
"serialNumber": "4F3A9C...",
"subjectDn": "CN=Example Bank,O=Example Bank"
}
Revocation
POST /admin/institutions/{id}/certificates/{serialNumber}/revoke flips the certificate's status to REVOKED. The public listing at GET /organisations/{id}/certificates reflects the current status of every certificate an institution has ever been issued — active or revoked.
Sender-constrained tokens (RFC 8705)
A Bearer token — a session from POST /login, or a service credential from POST .../service-credential — can be bound to a client mTLS certificate presented at the moment it's issued. Once bound, every later authenticated request must present the same certificate, or the request is rejected even with a valid Bearer token. The certificate does not need to be issued by any particular CA — self-signed is sufficient, since this mechanism binds a token to a key pair, it does not authenticate via a trust chain.
# Generate a certificate — any CA, including none, works
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout client.key -out client.crt -days 3650 \
-subj "/CN=example-bank"
# Presenting it at login binds the session it returns
curl --cert client.crt --key client.key \
-X POST https://directory.open.dev.br/login \
-d '{ "email": "admin@example.com", "password": "..." }'
# Every later call with that session must present the same certificate
curl --cert client.crt --key client.key \
https://directory.open.dev.br/admin/institutions/{institutionId} \
-H "Authorization: Bearer {sessionToken}"
DIRECTORY_REQUIRE_MTLS_BINDING (a deployment setting, off by default) makes presenting a certificate mandatory at /login, /register and /service-credential issuance. Binding already recorded on an existing session or credential is enforced regardless of this setting — turning it on later never invalidates a participant that was already presenting a certificate voluntarily.