Skip to main content

Administer every account from one

This guide lets one ADMIN account send the admin requests of every account that the gateways serve. Without it, an operator needs a user in each account.

The gateway answers $MQGW.admin.> in each account only for that account's clients. NATS service exports and imports bring these subjects into one account. The gateway config does not change.

Before you start, you need:

  • Gateways that serve several accounts. The examples use APP1, APP2, and GW, the account of the gateway's nats user.
  • A nats-server.conf that you can edit and reload.

1. Export the admin subjects from each account​

In each account that the gateways serve, export $MQGW.admin.> as a service to ADMIN only:

accounts {
GW: {
users: [{user: gw, password: "...", permissions: $gateway_permissions}]
exports: [{service: "$MQGW.admin.>", response_type: stream, accounts: [ADMIN]}]
}
APP1: {
users: [
{user: gw1, password: "...", permissions: $APP1_gateway_permissions}
{user: dev1, password: "...", permissions: $client_permissions}
]
exports: [{service: "$MQGW.admin.>", response_type: stream, accounts: [ADMIN]}]
}
APP2: { ... the same, with its own users ... }
}
  • response_type: stream lets every gateway reply to ping. With the default type, only the first reply reaches ADMIN.
  • accounts: [ADMIN] keeps other accounts from importing the subjects.

2. Import them into ADMIN​

The subjects are the same in each account. Give each import its own prefix with to:

ADMIN: {
users: [{user: ops, password: "..."}]
imports: [
{service: {account: GW, subject: "$MQGW.admin.>"}, to: "gw.$MQGW.admin.>"}
{service: {account: APP1, subject: "$MQGW.admin.>"}, to: "app1.$MQGW.admin.>"}
{service: {account: APP2, subject: "$MQGW.admin.>"}, to: "app2.$MQGW.admin.>"}
]
}

Reload the server:

nats-server --signal reload

3. Send requests from ADMIN​

As an ADMIN user, put the account prefix in front of each subject:

nats req 'app1.$MQGW.admin.ping' '' --replies 0 --timeout 1s
nats req 'app1.$MQGW.admin.gw-1.list' ''
nats req 'app2.$MQGW.admin.gw-2.kick' '{"client_id": "dev-2"}'

To start lame duck mode, use the GW prefix:

nats req 'gw.$MQGW.admin.gw-2.ldm' ''

The gateway serves ldm only in its own account, because lame duck mode stops the clients of every account.

With operator mode​

In each account that the gateways serve, add a private service export:

nsc add export --account APP1 --service --subject '$MQGW.admin.>' \
--response-type Stream --private

Generate an activation token for ADMIN. Then import it under a prefix:

nsc generate activation --account APP1 --subject '$MQGW.admin.>' \
--target-account "$(nsc describe account ADMIN --field sub | tr -d '"')" \
-o app1-admin.tok
nsc add import --account ADMIN --token app1-admin.tok \
--local-subject 'app1.$MQGW.admin.>'

Push the account JWTs to the resolver.

Check it works​

From ADMIN, send ping with each prefix:

nats req 'app1.$MQGW.admin.ping' '' --replies 0 --timeout 1s

Each gateway that serves APP1 replies with its id. A request for ldm with the app1 prefix gets no responders.

Permissions​

  • Gateway users need no change. The allow_responses setting from generate --format nats-server lets them answer requests that come through an import.
  • Client users must not reach $MQGW.admin.>. The generated $client_permissions deny it.
  • ADMIN users can kick any client in each exported account. With the GW import, they can also stop any gateway. Give ADMIN users to operators only. Leave out the import of an account that they must not reach.