> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nats-io/nats-server/llms.txt
> Use this file to discover all available pages before exploring further.

# Accounts and Multi-Tenancy

> Understanding NATS account isolation, security boundaries, and JWT authentication

## Overview

Accounts provide strong multi-tenancy in NATS by creating isolated subject namespaces. Each account maintains complete isolation from other accounts unless explicitly configured to share specific streams or services.

## Multi-Tenancy with Accounts

From `server/accounts.go:50-52`, an Account represents a subject namespace definition where:

* Messages published in one account cannot be seen by other accounts
* Subscriptions exist within account boundaries
* Sharing occurs only through explicit exports and imports
* Each account has independent limits and quotas

### The Global Account

From `server/accounts.go:42-44`, for backward compatibility with NATS \< 2.0:

```go theme={null}
const globalAccountName = DEFAULT_GLOBAL_ACCOUNT
```

Users not explicitly assigned to an account are placed in the global account. In modern deployments, you should explicitly define accounts rather than relying on the global account.

### Account Structure

From `server/accounts.go:52-119`, each account maintains:

* **Sublist** (`sl`): Subscription matching tree
* **Client tracking**: Maps of connected clients
* **Statistics**: Message and byte counters for different connection types
* **Import/Export maps**: Cross-account sharing configuration
* **JetStream context**: Optional per-account JetStream resources
* **Limits**: Connection, subscription, and payload limits
* **Permissions**: Default permissions for account users

## Account Isolation and Security Boundaries

### Subject Space Isolation

Each account has its own subject space:

```
Account A:                    Account B:
  orders.created               orders.created
  users.login                  users.login  
  inventory.update             inventory.update
```

These are completely separate - a message published to `orders.created` in Account A will never reach subscribers in Account B (unless explicitly exported/imported).

### Resource Isolation

From `server/accounts.go:53-60`, accounts track separate statistics:

```go theme={null}
stats struct {
    sync.Mutex
    stats       // Totals
    gw    stats // Gateways
    rt    stats // Routes  
    ln    stats // Leafnodes
}
```

Each account tracks:

* Messages in/out
* Bytes in/out
* Slow consumers
* Per-connection-type breakdowns

### Connection Isolation

Clients connect to specific accounts:

* User credentials determine account assignment
* Each client belongs to exactly one account
* Client can only publish/subscribe within their account
* Cross-account access only via explicit imports/exports

## System Account

The system account is a special privileged account used for monitoring and management.

### System Account Role

From `server/server.go:192`, the server maintains a reference to the system account:

```go theme={null}
sys                 *internal
sysAcc              atomic.Pointer[Account]
```

The system account:

* Receives server events and metrics
* Provides monitoring endpoints
* Handles server-to-server communication
* Cannot be used for regular application messaging

### System Account Configuration

```hcl theme={null}
accounts {
  SYS: {
    users: [
      {user: "admin", password: "admin_pass"}
    ]
  }
  APP: {
    users: [
      {user: "app", password: "app_pass"}
    ]
  }
}

system_account: "SYS"
```

<Warning>
  Never use the system account for application traffic. It has special privileges and bypass certain limits.
</Warning>

### System Account Events

The system account receives:

* Connection events: `$SYS.ACCOUNT.*.CONNECT`
* Disconnect events: `$SYS.ACCOUNT.*.DISCONNECT`
* Server stats: `$SYS.SERVER.*.STATSZ`
* JetStream advisories: `$JS.EVENT.ADVISORY.>`

Subscribe to these subjects in the system account for monitoring.

## JWT-Based Authentication

NATS supports decentralized authentication using JSON Web Tokens (JWTs).

### JWT Architecture

From `server/accounts.go:36` and `server/auth.go:33`:

```go theme={null}
import (
    "github.com/nats-io/jwt/v2"
    "github.com/nats-io/nkeys"
)
```

JWT authentication uses:

* **Operator JWT**: Root of trust, signs accounts
* **Account JWT**: Defines account properties and limits
* **User JWT**: Credentials for individual users
* **NKeys**: Ed25519 key pairs for signing and verification

### JWT Components

From `server/accounts.go:64-66`:

```go theme={null}
Nkey         string
Issuer       string  
claimJWT     string
```

Each account stores:

* **Nkey**: Account's public key
* **Issuer**: Operator's public key that signed this account
* **claimJWT**: The full JWT claim

### Signing Keys

From `server/accounts.go:98-99`:

```go theme={null}
signingKeys  map[string]jwt.Scope
extAuth      *jwt.ExternalAuthorization
```

Accounts support:

* **Multiple signing keys**: Rotate keys without downtime
* **Scoped keys**: Limit what each signing key can authorize
* **External authorization**: Delegate authentication to external services

### JWT Configuration

Enable JWT mode:

```hcl theme={null}
operator: "/path/to/operator.jwt"
resolver: {
  type: "full"
  dir: "/path/to/jwt/storage"
}
```

Or use URL resolver:

```hcl theme={null}
operator: "/path/to/operator.jwt"  
resolver: "URL(http://jwt-resolver.example.com:8080/jwt/v1/accounts/)" 
```

### User Credentials

Users authenticate with credential files:

```
-----BEGIN NATS USER JWT-----
eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5...
------END NATS USER JWT------

************************* IMPORTANT *************************
NKEY Seed printed below can be used to sign and prove identity.
    NKEYs are sensitive and should be treated as secrets.

-----BEGIN USER NKEY SEED-----
SUACCSSUZZMCJWVYW3OEQZ6NNFMWP...
------END USER NKEY SEED------
```

Clients load credentials:

```go theme={null}
nc, err := nats.Connect("nats://localhost:4222",
    nats.UserCredentials("/path/to/user.creds"))
```

## Account Limits and Quotas

From `server/accounts.go:126-133`, accounts support limits:

```go theme={null}
type limits struct {
    mpay           int32  // Max payload size
    msubs          int32  // Max subscriptions
    mconns         int32  // Max connections  
    mleafs         int32  // Max leaf node connections
    disallowBearer bool   // Disallow bearer tokens
}
```

### Connection Limits

Limit the number of connections per account:

```hcl theme={null}
accounts {
  APP: {
    users: [{user: "app", password: "pass"}]
    limits: {
      max_connections: 1000
      max_leafnodes: 10
    }
  }
}
```

From `server/accounts.go:77-80`, the server tracks:

```go theme={null}
nrclients    int32  // Number of remote clients
sysclients   int32  // Number of system clients  
nleafs       int32  // Number of leaf nodes
nrleafs      int32  // Number of remote leaf nodes
```

### Subscription Limits

Limit subscriptions per account:

```hcl theme={null}
accounts {
  APP: {
    users: [{user: "app", password: "pass"}]
    limits: {
      max_subscriptions: 10000
    }
  }
}
```

Exceeding limits results in client errors.

### Payload Size Limits

Limit maximum message size:

```hcl theme={null}
accounts {
  APP: {
    users: [{user: "app", password: "pass"}]
    limits: {
      max_payload: 1048576  # 1MB
    }
  }
}
```

From `server/server.go:123`, the server advertises max payload:

```go theme={null}
MaxPayload        int32    `json:"max_payload"`
```

### JetStream Limits

From `server/accounts.go:93`:

```go theme={null}
jsLimits     map[string]JetStreamAccountLimits
```

JetStream limits per account:

```hcl theme={null}
accounts {
  APP: {
    jetstream: {
      max_memory: 1073741824      # 1GB
      max_file: 10737418240       # 10GB  
      max_streams: 100
      max_consumers: 1000
    }
  }
}
```

## Exports and Imports

Accounts can selectively share streams or services.

### Stream Exports

From `server/accounts.go:142-150`, stream imports:

```go theme={null}
type streamImport struct {
    acc     *Account
    from    string           // Remote subject
    to      string           // Local subject
    tr      *subjectTransform
    claim   *jwt.Import
    usePub  bool
    invalid bool
}
```

Export a stream:

```hcl theme={null}
accounts {
  ORDERS: {
    exports: [
      {stream: "orders.>"}
    ]
  }
  
  FULFILLMENT: {
    imports: [
      {stream: {account: "ORDERS", subject: "orders.>"}, prefix: "external.orders"}
    ]
  }
}
```

Messages published to `orders.shipped` in ORDERS appear as `external.orders.shipped` in FULFILLMENT.

### Service Exports

Export request-reply services:

```hcl theme={null}
accounts {
  AUTH: {
    exports: [
      {service: "auth.validate"}
    ]
  }
  
  APP: {
    imports: [
      {service: {account: "AUTH", subject: "auth.validate"}}
    ]
  }
}
```

APP can send requests to `auth.validate` which are handled by AUTH account services.

### Subject Transforms

From `server/accounts.go:146-147`, imports support transformations:

```go theme={null}
tr      *subjectTransform
rtr     *subjectTransform  // Reverse transform
```

Transform subjects during import:

```hcl theme={null}
imports: [
  {
    stream: {account: "SOURCE", subject: "old.>"}
    to: "new.>"  # Maps old.foo -> new.foo
  }
]
```

## Account Management

### Static Configuration

Define accounts in configuration file:

```hcl theme={null}
accounts {
  ACCOUNT_A: {
    users: [
      {user: "user_a", password: "pass_a"}
    ]
  }
  ACCOUNT_B: {
    users: [
      {user: "user_b", password: "pass_b"}  
    ]
  }
}
```

### JWT-Based Management

Use JWT resolver for dynamic account management:

1. Create operator and signing key
2. Issue account JWTs signed by operator
3. Issue user JWTs signed by account
4. Configure server with operator JWT and resolver
5. Server fetches account JWTs from resolver as needed

This enables:

* Adding accounts without server restart
* Updating account limits dynamically
* Revoking user credentials
* Account delegation

### Account Revocation

From `server/accounts.go:84`:

```go theme={null}
usersRevoked map[string]int64
```

Revoke user credentials:

```bash theme={null}
nsc revocations add_user --account ACCOUNT --user-public-key NKEY
```

Revoked users are immediately disconnected.

### Account Updates

From `server/accounts.go:67`:

```go theme={null}
updated      time.Time
```

With JWT resolver:

* Server periodically checks for account updates
* Updated JWTs apply to new connections immediately
* Existing connections use permissions from connection time
* Can force disconnect for immediate updates

## Account Best Practices

### Account Design

1. **One account per tenant**: Isolate customers completely
2. **System account separation**: Never mix application and monitoring
3. **Service accounts**: Dedicated accounts for shared services
4. **Environment separation**: Separate dev/staging/prod accounts

### Security

1. **Use JWT authentication**: Centralized, revocable credentials
2. **Set appropriate limits**: Prevent resource exhaustion
3. **Minimal exports**: Only share what's necessary
4. **Audit imports**: Know what external data you consume
5. **Rotate signing keys**: Regular key rotation for security

### Performance

1. **Account-level optimization**: Some routes can be account-dedicated
2. **Limit account count**: Many accounts increase overhead
3. **Monitor account metrics**: Track per-account resource usage
4. **Subject planning**: Design subjects for efficient routing

### Operations

1. **Use JWT resolver**: Enable dynamic account management
2. **Monitor system account**: Subscribe to server events
3. **Set up alerts**: Track limit violations
4. **Document exports**: Maintain export/import relationships
5. **Test failover**: Verify account isolation during failures

## Monitoring Accounts

### Account Statistics

From server monitoring endpoints:

* `/accountz`: List all accounts and basic stats
* `/connz?acc=ACCOUNT`: Connections for specific account
* `/subsz?acc=ACCOUNT`: Subscriptions for specific account

### System Account Monitoring

Subscribe in system account:

```go theme={null}
// Connection tracking
nc.Subscribe("$SYS.ACCOUNT.*.CONNECT", func(m *nats.Msg) {
    // Log connections
})

// Account statistics  
nc.Subscribe("$SYS.REQ.ACCOUNT.*.STATSZ", func(m *nats.Msg) {
    // Process account stats
})
```

### JetStream Account Monitoring

For accounts with JetStream:

```go theme={null}
// Stream events
nc.Subscribe("$JS.EVENT.ADVISORY.STREAM.*", func(m *nats.Msg) {
    // Track stream operations
})

// Consumer events  
nc.Subscribe("$JS.EVENT.ADVISORY.CONSUMER.*", func(m *nats.Msg) {
    // Track consumer operations
})
```

## Advanced Account Features

### Account Trace Sampling

From `server/accounts.go:113-115`:

```go theme={null}
traceDest         string
traceDestSampling int
```

Configure message tracing per account:

* Route trace messages to specific destination
* Sample percentage of traced messages
* Useful for debugging message flow

### Account Tags

From `server/accounts.go:106-107`:

```go theme={null}
tags         jwt.TagList
nameTag      string
```

Tag accounts for organization and filtering:

```json theme={null}
{
  "tags": ["production", "tier-1", "region-us-west"]
}
```

### External Authorization

From `server/accounts.go:99`:

```go theme={null}
extAuth      *jwt.ExternalAuthorization
```

Delegate authorization decisions to external services:

* Server calls external service for auth decisions
* Enables integration with existing auth systems
* Supports custom authorization logic
* Can use for publish/subscribe permission checks

## Next Steps

<CardGroup cols={2}>
  <Card title="Architecture Overview" icon="diagram-project" href="/architecture/overview">
    Review overall NATS architecture
  </Card>

  <Card title="Clustering" icon="network-wired" href="/architecture/clustering">
    Deploy accounts across clusters
  </Card>

  <Card title="Gateways" icon="globe" href="/architecture/gateways">
    Share accounts across regions with gateways
  </Card>
</CardGroup>
