The platform team owns nats-system: the NATS operator, the system account, every account and its limits. The payments team owns the payments namespace and wants to declare its own users and streams there, without reading anything in nats-system.
What the platform team declares #
The account, and a grant that lets users in payments attach to it. The grant sits in the namespace it opens up, so only someone who can write there can open it. It trusts payments with every user key of the account: a NatsUser there can claim any key the account’s users hold, those issued outside the auth controller included, and deleting it revokes that key. Accounts stay in nats-system alone: whichever NatsAccount records an account key first holds it, so a namespace granted NatsAccounts to the NatsOperator could take any account key no NatsAccount records yet.
01-platform.yaml
# Owned by the platform team, in nats-system: the account and its limits.
apiVersion: auth.nats.mikluko.io/v1beta1
kind: NatsAccount
metadata:
name: payments
namespace: nats-system
spec:
operatorRef:
name: demo
limits:
connections: 200
jetstream:
memoryStorage: 512Mi
diskStorage: 100Gi
streams: 10
consumers: 100
---
# The platform team's consent: NatsUsers in the payments namespace may
# reference the payments account here, and nothing else in nats-system.
apiVersion: nats.mikluko.io/v1beta1
kind: NatsReferenceGrant
metadata:
name: payments-users
namespace: nats-system
spec:
from:
- group: auth.nats.mikluko.io
kind: NatsUser
namespace: payments
to:
- group: auth.nats.mikluko.io
kind: NatsAccount
name: payments # omitted: every NatsAccount in nats-system
kubectl apply -f https://nats-operator.io/docs/stories/04-team-self-service/01-platform.yamlWhat the payments team declares #
Users that reference the account across namespaces, and everything JetStream in its own namespace. Creds Secrets land beside the users.
01-team.yaml
# Owned by the payments team, in its own namespace. The team never reads
# nats-system: its creds Secret lands here.
apiVersion: auth.nats.mikluko.io/v1beta1
kind: NatsUser
metadata:
name: payments-api
namespace: payments
spec:
accountRef:
kind: NatsAccount
namespace: nats-system # admitted by the payments-users grant
name: payments
permissions:
publish:
allow: ["payments.>", "$JS.API.>"]
subscribe:
allow: ["payments.>", "_INBOX.>"]
credentials:
secretKeyRef:
name: payments-api-creds
---
# The user the JetStream controller acts as in this account.
apiVersion: auth.nats.mikluko.io/v1beta1
kind: NatsUser
metadata:
name: payments-jetstream
namespace: payments
spec:
accountRef:
kind: NatsAccount
namespace: nats-system
name: payments
permissions:
publish:
allow: ["$JS.API.>"]
subscribe:
allow: ["_INBOX.>"]
credentials:
secretKeyRef:
name: payments-jetstream-creds
---
# Everything JetStream stays in the team's namespace: no grant needed.
apiVersion: nats.mikluko.io/v1beta1
kind: NatsConnection
metadata:
name: demo
namespace: payments
spec:
servers: ["nats://demo.nats-system.svc:4222"]
credentials:
secretKeyRef:
name: payments-jetstream-creds
---
apiVersion: jetstream.nats.mikluko.io/v1beta1
kind: NatsStream
metadata:
name: payments
namespace: payments
spec:
connectionRef:
name: demo
name: PAYMENTS
subjects: ["payments.>"]
storage: File
replicas: 3
maxAge: 720h
kubectl apply -f https://nats-operator.io/docs/stories/04-team-self-service/01-team.yamlWithout a grant #
A user from a namespace no grant covers is refused, and deleting a grant later revokes the users it had admitted and deletes the creds Secrets they own.
01-natsuser-payments-reader.yaml
# Declared in the orders namespace, which no grant covers, against the
# payments account.
apiVersion: auth.nats.mikluko.io/v1beta1
kind: NatsUser
metadata:
name: payments-reader
namespace: orders
spec:
accountRef:
kind: NatsAccount
namespace: nats-system
name: payments
preset: readonly
credentials:
secretKeyRef:
name: payments-reader-creds
kubectl apply -f https://nats-operator.io/docs/stories/04-team-self-service/01-natsuser-payments-reader.yaml01-status-natsuser-payments-reader.yaml
# payments-reader, with no grant covering it.
status:
observedGeneration: 1
conditions:
- type: Ready
status: "False"
reason: ReferenceNotPermitted
- type: ReferencesResolved
status: "False"
reason: NoGrant
message: >-
no NatsReferenceGrant in nats-system admits NatsUser from namespace
orders to NatsAccount payments