Configure mTLS Authentication with Axios
Mutual TLS (mTLS) provides two-way cryptographic verification between
a client and a server to ensure that both parties are authenticated
before exchanging data. In this guide, you will learn how to configure
mTLS in a Node.js environment using the Axios HTTP client by leveraging
Node.js's native https module to pass client certificates,
private keys, and certificate authority (CA) bundles.
Prerequisites
To implement mTLS with Axios, you need the following certificate files provided by your server administrator or PKI:
- Client Certificate (
client.crt): The public certificate identifying the client. - Client Private Key (
client.key): The private key associated with the client certificate. - CA Certificate (
ca.crt): The root or intermediate Certificate Authority certificate used to verify the server's certificate.
Step-by-Step Configuration
Because Axios runs on top of Node.js's native HTTP/HTTPS modules,
mTLS is configured by creating an instance of https.Agent
and passing it to Axios via the httpsAgent option.
1. Load Certificate Files
Read the certificates from your file system using Node.js's
fs module:
const fs = require('fs');
const path = require('path');
const clientCert = fs.readFileSync(path.resolve(__dirname, 'certs/client.crt'));
const clientKey = fs.readFileSync(path.resolve(__dirname, 'certs/client.key'));
const caCert = fs.readFileSync(path.resolve(__dirname, 'certs/ca.crt'));2. Create the HTTPS Agent
Instantiate an https.Agent with your credentials:
const https = require('https');
const httpsAgent = new https.Agent({
cert: clientCert,
key: clientKey,
ca: caCert,
rejectUnauthorized: true // Ensures the server certificate is verified against the provided CA
});3. Attach the Agent to Axios
You can apply the custom agent to a dedicated Axios instance or to individual requests.
Using an Axios Instance (Recommended)
Creating a reusable instance ensures all requests sent through it automatically include the mTLS credentials:
const axios = require('axios');
const apiClient = axios.create({
baseURL: 'https://api.example.com',
httpsAgent: httpsAgent,
timeout: 10000
});
async function makeSecureRequest() {
try {
const response = await apiClient.get('/secure-data');
console.log('Response:', response.data);
} catch (error) {
console.error('mTLS Request Failed:', error.message);
}
}
makeSecureRequest();Using Per-Request Configuration
Alternatively, you can pass the httpsAgent directly
inside a single request's configuration object:
axios.get('https://api.example.com/secure-data', { httpsAgent })
.then(response => console.log(response.data))
.catch(error => console.error(error));Additional Configurations
Encrypted Private Keys (Passphrase)
If your client private key is encrypted with a password, provide the
passphrase property to the https.Agent:
const httpsAgent = new https.Agent({
cert: clientCert,
key: clientKey,
passphrase: 'your-private-key-password',
ca: caCert
});PKCS#12 / PFX Bundles
If your certificate and private key are bundled in a
.pfx or .p12 file, use the pfx
property instead of cert and key:
const pfxBundle = fs.readFileSync(path.resolve(__dirname, 'certs/bundle.p12'));
const httpsAgent = new https.Agent({
pfx: pfxBundle,
passphrase: 'your-bundle-password',
ca: caCert
});