Axios with SSL Certificate
Mutual TLS (SSL client certificate)
As of TAS 5.17, you can configure a client SSL certificate for HTTPS requests (mutual TLS) using the applySslConfig() method. The method returns the same client instance, so it can be chained with further configuration (e.g. setVaultHeader).
Parameters
The method accepts a single configuration object opts:
Parameter | Type | Description |
|
| CA bundle (certificate authority). Optional. |
|
| Client certificate. Optional. |
|
| Private key for the client certificate. Optional. |
|
| Password for the private key (if the key is encrypted). Optional. |
|
| Whether to verify the server's SSL certificate. Default value |
|
| List of allowed TLS ciphers (OpenSSL format). Optional. Used for compatibility with older services — see the warning in the practical example. |
TAS 5.17 — certificate value via lib.getCertificate()
In version 5.17, the Vault does not yet consolidate certificates. The certificate value must be loaded the "old way" using lib.getCertificate(certName, encoding?) (default encoding binary) and passed into applySslConfig() as a string or Buffer.
const client = axios.getAxios({ baseURL: 'https://api.mutual-tls.example.com' });
client.applySslConfig({
ca: lib.getCertificate('mtls-ca'),
cert: lib.getCertificate('mtls-client-cert'),
key: lib.getCertificate('mtls-client-key'),
});
const response = client.get('/secure-endpoint');
return response.data;lib.getCertificatePath(certName).TAS 5.18 — certificates and external resources from the Vault via vault.get()
As of version 5.18, the Vault consolidates both sensitive values (API keys, passwords, tokens) and certificates and external resources (Administration → Vault, External resources tab). In a calculation, everything is loaded uniformly via vault.get(name), which returns a VaultSecretRef — this cannot be serialized or logged and is passed directly into applySslConfig().
const client = axios.getAxios({ baseURL: 'https://api.mutual-tls.example.com' });
client.applySslConfig({
ca: vault.get('MTLS_CA'),
cert: vault.get('MTLS_CLIENT_CERT'),
key: vault.get('MTLS_CLIENT_KEY'),
});
const response = client.get('/secure-endpoint');
return response.data;vault.get(...)) is used in 5.18 to load values from external resources defined at the server configuration level, e.g. in the .env file.rejectUnauthorized: false disables verification of the server certificate and exposes the connection to the risk of a MITM attack. Use only for testing against self-signed certificates, never in production.Practical example — SOAP call with a client certificate
The most common real-world use of mutual TLS is calling an older SOAP endpoint (typically a government service or a banking interface) that also authenticates with a client certificate. Compared to the simple client.get() above, three things are added: an XML body via Buffer.from, the SOAPAction header, and the use of requestRaw. Let's walk through the example step by step.
1. Request body via Buffer.from
By default, axios serializes the body as JSON. A SOAP envelope, however, is XML — to have axios send it unchanged, wrap it in a binary Buffer:
const payload = Buffer.from(xml, 'utf-8');
The xml variable contains a ready-made SOAP envelope as text; Buffer.from(..., 'utf-8') converts it into binary data.
2. Client with an explicit timeout
SOAP services tend to be slower, so set a sufficient timeout (in milliseconds). The default value of 0 follows the global calculation timeout (120 s), which may not be enough for a slow service:
const client = axios.getAxios({
timeout: 300000
});3. Setting the certificate
The configuration is the same as in the examples above — here with values from the Vault via lib.getCertificate() (TAS 5.17). In addition, two security-reducing parameters appear, which legacy SOAP services often require:
client.applySslConfig({
cert: lib.getCertificate('client.pem'),
key: lib.getCertificate('client.key'),
rejectUnauthorized: false,
ciphers: "DEFAULT@SECLEVEL=0"
});The ciphers parameter defines the allowed TLS ciphers. The value DEFAULT@SECLEVEL=0 lowers the OpenSSL security level and allows older, otherwise disabled ciphers and weaker keys — without it, a connection to older services may fail to be established.
rejectUnauthorized: false and ciphers: "DEFAULT@SECLEVEL=0" deliberately reduces connection security — it disables server certificate verification (MITM risk) and allows outdated ciphers. Use it only where the counterparty genuinely requires it. If the service runs on a modern certificate, omit both options.4. Sending via requestRaw
SOAP is sent using the POST method. The SOAPAction header is mandatory in SOAP 1.1 — the value '""' (empty quotes) is used when the service does not require a specific action. requestRaw is used because the status code and headers are usually needed from the SOAP response:
const result = client.requestRaw({
method: 'POST',
url,
data: payload,
headers: {
'SOAPAction': '""'
}
});requestRaw (as of version 5.7.37) returns the full response { data, status, statusText, headers } and does not throw an exception on an error status — so check the status code manually (e.g. if (result.status !== 200)). The classic methods (get, post, …) return data directly and throw an exception on error; use those for regular JSON APIs where you don't need the status or headers.Complete code
const payload = Buffer.from(xml, 'utf-8');
const client = axios.getAxios({
timeout: 300000
});
client.applySslConfig({
cert: lib.getCertificate('client.pem'),
key: lib.getCertificate('client.key'),
rejectUnauthorized: false,
ciphers: "DEFAULT@SECLEVEL=0"
});
const result = client.requestRaw({
method: 'POST',
url,
data: payload,
headers: {
'SOAPAction': '""'
}
});
result holds the response directly. Never use async, await, .then(), or Promise; the TAS transpilation would cause the calculation to fail silently.
Updated
by Frantisek Brych