TLS & PKI
AuthNexus employs a four-CA Public Key Infrastructure with mutual TLS (mTLS) for all inter-component communication and client authentication. This design provides cryptographic isolation between management, node-to-CP, business, and application layers.
Four Independent Certificate Authorities
Each CA serves a distinct trust domain. No CA shares keys or trust chains with another.
| CA Profile | Trust Domain | Purpose |
|---|---|---|
cp_server_ca | Management plane | Signs the Control Plane's HTTPS server certificate |
cp_node_client_ca | Node-to-CP | Signs client certificates used by server nodes to authenticate to the Control Plane |
tcp_server_ca | Business plane | Signs business TCP server certificates presented to SDK clients |
app_client_ca | Application | Signs SDK/application client certificates for mTLS with server nodes |
All four CAs are initialized during the first-run setup wizard. Until initialization completes, the Control Plane remains in setup-only mode and will not serve /cp/* endpoints.
CA Storage
CA private keys and certificates are stored in the Control DB. The PKI subsystem generates keys using OpenSSL 3.x with appropriate key lengths. CA certificates are self-signed root certificates -- AuthNexus does not depend on external CAs or public certificate authorities.
mTLS Handshake Validation
Business mTLS connections (SDK to server node) are validated through four layers of trust, not merely the CA chain:
Layer 1: CA Trust Chain
The standard X.509 chain validation -- the client certificate must chain to the app_client_ca root, and the server certificate must chain to tcp_server_ca.
Layer 2: Certificate Semantics
- The client certificate must include the
clientAuthExtended Key Usage (EKU). - The client certificate must contain a URI Subject Alternative Name (SAN) in the format
urn:authnexus:app:<app_id>, binding the certificate to a specific application.
Layer 3: Control Plane Binding
app_mtls_trust_bundle-- the CA trust bundle published to nodes, controlling which client CAs are accepted.app_cert_bindings-- explicit certificate-to-application bindings tracked in the Control DB.
Layer 4: Business Handshake Verification
During the application-level handshake (after TLS), the claimed app_id in the SDK's initial message must match the app_id embedded in the client certificate's URI SAN.
Node-to-CP mTLS
Server nodes authenticate to the Control Plane using cp_node_client_ca-issued certificates. The CP server presents a cp_server_ca-issued certificate. This channel carries all /cp/v2/* traffic (Channels 1, 2, and 3).
Enrollment Flow
- Admin creates a node in the Control Plane UI.
- CP generates an enrollment token and a deploy package containing
node_agent.json, certificates, and keys. - The server node boots with
--node-agent node_agent.jsonand enrolls via the/cp/v2/nodes/:id/checkinendpoint. - Enrollment is determined by certificate file presence. After reissuance, old certificates must be removed for the node to re-enroll.
OCSP Stapling
AuthNexus implements RFC 6960 OCSP stapling for real-time certificate revocation enforcement.
Architecture
- The CP runs an
OcspResponderthat signs OCSP responses on-demand (no caching). - Each server node runs an
OcspStaplingManagerthat periodically fetches OCSP responses over plain HTTP (Channel 4, port 9092). - Fetched responses are cached locally and stapled into TLS handshakes with SDK clients.
Stapling Lifecycle
- Node requests OCSP response from CP every ~15 minutes (adaptive:
nextUpdate / 2). - CP signs the response with the
tcp_server_cakey. - Node caches the response and includes it in every TLS handshake.
- SDK verifies the stapled response using
ocsp_signer_ca.pem.
Revocation Behavior
When a node receives a revoked OCSP response:
- The node continues to staple the revoked response to SDK clients.
- SDK clients with
must-staplecertificates reject the handshake (fail-closed on the business side). - The node does not self-shutdown. Management channels remain alive so the admin can re-enable the node, which then recovers automatically.
Why Plain HTTP for OCSP?
OCSP responses carry their own RSA-SHA256 signature -- TLS transport is redundant. Plain HTTP on a dedicated port avoids mTLS handshake overhead and prevents resource contention with SSE long connections.
App Client CA Hot Replacement
Application client CAs can be replaced at runtime through a generation-based mechanism:
- Admin publishes a new
app_client_ca_bundlevia the Control Plane. - The configuration propagates to server nodes via Channel 1 config pull.
- The server creates a new TLS context with the updated CA trust store.
- In-flight handshakes on the old TLS context are rejected -- no grace period.
This ensures that revoked or rotated CAs take effect immediately without requiring a server restart.
SDK Trust Policy
The SDK uses a TrustPolicy structure (loaded from authnexus_trust.json or configured programmatically) to verify the server:
struct TrustPolicy {
std::string server_ca_bundle_path; // CA bundle for chain validation
std::vector<std::string> ca_spki_pins_sha256; // SPKI pin set (RFC 7469 style)
std::vector<std::string> required_uri_sans; // Required URI SANs on server cert
std::vector<std::string> revoked_cert_sha256; // Revoked cert hashes
std::string ocsp_signer_ca_bundle_path; // OCSP signature verification CA
// Phase 2: pending pins for graceful CA rotation
std::vector<std::string> ca_spki_pins_sha256_pending;
uint64_t pending_pin_effective_at_unix_ms;
};Pin Rotation (Phase 2)
To support zero-downtime CA rotation, the trust policy supports pending pins:
- Before
pending_pin_effective_at_unix_ms: onlyca_spki_pins_sha256is enforced. Admins can pre-distribute the new pin to all SDKs. - After the effective time: both current and pending pin sets are accepted (
current UNION pending). Old nodes still match current pins; new nodes match pending.
Certificate Lifecycle
Issuance
Certificates are issued through the PKI job system. When a node is created or a rotation is requested, the CP creates asynchronous PKI jobs that:
- Generate a key pair for the entity.
- Create a Certificate Signing Request (CSR) with appropriate extensions (EKU, SANs).
- Sign the CSR with the relevant CA.
- Store the certificate in the Control DB.
- Package the certificate and key into a deploy package (for nodes) or cert package (for applications).
Rotation
Certificate rotation for nodes is managed through the admin API:
POST /admin/v1/nodes/:nid/certs/rotateThis triggers asynchronous PKI jobs (tracked at /admin/v1/pki/jobs) that:
- Issue new server and CP client certificates.
- Rebuild the node deploy package.
- Deliver the updated certificates to the node via Channel 1 config pull.
Revocation
Certificates can be revoked through the admin API:
POST /admin/v1/pki/certs/:id/revoke
POST /admin/v1/nodes/:nid/certs/:cid/revokeRevocation is immediate in the Control DB. For business certificates, the OCSP responder (Channel 4) will begin returning revoked status, which propagates to SDK clients via OCSP stapling.
Monitoring
The admin API provides endpoints for proactive certificate management:
GET /admin/v1/pki/expiring # Certificates approaching expiry
GET /admin/v1/pki/revocations # Revoked certificates list
GET /admin/v1/pki/audit-logs # Full PKI operation audit trailBest Practices
- Never share CA keys between the four trust domains.
- Use SPKI pins in SDK trust policies for defense-in-depth beyond CA chain validation.
- Monitor certificate expiration via the
/admin/v1/pki/expiringendpoint. - Test CA rotation in a staging environment before production rollout.
- Enable must-staple on business server certificates for strongest revocation enforcement.
Next Steps
- Security Model -- epoch-based session invalidation and blacklist enforcement
- Four-Channel Communication -- how mTLS protects inter-component traffic
- Operations Manual -- certificate rotation procedures