Nats Jetstream
You set up nats jetstream by turning on persistence in your server and defining streams. Then you create consumer rules so apps can read and replay stored messages. Teams often start by giving one shared account to all services and developers. This makes early testing fast because any app can make or delete streams. Still, broad permissions cause big problems when you move your workloads to production. One bad command from a local tool can wipe out an entire queue. Engineers might also read raw
NATS Security: the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
You set up nats jetstream by turning on persistence in your server and defining streams. Then you create consumer rules so apps can read and replay stored messages.
Teams often start by giving one shared account to all services and developers. This makes early testing fast because any app can make or delete streams. Still, broad permissions cause big problems when you move your workloads to production. One bad command from a local tool can wipe out an entire queue. Engineers might also read raw payloads that hold private user data during a debug session.
How nats jetstream works in practice
Core messaging only sends data to apps that are listening right now. If an app goes down, it misses every message sent during that time. The persistence engine fixes this by saving messages to disk or memory first. It groups related subjects into a single unit called a stream.
When a service sends a message, the server writes it to the stream log. You can set limits on how long the stream keeps those messages. Some teams keep data for a set number of days before deleting it. Other teams drop old messages only when the disk hits a size limit.
Apps read from streams through consumers, which act as views into the stored data. A consumer tracks which messages an app has read and which ones remain. If a worker crashes, the consumer waits and resends the message later. You can also use a key-value store or an audit storage built on top. These features let apps share state or large files without an extra database.
How native account and permission controls work
The server uses accounts to split up traffic on a shared cluster. One account cannot see the streams or messages that belong to another account. Inside each account, you create users and give them specific publish or subscribe rules. You can let a service send data to one subject while blocking all others.
NATS Security: architecture patterns and best practices
Continue reading? Get the full guide.
Free. No spam. Unsubscribe anytime.
Admins manage streams by sending control messages to special system subjects on the cluster. If a user can publish to those system subjects, they can change stream settings. To lock this down, teams give most apps read and write access to data subjects only. They reserve system subject access for deployment tools and senior platform engineers.
Where native permissions fall short during live access
Native rules decide who can log in and which subjects they can touch. That works well for automated services that run the same code every day. The gap appears when a human engineer needs to check a broken production stream. To inspect a stuck consumer or fix a stream, the engineer needs system permissions.
Once an engineer logs in with an admin key, the server trusts every command. Native subject rules cannot tell a safe read command from a destructive delete call. Both actions often flow through the same set of admin control subjects. Also, when an engineer reads a live stream to debug an issue, payloads arrive intact. Those messages often hold emails, phone numbers, card numbers, or national IDs. Sharing static user keys on laptops also makes it hard to track who ran what.
Add runtime guardrails and masking beside your databases and APIs
Login rules, role grants, and CI checks govern who connects to your stack. Yet any allowed script, engineer, or AI agent still runs commands with the full scope of its role. For workloads on Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes, SSH, or internal HTTP services, hoop.dev sits beside the service as an open-source proxy, a sidecar for your database or API.
Before a query runs, hoop.dev guardrails check the statement against your rules. An AI Analyzer you configure can score intent or hold risky calls for human review. Next, hoop.dev data masking rewrites sensitive fields in responses, and each verdict is logged per listener. Explore the MIT-licensed project on GitHub.
Frequently asked questions
What is the main difference between core messaging and the persistence engine?
Core messaging sends data only to apps that are online at that exact moment. The persistence engine saves messages to storage so apps can read or replay them later.
How do consumers track message progress across a team of workers?
The server waits for each worker to send back an acknowledgment after processing a message. If the worker fails to reply in time, the consumer sends the message again.
Why is it risky to give developers full access to system subjects?
System subjects control stream settings, storage limits, and message deletion across the whole account. One wrong message to a system subject can purge production data or break active consumers.
Related guides
In this post