Skip to main content

TLS Overview

NATS Server supports TLS (Transport Layer Security) to encrypt connections and authenticate clients using certificates. TLS is essential for production deployments.

Basic TLS Configuration

Server TLS

Enable TLS for client connections:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
}
Or via command line:
nats-server --tls --tlscert=/path/to/server-cert.pem --tlskey=/path/to/server-key.pem

Full TLS with Client Verification

tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
}
Or via command line:
nats-server --tlsverify --tlscert=server.pem --tlskey=key.pem --tlscacert=ca.pem

Certificate Files

Certificate Formats

NATS accepts PEM-encoded certificates: server-cert.pem:
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKu9MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
...
-----END CERTIFICATE-----
server-key.pem:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKr5r5YLY+RqZo
...
-----END PRIVATE KEY-----

Generating Self-Signed Certificates

For development/testing:
# Generate CA
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ca-key.pem -out ca.pem \
  -subj "/CN=NATS CA"

# Generate server certificate
openssl req -nodes -newkey rsa:2048 \
  -keyout server-key.pem -out server.csr \
  -subj "/CN=localhost"

# Sign server certificate
openssl x509 -req -days 365 -in server.csr \
  -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
  -out server-cert.pem
Never use self-signed certificates in production. Obtain certificates from a trusted Certificate Authority.

Client Certificate Verification

Mutual TLS (mTLS)

Require clients to present valid certificates:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
}

Certificate Mapping

Map certificate properties to user accounts:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  map_and_verify: true
}

authorization {
  users = [
    {
      user: "CN=alice,O=Company,C=US"
      permissions: {
        publish: ["orders.>"]
        subscribe: ["results.>"]
      }
    }
    {
      user: "CN=bob,O=Company,C=US"
      permissions: {
        publish: ["events.>"]
        subscribe: ["data.>"]
      }
    }
  ]
}

Certificate Pinning

Pin specific client certificates:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  verify: true
  pinned_certs: [
    "/path/to/client1-cert.pem",
    "/path/to/client2-cert.pem"
  ]
}

Cipher Suites

NATS Server supports modern, secure cipher suites.

Default Cipher Suites

From server/ciphersuites.go, NATS uses Go’s tls.CipherSuites() which includes:
  • TLS_AES_128_GCM_SHA256 (TLS 1.3)
  • TLS_AES_256_GCM_SHA384 (TLS 1.3)
  • TLS_CHACHA20_POLY1305_SHA256 (TLS 1.3)
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305

Custom Cipher Suites

tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  cipher_suites: [
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
  ]
}

Curve Preferences

From server/ciphersuites.go:66-73, default curves (in order):
  1. X25519MLKEM768 - Post-quantum hybrid
  2. X25519 - Fast elliptic curve
  3. CurveP256
  4. CurveP384
  5. CurveP521
Custom curve preferences:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  curve_preferences: [
    "X25519MLKEM768",
    "CurveP256"
  ]
}
NATS prioritizes post-quantum cryptography with X25519MLKEM768 by default.

FIPS Mode

When FIPS 140 mode is enabled (server/ciphersuites.go:56-65):
  • X25519 alone is excluded (not FIPS-approved)
  • X25519MLKEM768 is included (FIPS-approved when combined with MLKEM768)
  • Only FIPS-compliant cipher suites are available

TLS Versions

Minimum TLS Version

tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  min_version: "1.3"
}
Supported values:
  • 1.0 (deprecated, not recommended)
  • 1.1 (deprecated, not recommended)
  • 1.2 (minimum recommended)
  • 1.3 (recommended)
Always use TLS 1.2 or higher. TLS 1.3 provides better performance and security.

TLS Timeout

Configure TLS handshake timeout:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  timeout: 2.0  # seconds
}

TLS for Cluster Routes

