# verae-access-authz Authorization step on the NATS **address path**. Zapier is only **one** access plane. Direct web, customer API, and server-to-server leaf nodes are separate, and each is default-deny against internal subjects. **Forgejo:** https://git.georgelambert.org/marchon/verae-access-authz **Catalog:** https://zapier.georgelambert.org/packages/verae-access-authz/README.pdf ## Address path ```text client → verae.access.... (ingress, that plane only) → verae.access.authz.check (allow / deny) → verae... (internal bus) ``` Internal subjects (`verae.billing.*`, `verae.archive.*`, `verae.zapier.jobs.*`) stay stable. Planes never publish them until `authz.check` returns `allow`. | Plane | Who | May reach | |-------|-----|-----------| | `zapier` | Zapier Platform HTTPS | jobs.*, webhooks.deliver, billing.usage.recorded | | `web` | Customer browser portal | statement.get, balance.adjust kind=reload\|payment | | `api` | Customer `x-api-key` (not Zapier) | statement.get, usage.recorded, jobs.watch | | `leaf` | S2S NATS leaf / mTLS | archive.*, jobs.*, webhooks — **not billing** | | `staff` | CS / sales / admin | statement, balance.adjust (credits) | A leaf node cannot credit an account. A Zapier hop cannot read a customer statement. A browser cannot `archive.put`. ```bash NATS_URL=nats://127.0.0.1:4222 PORT=3020 npm start curl -s http://127.0.0.1:3020/policy curl -s -X POST http://127.0.0.1:3020/check -H 'content-type: application/json' \ -d '{"plane":"leaf","subject":"verae.billing.balance.adjust"}' ```