Overview
WhenVANE_MTLS_CA_CERT is set, the Vane server switches from HTTP to HTTPS and requests (but does not require) a client certificate on every connection. Clients that present a certificate signed by the configured CA, with a Common Name (CN) matching a registered company ID, authenticate via that certificate without needing a Bearer token.
Clients without certificates fall through to normal API key / OAuth token authentication, so existing callers continue to work unmodified.
Configuration
Three environment variables are required to enable mTLS:
If
VANE_MTLS_CA_CERT is set but VANE_TLS_CERT or VANE_TLS_KEY is missing, the server logs a fatal error and exits.
How authentication works
- A client connects with a TLS client certificate whose CN is
acme. - Node.js presents the certificate to Vane via the
TLSSocket.getPeerCertificate()API. - Vane extracts the CN and looks up
acmein the database. - If
acmeis a registered company, the request is authenticated as that company. No Bearer token required. - If the CN does not match a registered company, or no certificate was presented, authentication falls through to Bearer token validation.
requestCert: true, rejectUnauthorized: false — it requests a certificate from every client but does not terminate connections that omit one. This ensures backward compatibility.
What mTLS protects
Without mTLS: An attacker who intercepts an API key can make authenticated requests from anywhere. The API key is a static credential. With mTLS: Authentication requires possession of a valid private key whose certificate was signed by the configured CA. The API key alone is insufficient. mTLS is most valuable when:- Agents are running in infrastructure you control (e.g., k8s pods with automatically-rotated TLS credentials via cert-manager).
- You want to enforce that API calls can only come from specific machines, not just anyone with the key string.
- You are integrating with SPIRE or another SPIFFE-compatible workload identity system that issues client certificates.