Dynamic NATS permissions with auth callout usually come down to one decision: reconnect clients so auth callout can issue a new User JWT, or use scoped signing keys and account reloads so permission templates can change without intentionally disconnecting clients.
This FAQ comes from a NATS community discussion about OAuth-backed users, project membership, and project- or device-specific subjects.
Auth callout runs when a client connects. A reconnect also triggers auth callout again. If your callout service generates a User JWT with a complete publish and subscribe permission map, those permissions apply to the connection that was just authorized. If your application database changes later, the existing connection does not automatically receive a new generated User JWT.
That gives you two main patterns:
Choose based on how often permissions change, how many unique permission templates you need, whether reconnects are acceptable, and how much decentralized JWT operational complexity you want to run.
With auth callout, the NATS server calls your authentication service when a client connects. Your service can inspect the latest external identity state, such as an OAuth userinfo response, project membership, or an application database, and return current authorization data for that new connection.
A reconnect follows the same path: the client reconnects, auth callout runs again, and your service can make a fresh authorization decision.
The important boundary is that auth callout is not a live subscription to your application authorization database. If the callout service embeds a full permissions map in the generated User JWT, changing your external database later does not automatically rewrite the effective permissions for an already-authorized connection.
Use this pattern when reconnects are acceptable and you want the simplest dynamic authorization model.
The flow is:
NATS provides a way to kick connections using a system-account server request. With the NATS CLI this is typically:
nats server request kick <client-id> <server-id>You must be connected through the system account to perform this kind of server operation. The client ID and server ID identify which connection on which server should be closed; check nats server request kick --help for the exact arguments required by your installed CLI version and deployment topology.
This pattern is often a good fit when:
Track enough metadata to find and close active connections when authorization changes. In practice, teams commonly store connection identifiers, and sometimes the server identifier as well, in state owned by the auth service.
That state lets your application find the right active connections after a project membership, resource, or subject-level authorization change.
No. Kicking a connection only closes the current connection. A normal NATS client may immediately try to reconnect.
Your auth callout service must make the authorization decision again on reconnect. If the user should no longer have access, the callout service must deny the connection or return permissions that no longer allow the removed subjects.
Use this pattern when permissions change frequently and you want to avoid intentionally reconnecting clients on each change.
In this model, auth callout still integrates with your external identity provider. The callout service validates the user, reads the relevant OAuth or application state, and issues a valid NATS User JWT. Instead of embedding a full per-connection permission map in every generated User JWT, the User JWT is signed by a scoped signing key whose permission template lives in the account configuration. When a User JWT is signed by a scoped signing key, the signing key’s permission template is applied, overriding any permissions embedded in the User JWT itself.
The useful property is that the permission template can be changed by updating the account JWT and propagating it to the server. That can allow permission changes to take effect without intentionally interrupting active clients.
Conceptually:
nsc push) so NATS picks up the new permission template.This adds more moving parts than a pure reconnect-and-kick design, but it can be a better fit for high-churn authorization where frequent disconnects would be undesirable.
Scoped signing keys are worth evaluating when:
For a small or medium deployment, such as a few hundred active users with per-user or per-project subject permissions, scoped signing keys may be reasonable to evaluate. For larger systems, be careful with designs that require a separate signing key for every user, because account JWT size becomes part of the scaling limit.
Yes. Auth callout is the mechanism that lets your service participate in authentication at connection time. Decentralized JWT auth is the model for operators, accounts, users, signing keys, and JWT-based authorization.
The callout service can create any valid NATS JWT that matches the deployment’s authentication model. That means it can use external identity information, such as an OAuth userinfo response, while still issuing NATS credentials compatible with operator-mode JWT authentication.
A practical learning path is:
nsc.synadia-io/callout.go repository.Operator mode generally provides more flexibility and a stronger operational model than putting all auth directly into static server configuration, but it also requires more setup.
For highly individualized live permission templates, one possible design is to create a scoped signing key per user. That lets each user’s permission template be updated independently.
This does not scale without limits. Signing keys are stored in the account JWT, and the account JWT should not grow much beyond a few megabytes in practice. As a rule of thumb from community guidance, this approach is more appropriate for hundreds or perhaps low thousands of users than for an unbounded population.
For very large user counts, the reconnect-and-kick pattern may be more practical unless you can group users into shared permission templates.
Yes, if your authorization model allows it. Grouping users by role, project, or resource group can reduce the number of scoped signing keys.
Shared templates make the scoped signing key model more scalable. Fully unique per-user templates provide fine-grained control, but increase account JWT size and operational complexity.
Use generated User JWT permissions plus connection kicking when:
Use scoped signing keys when:
| Requirement | Prefer reconnect-and-kick | Prefer scoped signing keys |
|---|---|---|
| Infrequent permission changes | Yes | Maybe |
| Frequent changes during active sessions | Maybe | Yes |
| Very large user population | Often | Only if templates are shared or bounded |
| Per-user unique templates | Often simpler | Possible, but watch account JWT size |
| Avoiding reconnects | No | Yes, with account reload workflow |
| Operational simplicity | Yes | No |
Start by putting a number behind frequent permission changes. The best design depends on whether permissions change once in a while, several times per user session, or continuously as users create and remove resources.
Then decide whether access is truly per user, or whether it can be represented by shared roles, project-level templates, or resource groups. Shared templates can make scoped signing keys more scalable. Fully unique per-user templates provide fine-grained control, but increase account JWT size and operational complexity.
If you choose the reconnect model, make connection tracking part of the auth service design from the beginning. Store enough metadata to kick active connections when authorization changes, and make sure reconnect authorization is based on the latest source of truth.
If you choose the scoped signing key model, test the full lifecycle:
Dynamic NATS permissions with auth callout are a tradeoff between simplicity and live authorization flexibility. Embedding full permissions in the generated User JWT is straightforward, but changes require reconnecting or kicking existing clients so auth callout can authorize them again. Combining auth callout with scoped signing keys can support reloadable permission templates, but adds decentralized JWT operational complexity and account JWT size considerations.
For frequent, fine-grained permission changes across a manageable number of users or templates, scoped signing keys are worth evaluating. For very large user populations or simpler permission lifecycles, tracking active connections and forcing reauthorization on reconnect may be the more practical design.
Want help from the NATS experts? Meet with our architects to get help tailored to your use case and environment.



News and content from across the community