feat(mtls): implement Issue #204 — mTLS mutual authentication#242
Merged
kelly-musk merged 2 commits intoMar 27, 2026
Merged
Conversation
3-tier CA hierarchy (Root/Intermediate/Leaf): - Root CA: offline-only key generation (CertificateAuthority::generate_root_ca) - Intermediate CA: runtime-loaded from secrets manager via MTLS_INTERMEDIATE_CA_CERT_PEM/KEY - Leaf certs: per-service, 90-day validity, issued only to REGISTERED_SERVICES allowlist Certificate lifecycle: - CertificateProvisioner: startup provisioning + 14-day rotation threshold - CertificateStore: in-memory store with zero-downtime rotation (current + previous) - CertLifecycleWorker: daily sweep, auto-rotates expiring certs, wired into main.rs mTLS enforcement middleware (Axum): - Reads X-Client-Cert-Subject / X-Client-Cert-Serial headers from TLS terminator - Validates: registered service, not revoked (CRL), service call allowlist (kellymusk#96) - MTLS_ENFORCE=false for dev; hard reject in production Revocation: - RevocationList: in-memory CRL with immediate serial blacklisting - RevocationService: revoke_certificate + OCSP-style status check - Admin revoke endpoint issues replacement cert atomically Admin endpoints (GET/POST /api/admin/security/certificates[/:svc/rotate|revoke]): - Wired under /api/admin/security prefix in main.rs - MtlsAdminState shared across handlers Infrastructure TLS (src/mtls/infra_tls.rs): - service_tls_identity(): returns (cert_pem, key_pem) for PostgreSQL/Redis mTLS - postgres_mtls_params(): helper for per-service DB client identity injection - Skips revoked/expired certs with structured warning log Observability: - aframp_mtls_cert_days_until_expiry gauge (per service) - aframp_mtls_handshake_total counter (from/to/result labels) - aframp_mtls_cert_rotations_total, cert_revocations_total, cert_issuances_total - Registered against prometheus::default_registry() at startup Tests: - Unit: subject parsing, trust chain, rotation threshold, OCSP status (cert.rs, revocation.rs) - Integration: full lifecycle, zero-downtime rotation, revocation rejection (tests/mtls_integration_test.rs) - Infra TLS: valid/revoked/expired/missing cert identity (infra_tls.rs) Migration: 20260327120000_mtls_certificate_lifecycle.sql
|
@rayeberechi Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR implements a comprehensive Mutual TLS (mTLS) framework, establishing a zero-trust communication layer for all internal microservices, databases, and Redis instances. This ensures transport-layer identity verification is mandatory before any application-layer data (JWTs) is exchanged.
Core Implementation
CertificateProvisionerthat automatically generates 90-day leaf certificates for all registered services at startup.CertLifecycleWorkerthat triggers automated rotation 14 days before expiry, maintaining overlapping validity to prevent connection drops.infra_tls.rsto provide dedicated mTLS identities for PostgreSQL and Redis connection pools, ensuring the entire data path is encrypted and authenticated.Security Enhancements & Fixes
mem::zeroedstubs in the provisioner, replacing them with a robustwithout_ca()graceful failure pattern.RevocationServicewith support for CRL/OCSP logic to immediately terminate connections from compromised service keys.Observability & Admin
GET /api/admin/security/certificates: Inventory of all active service certificates.POST /.../rotate: Manual admin-initiated rotation.POST /.../revoke: Immediate revocation and replacement issuance.Technical Specifications
infra_tls.rscovering valid, revoked, expired, and missing certificate states for infrastructure connections.cert.rsrelated to missingchronoimports.Verification
Closes #204