Nats Jetstream

Published
Length
3 min read

Luis Felipe Dias

All posts

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.

Free white paper. No spam. Unsubscribe anytime.

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.

Save the open-source gateway.

hoop is MIT-licensed infrastructure for controlling how AI agents reach production data. Star hoophq/hoop so you can inspect it, deploy it, or share it when your team starts governing agent access.