Synadia Protect

Inspecting the gateway

This section assumes you have a running gateway from the setup and have completed running the gateway.

Setting up admin access

The protect admin commands connect to the gateway's management API. Create a NATS context pointing to the management port using the admin NKey:

$ nats context add --server 127.0.0.1:4911 --nkey my_gateway/admin.nk admin

Gateway info

$ protect admin --context admin info
Gateway Information

             Name: my_gateway
          Version: dev
             Time: 2026-04-02 14:29:59
           Uptime: 49m6s
      Connections: 0

Ports:

   clients:

     Connection Kind: client
                Name: clients
                Port: 4222
             Backend: nats://demo.nats.io:4222
Rules

 No rules loaded

This shows the gateway name, version, uptime, connection count, configured ports with their backends, and loaded rules.

Generating traffic

To generate traffic the gateway must allow connections. By default the gateway denies all traffic when no rules match — attempting to subscribe fails:

$ nats sub --context local "hello.gateway"
nats: error: nats: Authorization Violation denied by policy: rPh38lyrczfO9fiIr4rkZj

The local context points to the gateway at 127.0.0.1:4222. Create it with:

$ nats context add --server 127.0.0.1:4222 local

To temporarily allow traffic, edit my_gateway/config.yaml and change unmatched_rule_to_backend_action and unmatched_rule_from_backend_action from deny to allow:

rules:
  default_rule_direction: to_backend
  unmatched_rule_to_backend_action: allow # was deny
  unmatched_rule_from_backend_action: allow # was deny

Restart the gateway for the change to take effect:

$ protect start --config my_gateway/config.yaml

Now open a subscriber through the gateway:

$ nats sub --context local "hello.gateway"

Connection stats via CLI

With the subscriber connected, protect admin stats shows active connections:

$ protect admin --context admin stats
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                      Gateway Statistics for my_gateway                                                                     │
├─────┬─────────────────────┬───────────┬────────┬─────────────────┬────────────┬─────────────────┬─────────┬──────────┬──────────┬───────────┬─────────┬────────┬───────────┤
│ CID │ Connected           │ Port Name │   Kind │ Remote Server   │ Remote CID │ Address         │ Msgs In │ Msgs Out │ Bytes In │ Bytes Out │ Account │ System │ Suspended │
├─────┼─────────────────────┼───────────┼────────┼─────────────────┼────────────┼─────────────────┼─────────┼──────────┼──────────┼───────────┼─────────┼────────┼───────────┤
│   3 │ 2026-04-09 21:52:19 │ clients   │ client │ 127.0.0.1:56949 │          9 │ 127.0.0.1:56948 │       0 │        0 │        0 │         0 │ $G      │ false  │ false     │
╰─────┴─────────────────────┴───────────┴────────┴─────────────────┴────────────┴─────────────────┴─────────┴──────────┴──────────┴───────────┴─────────┴────────┴───────────╯

Each row shows the connection ID, port, kind, backend server, message and byte counters, account, and suspension status.

Now publish some messages from another terminal:

$ nats pub --context local hello.gateway "testing" --count 100

Running stats again shows traffic:

$ protect admin --context admin stats
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                      Gateway Statistics for my_gateway                                                                     │
├─────┬─────────────────────┬───────────┬────────┬─────────────────┬────────────┬─────────────────┬─────────┬──────────┬──────────┬───────────┬─────────┬────────┬───────────┤
│ CID │ Connected           │ Port Name │   Kind │ Remote Server   │ Remote CID │ Address         │ Msgs In │ Msgs Out │ Bytes In │ Bytes Out │ Account │ System │ Suspended │
├─────┼─────────────────────┼───────────┼────────┼─────────────────┼────────────┼─────────────────┼─────────┼──────────┼──────────┼───────────┼─────────┼────────┼───────────┤
│   3 │ 2026-04-09 21:52:19 │ clients   │ client │ 127.0.0.1:56949 │          9 │ 127.0.0.1:56948 │     100 │        0 │     3200 │         0 │ $G      │ false  │ false     │
╰─────┴─────────────────────┴───────────┴────────┴─────────────────┴────────────┴─────────────────┴─────────┴──────────┴──────────┴───────────┴─────────┴────────┴───────────╯

The connection (CID 3) shows 100 messages in with 3200 bytes.

The stats table is wide. Scroll horizontally to see all columns including Bytes Out, Account, System, and Suspended.

Before continuing, restore unmatched_rule_to_backend_action and unmatched_rule_from_backend_action to deny in my_gateway/config.yaml and restart the gateway. With allow, the gateway permits all traffic unless a rule explicitly denies it.

rules:
  default_rule_direction: to_backend
  unmatched_rule_to_backend_action: deny
  unmatched_rule_from_backend_action: deny
Previous
Running