Secure cluster communication:
cluster {
  name: "production"
  listen: "0.0.0.0:6222"
  
  tls {
    cert_file: "/path/to/route-cert.pem"
    key_file: "/path/to/route-key.pem"
    ca_file: "/path/to/ca.pem"
    verify: true
  }
  
  routes: [
    "nats://server2:6222"
    "nats://server3:6222"
  ]
}

TLS for Gateway Connections

Secure super-cluster connections:
gateway {
  name: "us-east"
  listen: "0.0.0.0:7222"
  
  tls {
    cert_file: "/path/to/gateway-cert.pem"
    key_file: "/path/to/gateway-key.pem"
    ca_file: "/path/to/ca.pem"
    verify: true
  }
  
  gateways: [
    {name: "us-west", urls: ["nats://uswest:7222"]}
    {name: "eu-central", urls: ["nats://eu:7222"]}
  ]
}

TLS for Leaf Nodes

Secure leaf node connections:
leafnodes {
  listen: "0.0.0.0:7422"
  
  tls {
    cert_file: "/path/to/leaf-cert.pem"
    key_file: "/path/to/leaf-key.pem"
    ca_file: "/path/to/ca.pem"
    verify: true
  }
}

TLS for HTTP Monitoring

Secure monitoring endpoints:
https_port: 8443

http {
  tls {
    cert_file: "/path/to/monitor-cert.pem"
    key_file: "/path/to/monitor-key.pem"
  }
}

OCSP Stapling

Online Certificate Status Protocol for certificate validation:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  ocsp_peer: true
}

OCSP Peer Verification

Verify client certificates via OCSP:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  ocsp_peer: true
}

Certificate Rotation

Automatic Reload

NATS Server can reload certificates without restart:
# Update certificate files
cp new-cert.pem /path/to/server-cert.pem
cp new-key.pem /path/to/server-key.pem

# Reload server configuration
nats-server --signal reload

Certificate Expiration Monitoring

NATS Server exposes certificate expiration in monitoring endpoints:
{
  "tls_cert_not_after": "2026-12-31T23:59:59Z"
}

TLS Best Practices

1. Always Use TLS in Production

tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  min_version: "1.3"
}

2. Use Strong Cipher Suites

Avoid weak ciphers:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  cipher_suites: [
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
  ]
}

3. Enable Client Certificate Verification

For maximum security:
tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  map_and_verify: true
}

4. Rotate Certificates Regularly

  • Set certificate validity to 90 days or less
  • Automate renewal (e.g., with Let’s Encrypt)
  • Monitor expiration dates

5. Separate Certificates by Component

# Client connections
tls {
  cert_file: "/certs/client-cert.pem"
  key_file: "/certs/client-key.pem"
}

# Cluster routes
cluster {
  tls {
    cert_file: "/certs/cluster-cert.pem"
    key_file: "/certs/cluster-key.pem"
  }
}

# Monitoring
http {
  tls {
    cert_file: "/certs/monitor-cert.pem"
    key_file: "/certs/monitor-key.pem"
  }
}

6. Protect Private Keys

# Set restrictive permissions
chmod 600 /path/to/server-key.pem
chown nats:nats /path/to/server-key.pem

7. Enable OCSP

tls {
  cert_file: "/path/to/server-cert.pem"
  key_file: "/path/to/server-key.pem"
  ca_file: "/path/to/ca.pem"
  verify: true
  ocsp_peer: true
}

Troubleshooting TLS

Test TLS Connection

# Test with openssl
openssl s_client -connect localhost:4222 -CAfile ca.pem

# Test with nats-cli
nats-cli pub test "hello" --tlsca=ca.pem --tlscert=client.pem --tlskey=client-key.pem

Common Errors

“x509: certificate signed by unknown authority”
  • Client doesn’t trust server’s CA
  • Solution: Provide correct CA file to client
“tls: bad certificate”
  • Server rejected client certificate
  • Solution: Ensure client cert is signed by trusted CA
“tls: handshake timeout”
  • TLS handshake taking too long
  • Solution: Increase tls.timeout value

Build docs developers (and LLMs) love