Documentation Index
Fetch the complete documentation index at: https://snakysec.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
ADR-003 — X.509 certificate auth over client_secret for Entra ID
Date: 2025-02-01 Status: Accepted Deciders: Nicolas (founder)Context
The platform authenticates to Microsoft Entra ID as a multi-tenant application to obtain access tokens for Microsoft Graph API and Exchange Online. Two auth methods are available:client_secret (shared password) and certificate-based (client_assertion JWT signed with RSA private key).
Decision
X.509 certificate auth (client_assertion / private_key_jwt) is the primary authentication method. client_secret remains supported as a fallback for dev/legacy environments.
Rationale
- Security: Certificates cannot be extracted from Entra ID portal and used elsewhere; secrets can be copy-pasted. Recommended by Microsoft for production applications.
- Compliance: Microsoft’s own SCuBA guidelines (MS.AAD) and CIS M365 recommend service principal certificate auth
- No secret expiry surprises: Certificates have explicit expiry dates managed in Vault; client secrets have hard 2-year max in Entra ID and are often forgotten until they expire
- Audit trail: Certificate thumbprint (
x5t) is logged in Entra ID sign-in logs — attribution is unambiguous
Implementation
lib/auth-cert.ts:createClientAssertion()→ RS256 JWT, 10-minute window, uniquejti(replay protection)x5tthumbprint computed from DER-encoded cert (SHA-1, base64url) — cached in module scopeapplyClientAuth()transparently selects cert vs secret based on env vars- NextAuth v5
token.requestoverride handles the initial code exchange withclient_assertion
Certificate rotation procedure
See runbook:docs/runbooks/key-rotation.md
Consequences
ENTRA_CERT_PRIVATE_KEY+ENTRA_CERT_PEMstored in Vault; set viavault kv patch- Certificate must be registered in Entra ID app registration (Certificates & secrets)
openssl req -x509 -newkey rsa:2048 ...— RSA-2048 minimum; RSA-3072 recommended for new certs post-2026- Tests:
src/lib/__tests__/auth-cert.test.tsvalidates JWT structure + replay protection
Alternatives rejected
- Managed Identity: Only works on Azure-hosted infrastructure; our Docker/VPS deployment target doesn’t support it
- Federated credentials (OIDC): Viable for GitLab CI pipelines — partially implemented via
ENTRA_OIDC_TOKENin the audit worker