Directory. / developers

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.