DEV Community

Arti Jain
Arti Jain

Posted on

A Quick Intro to Mutual TLS (mTLS)

Most APIs today run over HTTPS. In a typical setup, the client checks the server’s certificate to make sure it’s talking to the right host. That may be enough when you’re building a public REST API where clients authenticate using API keys or tokens.

But in banking and fintech, the communication is often system-to-system. Think of a bank’s backend calling a payment processor, or two financial institutions exchanging transaction data. In these cases, both sides need to prove who they are. Before any communication starts, the domains/parties has to have trust. Relying only on TLS plus an API key isn’t strong enough.

This is the place Mutual TLS (mTLS) comes in and widely used.

TLS vs. mTLS

Here’s the difference:

  • TLS (standard HTTPS): The client validates the server’s certificate. The server only sees whatever credentials (API key, OAuth token, etc.) the client sends later in the request.
  • mTLS: Both the client and the server exchange certificates during the TLS handshake. Each validates the other before any request is processed.

With mTLS, if a client doesn’t have a valid certificate signed by a trusted CA, the connection is dropped immediately. This prevents unknown or unauthorized services from even hitting the secure service endpoints.

Why This Matters in Fintech

In financial systems (fintech), each service is dealing with regulated data, strict compliance rules, and high risk if something goes wrong. Tokens can leak. API keys can get exposed in logs. With mTLS, authentication is baked directly into the connection itself.

That’s why banks, clearing houses, insurance, and payment processors often mandate mTLS for system-to-system integration. It gives both sides cryptographic assurance of who’s on the other end.

Node.js sample: Code to connect to am M-TLS API

Here’s how you’d connect to an mTLS-enabled service using Node’s built-in https module:

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

const options = {
  hostname: 'api.financial-service.com',
  port: 443,
  path: '/transactions',
  method: 'GET',
  key: fs.readFileSync('client-key.pem'),       // your private key
  cert: fs.readFileSync('client-cert.pem'),     // your client certificate
  ca: fs.readFileSync('ca-cert.pem')            // trusted CA cert
};

const req = https.request(options, (res) => {
  let body = '';
  res.on('data', chunk => body += chunk);
  res.on('end', () => console.log(body));
});

req.on('error', (err) => {
  console.error('Request failed:', err);
});

req.end();

Enter fullscreen mode Exit fullscreen mode

When you run this, Node presents your certificate during the TLS handshake. If the server trusts it, the request goes through. If not, the connection never establishes.

Tooling Gaps

If you’ve used Postman or curl for API testing, you know how smooth the developer experience is with regular APIs. mTLS isn’t quite there yet.

This lack of mature tooling makes mTLS harder to adopt, especially for teams that need to test locally or debug production issues. For fintech and banking developers, that usually means building custom setups and relying more on logs than friendly tooling.

Top comments (0)