Skip to main content
Mole securing connections

TLS and Mutual TLS

Layered Security Model

Muti Metroo uses a layered security model:

  1. End-to-End Encryption (Primary): X25519 key exchange + ChaCha20-Poly1305 encrypts all stream data. Transit agents cannot decrypt traffic - only ingress and exit agents can read the payload.

  2. Transport TLS (Defense-in-depth): TLS 1.3 encrypts the transport layer. This provides an additional encryption layer but is not the primary security mechanism.

Because of the E2E encryption layer, TLS certificate verification is optional by default. Agents auto-generate self-signed certificates and don't verify peer certificates. This allows quick deployment without PKI setup while maintaining strong security guarantees.

Configuration

See TLS Certificates Configuration for all options including certificate paths, strict mode, and mTLS setup.

TLS Verification Modes

ModeCertificate VerificationUse Case
DefaultNone (auto-generated certs)Quick deployment, development
StrictCA-based verificationProduction, compliance
Strict + mTLSMutual authenticationZero-trust, high-security

Why Default No-Verification is Safe

The default configuration doesn't verify TLS certificates, yet remains secure:

  1. E2E Encryption: Stream data is encrypted with ChaCha20-Poly1305 using keys derived from X25519 exchange. Even if a MITM intercepts TLS, they cannot decrypt stream content.

  2. Agent ID Verification: Peers verify each other's Agent ID during handshake. This is independent of TLS certificates.

  3. Double Encryption: Traffic is encrypted twice - once at the E2E layer, once at TLS. A MITM would need to break both.

When to Enable Strict Mode

Enable strict: true when you need:

  • Defense-in-depth: Additional validation beyond E2E encryption
  • Network access control: Reject connections from agents without valid certificates
  • Compliance requirements: Environments requiring PKI-based authentication
  • Early MITM detection: TLS verification can detect interception attempts earlier

When to Enable mTLS

Enable mtls: true (mutual TLS) when you need:

  • Mutual authentication: Both sides must present valid certificates
  • Network-level access control: Only agents with valid certs can connect
  • Early rejection: Unauthorized connections rejected at TLS, before protocol handshake
  • Zero-trust compliance: Required for many security frameworks

Certificate Requirements

Important: Muti Metroo only accepts EC (Elliptic Curve) certificates. RSA certificates are rejected.

Generate certificates using the built-in CLI:

# Generate CA
muti-metroo cert ca --cn "My Mesh CA" -o ./certs

# Generate agent certificate
muti-metroo cert agent --cn "agent-1" \
--ca ./certs/ca.crt \
--ca-key ./certs/ca.key \
-o ./certs

See cert command for full options.

Mixed TLS Environments

When connecting through public proxies (like nginx with Let's Encrypt) while using strict TLS internally, you can disable verification for specific peers:

  • Internal peers: Verified against your internal CA
  • Public proxy peers: Skip verification (E2E encryption still protects traffic)

This is safe because E2E encryption protects all traffic regardless of TLS verification status.

Security Properties

What TLS Verification Adds

FeatureWithout StrictWith StrictWith mTLS
Transport encryptionYesYesYes
E2E encryptionYesYesYes
Server identity verificationNoYesYes
Client identity verificationNoNoYes
Early MITM detectionNoYesYes
Network-level access controlNoPartialFull

What's Always Protected

Regardless of TLS mode, your traffic is protected by:

  • E2E encryption (ChaCha20-Poly1305)
  • Agent ID verification during handshake
  • Integrity checking (AEAD authentication)

Troubleshooting

Certificate Not Trusted

Error: x509: certificate signed by unknown authority

Cause: strict: true is enabled but the CA certificate is missing or incorrect.

Solutions:

  • Verify CA certificate path is correct
  • Check certificate was signed by the configured CA: openssl verify -CAfile ca.crt agent.crt

Certificate Expired

Error: x509: certificate has expired

Solution: Check expiration with openssl x509 -enddate -noout -in agent.crt and regenerate if needed.

RSA Certificate Rejected

Error: certificate must use ECDSA, got RSA

Cause: Muti Metroo only accepts EC certificates.

Solution: Regenerate using the CLI: muti-metroo cert agent ...

Client Certificate Required

Error: tls: client didn't provide a certificate

Cause: The listener has mTLS enabled but the connecting peer doesn't have a certificate configured.

Solution: Configure tls.cert and tls.key on the connecting agent.

Decision Guide

ScenarioRecommended Mode
Development/testingDefault (no verification)
Internal mesh, trusted networkDefault or Strict
Production with compliance needsStrict
Zero-trust environmentStrict + mTLS
Mixed internal/external peersPer-peer overrides

Next Steps