Agent Wranglers

Recommended

Authenticate calls between your own services

Make every service prove who it is on every call to another service, even inside a private network. Refuse a call without a valid identity, and allow each caller only the services it needs.

How to do it

A private network proves nothing about the caller. An attacker who gets into one server can call every service that trusts the network. Give each service its own identity, such as a client certificate for mutual TLS or a short-lived signed token from the platform. A service mesh, such as Istio or Linkerd, can add mutual TLS without code changes. Keep a list of the callers each service accepts, in code. Tokens between services follow Authenticate with tokens in headers.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

JavaScript example

import https from 'node:https';
import { readFileSync } from 'node:fs';

const ALLOWED_CALLERS = new Set(['orders.internal.example.com']);

https.createServer({
  key: readFileSync('/etc/tls/billing.key'),
  cert: readFileSync('/etc/tls/billing.crt'),
  ca: readFileSync('/etc/tls/internal-ca.crt'),
  requestCert: true,
  rejectUnauthorized: true,
}, (req, res) => {
  const caller = req.socket.getPeerCertificate().subject?.CN;
  if (!ALLOWED_CALLERS.has(caller)) return res.writeHead(403).end();
  res.end('ok');
}).listen(8443);

Python example

import requests

response = requests.get(
    "https://billing.internal.example.com:8443/invoices/42",
    cert=("/etc/tls/orders.crt", "/etc/tls/orders.key"),
    verify="/etc/tls/internal-ca.crt",
    timeout=5,
)

Shell example

# Run from an app server. A call without a client certificate must fail.
curl -sS --cacert /etc/tls/internal-ca.crt https://billing.internal.example.com:8443/invoices/42 \
  && echo "FAIL: call without identity accepted"

How to check

From a server inside the network, a call to an internal service with no certificate or token fails the handshake or gets 401. A call with a valid identity that is missing from the caller list gets 403.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/infrastructure/networking-and-dns/service-to-service-auth">Agent Wranglers infrastructure playbook</a>. In code you write, add a comment next to it with the same link.