How to Set Up Client Certificates in Axios

This guide explains how to configure Mutual TLS (mTLS) authentication in Node.js using the Axios HTTP client. You will learn how to load your client certificate, private key, and Certificate Authority (CA) bundle using Node.js's native https module and attach them to Axios requests via a custom HTTPS agent.


Understanding Axios mTLS Configuration

Axios itself does not handle raw TLS/SSL socket connections directly in Node.js; instead, it relies on Node's built-in https module. To perform mutual SSL authentication, you must create an https.Agent configured with your credentials and pass it to your Axios instance.

Prerequisites

Ensure you have your certificate files ready:

Step-by-Step Implementation

1. Load the Certificates

Read your certificate and key files from the file system using Node.js's fs module:

const fs = require('fs');
const path = require('path');

const cert = fs.readFileSync(path.resolve(__dirname, 'certs/client-cert.pem'));
const key = fs.readFileSync(path.resolve(__dirname, 'certs/client-key.pem'));
const ca = fs.readFileSync(path.resolve(__dirname, 'certs/ca-cert.pem'));

2. Create the HTTPS Agent

Instantiate an https.Agent and provide the certificate properties:

const https = require('https');

const httpsAgent = new https.Agent({
  cert: cert,
  key: key,
  ca: ca,
  rejectUnauthorized: true // Ensures server certificate validity
});

3. Attach the Agent to Axios

You can apply the httpsAgent to a single request or create a reusable Axios instance.

Option A: Using an Axios Instance (Recommended)

const axios = require('axios');

const apiClient = axios.create({
  baseURL: 'https://secure-api.example.com',
  httpsAgent: httpsAgent,
  timeout: 10000
});

async function makeRequest() {
  try {
    const response = await apiClient.get('/data');
    console.log('Response:', response.data);
  } catch (error) {
    console.error('Request failed:', error.message);
  }
}

makeRequest();

Option B: On a Single Request

const axios = require('axios');

async function makeSingleRequest() {
  try {
    const response = await axios.get('https://secure-api.example.com/data', {
      httpsAgent: httpsAgent
    });
    console.log('Response:', response.data);
  } catch (error) {
    console.error('Request failed:', error.message);
  }
}

makeSingleRequest();

Alternative Configurations

Password-Protected Private Keys

If your private key requires a passphrase, supply the passphrase property to the https.Agent:

const httpsAgent = new https.Agent({
  cert: cert,
  key: key,
  passphrase: 'your-private-key-password',
  ca: ca
});

PKCS#12 (.p12 / .pfx) Files

If your certificate and private key are bundled inside a single .p12 or .pfx file, use the pfx property instead of cert and key:

const pfx = fs.readFileSync(path.resolve(__dirname, 'certs/client.p12'));

const httpsAgent = new https.Agent({
  pfx: pfx,
  passphrase: 'your-pfx-password',
  ca: ca
});