Secure Agent Communication: TLS, mTLS, and Encrypted Message Passing
Master transport security for multi-agent systems including TLS configuration, mutual TLS authentication, encrypted message passing between agents, service mesh integration, and zero-trust networking principles.
Why Agent Communication Security Matters
In a multi-agent system, agents exchange messages that contain user data, reasoning traces, tool call results, and coordination instructions. If these messages travel over unencrypted channels, any network-level attacker can eavesdrop on sensitive data or inject malicious messages that alter agent behavior.
The threat model for agent-to-agent communication includes passive eavesdropping, message tampering, replay attacks, and impersonation. A compromised agent that can forge messages from a trusted agent can escalate privileges across the entire system. Transport security is the first defense layer.
TLS for Agent HTTP Endpoints
When agents communicate over HTTP, enforce TLS 1.3 as the minimum protocol version. Configure your agent servers to reject older protocol versions and weak cipher suites:
import ssl
import aiohttp
from aiohttp import web
def create_tls_context() -> ssl.SSLContext:
"""Create a strict TLS context for agent servers."""
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
ctx.load_cert_chain(
certfile="/etc/certs/agent-server.crt",
keyfile="/etc/certs/agent-server.key",
)
ctx.load_verify_locations("/etc/certs/ca.crt")
# Disable compression to prevent CRIME attacks
ctx.options |= ssl.OP_NO_COMPRESSION
return ctx
async def agent_message_handler(request: web.Request) -> web.Response:
"""Handle incoming agent-to-agent messages over TLS."""
payload = await request.json()
agent_id = payload.get("sender_agent_id")
message = payload.get("message")
# Process the inter-agent message
result = await process_agent_message(agent_id, message)
return web.json_response({"status": "ok", "result": result})
async def process_agent_message(agent_id: str, message: dict) -> dict:
return {"acknowledged": True, "from": agent_id}
app = web.Application()
app.router.add_post("/agent/message", agent_message_handler)
# Run with TLS
ssl_ctx = create_tls_context()
# web.run_app(app, ssl_context=ssl_ctx, port=8443)
Mutual TLS: Authenticating Both Sides
Standard TLS authenticates only the server. In multi-agent systems, you need mutual TLS (mTLS) so that each agent proves its identity to the other. Both the client and server present certificates signed by a trusted certificate authority:
def create_mtls_server_context() -> ssl.SSLContext:
"""Server context that requires client certificates."""
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
ctx.load_cert_chain(
certfile="/etc/certs/server.crt",
keyfile="/etc/certs/server.key",
)
ctx.load_verify_locations("/etc/certs/ca.crt")
# Require client certificate
ctx.verify_mode = ssl.CERT_REQUIRED
return ctx
def create_mtls_client_context() -> ssl.SSLContext:
"""Client context that presents its own certificate."""
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
# Client presents its certificate
ctx.load_cert_chain(
certfile="/etc/certs/agent-client.crt",
keyfile="/etc/certs/agent-client.key",
)
ctx.load_verify_locations("/etc/certs/ca.crt")
return ctx
async def send_secure_message(target_url: str, message: dict) -> dict:
"""Send a message to another agent using mTLS."""
ssl_ctx = create_mtls_client_context()
async with aiohttp.ClientSession() as session:
async with session.post(
target_url,
json=message,
ssl=ssl_ctx,
) as response:
return await response.json()
Encrypted Message Payloads
TLS protects data in transit, but messages may pass through intermediaries such as message queues or logging systems. Add payload-level encryption so messages remain confidential even at rest:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
import json
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
class AgentMessageEncryptor:
"""Encrypts and decrypts agent messages using AES-256-GCM."""
def __init__(self, shared_key: bytes):
if len(shared_key) != 32:
raise ValueError("Key must be 32 bytes for AES-256")
self.aesgcm = AESGCM(shared_key)
def encrypt(self, message: dict, associated_data: bytes = b"") -> dict:
"""Encrypt a message dict, returning nonce + ciphertext."""
plaintext = json.dumps(message).encode("utf-8")
nonce = os.urandom(12) # 96-bit nonce for GCM
ciphertext = self.aesgcm.encrypt(nonce, plaintext, associated_data)
return {
"nonce": nonce.hex(),
"ciphertext": ciphertext.hex(),
"aad": associated_data.hex(),
}
def decrypt(self, encrypted: dict) -> dict:
"""Decrypt a message dict."""
nonce = bytes.fromhex(encrypted["nonce"])
ciphertext = bytes.fromhex(encrypted["ciphertext"])
aad = bytes.fromhex(encrypted.get("aad", ""))
plaintext = self.aesgcm.decrypt(nonce, ciphertext, aad)
return json.loads(plaintext.decode("utf-8"))
# Usage
key = os.urandom(32) # In production, load from a secrets manager
encryptor = AgentMessageEncryptor(key)
message = {"tool_result": "Patient record #4521", "confidence": 0.95}
encrypted = encryptor.encrypt(message, associated_data=b"agent-A-to-agent-B")
decrypted = encryptor.decrypt(encrypted)
Zero-Trust Networking for Agents
Zero trust means no agent is trusted by default, regardless of network location. Every request is authenticated, authorized, and encrypted. Implement zero trust by combining mTLS identity with per-request authorization tokens:
import hashlib
import hmac
import time
class ZeroTrustMiddleware:
"""Validates agent identity and request authenticity."""
def __init__(self, signing_secret: str, max_age_seconds: int = 30):
self.signing_secret = signing_secret.encode()
self.max_age = max_age_seconds
def sign_request(self, agent_id: str, payload: bytes) -> dict:
"""Create signed headers for an outgoing agent request."""
timestamp = str(int(time.time()))
message = f"{agent_id}:{timestamp}:".encode() + payload
signature = hmac.new(self.signing_secret, message, hashlib.sha256).hexdigest()
return {
"X-Agent-ID": agent_id,
"X-Timestamp": timestamp,
"X-Signature": signature,
}
def verify_request(self, headers: dict, payload: bytes) -> bool:
"""Verify incoming request authenticity."""
agent_id = headers.get("X-Agent-ID", "")
timestamp = headers.get("X-Timestamp", "0")
signature = headers.get("X-Signature", "")
# Check timestamp freshness to prevent replay attacks
age = abs(int(time.time()) - int(timestamp))
if age > self.max_age:
return False
expected_message = f"{agent_id}:{timestamp}:".encode() + payload
expected_sig = hmac.new(
self.signing_secret, expected_message, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_sig)
FAQ
When should I use mTLS versus API keys for agent authentication?
Use mTLS when agents run as long-lived services that need continuous authenticated communication — it provides strong identity without per-request credential management. Use API keys when agents are short-lived or when you need simpler key rotation. In high-security environments, combine both: mTLS for transport identity and API keys for application-level authorization.
How do I manage certificate rotation without downtime?
Use a certificate management system like cert-manager in Kubernetes or Vault PKI. Issue short-lived certificates (hours or days, not years) and rotate them automatically before expiry. Configure your TLS contexts to reload certificates from disk without restarting the process. Service meshes like Istio handle this transparently.
Is payload encryption necessary if I already have TLS?
It depends on your threat model. TLS protects data in transit between two endpoints, but if messages are stored in a queue, logged, or pass through a proxy, they are decrypted at those points. Payload encryption provides end-to-end confidentiality between the sending and receiving agents regardless of the transport path.
#TLS #MTLS #AgentCommunication #ZeroTrust #ServiceMesh #AgenticAI #LearnAI #AIEngineering
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.