This episode covers NATS authentication from user and password, tokens, nkeys, up to JWT, then TLS for connection encryption and per-user authorization, closing with security best practices in production.

Episode 12 built the multi-tenant structure. Episode 13 locks the doors: security. All messaging features are meaningless if anyone can connect, listen to every subject, or send messages on behalf of another service.
We'll climb NATS's authentication ladder from the simplest to the most secure — user and password, tokens, nkeys, JWT — then TLS for encryption and authorization for access control. This is required gear before going to production.
The simplest way to define credentials is the authorization block in the configuration file:
authorization {
users = [
{ user: admin, password: "sup3r-rahasia" }
{ user: worker, password: "rahasia-kerja" }
]
}The authorization block above defines two users with their own passwords. Clients connect by sending the user and password in the connection URL. This method is easy but stores passwords in a file — only suitable for development.
The next level is the token: a single shared credential for all clients. Suitable for simple environments or internal services:
authorization {
token: "s3cr3t-token-bersama"
}The token: "s3cr3t-token-bersama" configuration uses a single token. Every client that knows the token can connect. Simple, but revoking the token means replacing it for all clients at once.
NKeys are public-private key pairs for passwordless identity. The seed key (private) is kept secret, while the public key is used by the server for verification.
nsc add user --account ORDERS --name worker-nkeyUsers created via nsc add user automatically get an nkey. When a client connects, the server sends a random challenge, the client signs it with the seed key, and the server verifies with the public key. No password ever crosses the network.
JWT is a token that carries a user's identity and permissions within it:
nsc generate creds --account ORDERS --user api-worker -o api-worker.credsnsc generate creds produces a .creds file containing the JWT and seed key. Clients use this file to connect:
nats sub orders.> --creds api-worker.credsThe --creds api-worker.creds flag makes the CLI automatically use the JWT for authentication. JWT's advantage: new users can be created and revoked without restarting the server, and each user only carries its own permissions.
Authentication is only half of security. TLS encrypts all traffic so it can't be intercepted:
tls {
cert_file: "/etc/nats/certs/server-cert.pem"
key_file: "/etc/nats/certs/server-key.pem"
ca_file: "/etc/nats/certs/ca.pem"
verify: true
}The tls block enables TLS with a server certificate. verify: true also requires the client to present a certificate — mutual TLS. Client connections must then use tls://:
nats sub orders.> --server tls://nats.internal:4222 --tlsThe tls://nats.internal:4222 URL points clients to an encrypted connection. In production, combine TLS with JWT or nkeys for authentication and encryption at the same time.
Warning
Never run production NATS without TLS on a network that isn't fully trusted. Authentication proves who you are, but only TLS ensures data can't be read in transit.
Production best practices combine all the layers:
authentication -> JWT or nkeys (who you are)
authorization -> per-user permissions (what you may do)
encryption -> mutual TLS (can't be intercepted)
isolation -> accounts and export-import (tenant boundaries)The encryption -> mutual TLS pattern closes the last gap: even after authentication, data remains unreadable to third parties. Combine it with routine credential rotation and audit logs for a mature security posture.
Episode 13 secured your NATS: starting from user and password and tokens for simple environments, nkeys for cryptographic identity, JWT for decentralized credentials that can be revoked anytime, TLS for connection encryption, up to the combination of authorization and account isolation in production.
Key takeaways:
verify: true enables mutual TLS.In episode 14 next, we'll discuss clustering & leaf nodes — building multi-server clusters with Raft consensus for JetStream, gateways between clusters, tolerance to node loss, then connecting edge servers to a hub via leaf nodes for IoT scenarios and multi-region federation. Your NATS scale starts spreading across multiple machines.