Separate Zapier, web, API, and leaf access planes with NATS authz
Some checks are pending
offline / test (push) Waiting to run

Zapier is one ingress. Direct web, customer API, and S2S leaf nodes are their own services. Every hop to an internal subject must pass verae.access.authz.check (default deny by plane).
This commit is contained in:
George Lambert 2026-09-11 16:05:05 -04:00
parent ac38676645
commit 1b199ca4d4
117 changed files with 2640 additions and 105 deletions

View file

@ -10,8 +10,12 @@ Verae Time proves a SHA-256 existed at a given time. Zapier lets customers regis
| Plane | What | Network |
|-------|------|---------|
| Zapier cloud | `verae-zapier-app`, `verae-activate` | HTTPS to zappier-edge |
| Commercial edge | `zappier-edge` portal, admin, `x-api-key`, Stripe meter | Public HTTPS; NATS billing pubs/requests |
| Zapier cloud | `verae-zapier-app` via **access-zapier** | HTTPS to `:3024` only (not NATS) |
| Direct web | `verae-access-web` customer browser | HTTPS `:3021` |
| Direct customer API | `verae-access-api` `x-api-key` | HTTPS `:3022` |
| S2S leaf | `verae-access-leaf` | NATS `verae.access.leaf.in` / HTTPS `:3023` |
| Authz | `verae-access-authz` | `verae.access.authz.check` before any internal subject |
| Commercial edge | `zappier-edge` portal, admin, Stripe (legacy combined) | Public HTTPS; NATS billing after authz |
| Account balance | `zappier-account-balance` prepaid SoT | NATS `verae.billing.*` + HTTP `:3010` |
| CS / sales / accounting | `zappier-customer-service`, `zappier-sales-pricing`, `zappier-accounting-export` | Private HTTP; NATS statement/adjust |
| Middleware HTTP | `/zapier/v1/*` job id + wait | Public HTTPS from edge only |

View file

@ -8,6 +8,11 @@ Each runtime piece is its **own git repo** on Forgejo (`git.georgelambert.org`,
| **verae-nats-process** | `packages/verae-nats-process` | **Template** for a new addressed NATS process |
| **master-zapier-plan-draft** | workspace root | Combined snapshot (`main` and `master`) |
| **zappier-edge** | `packages/zappier` | Metered HTTPS, portal, admin, Stripe; **proxies Verae calls to middleware** |
| **verae-access-authz** | `packages/verae-access-authz` | NATS authorization step (`authz.check`) |
| **verae-access-web** | `packages/verae-access-web` | Direct customer web plane |
| **verae-access-api** | `packages/verae-access-api` | Direct customer API plane (not Zapier) |
| **verae-access-leaf** | `packages/verae-access-leaf` | Server-to-server NATS leaf plane |
| **verae-access-zapier** | `packages/verae-access-zapier` | Zapier Platform plane only |
| **zappier-account-balance** | `packages/zappier-account-balance` | NATS source of truth for prepaid balances |
| **zappier-customer-service** | `packages/zappier-customer-service` | CS goodwill credits onto prepaid balances |
| **zappier-sales-pricing** | `packages/zappier-sales-pricing` | Sales per-customer tier / multiplier |

View file

@ -20,7 +20,7 @@ Todays NS1 box (`NS1.GEORGELAMBERT.ORG`, `70.88.205.138`) already runs JetStr
| Allowed | Forbidden |
|---------|-----------|
| verae-middleware, fleet workers, WORM, tree nodes, account-balance, zappier-edge billing, CS/sales/accounting, `verae-nats-process` clones | Zapier cloud, customer browsers (they use HTTPS portal/CS/sales UIs) |
| access-authz, access-leaf (after token), middleware, fleet workers, WORM, tree, account-balance, access planes, CS/sales | Zapier cloud, customer browsers (HTTPS to access-web / access-api / access-zapier only) |
## Address families already in use

View file

@ -5,10 +5,14 @@ NATS **addresses** (subjects) are the extension point. A new search, store, or j
## Pattern
```text
verae.<area>.<resource>.<action>
verae.access.<plane>.<area>.<resource>.<action> # ingress (one plane)
verae.access.authz.check # authorization step
verae.<area>.<resource>.<action> # internal bus
verae.<area>.<resource>.reply.<correlationId>
```
Planes: `zapier` | `web` | `api` | `leaf` | `staff`. Default deny. A leaf cannot `balance.adjust`; Zapier cannot `statement.get`; a browser cannot `archive.put`.
| Piece | Example | Meaning |
|-------|---------|---------|
| `verae` | — | Verae bus (not Zapier) |
@ -26,7 +30,7 @@ verae.<area>.<resource>.reply.<correlationId>
2. Rename `verae.example.process.in` / `.out` / `.reply.*` in `src/subjects.js`.
3. Add a row to that repos `ROUTING.md` and to [INDEX.md](INDEX.md).
4. Register the process in `verae-fleet` (`min`/`max`, machines, roles).
5. If Zapier must call it, add **one HTTPS route** on middleware — Zapier still never sees NATS.
5. If an access plane must call it, add the subject to **verae-access-authz** policy for that plane only. Zapier still never sees NATS.
Do **not** invent a public NATS URL for Zapier. Do **not** reuse `verae.archive.query` as a queue group.

View file

@ -8,23 +8,24 @@ SVG files in [`diagrams/`](diagrams/). The same shapes are repeated below in mer
```mermaid
flowchart LR
Z[Zapier cloud apps] -->|HTTPS x-api-key| E[zappier-edge]
Cust[customer portal] -->|HTTPS statement| E
CS[customer-service] -->|NATS statement/adjust| N[NATS 3-node cluster]
SA[sales-pricing] -->|NATS statement| N
AC[accounting-export] -->|NATS statement| N
E -->|NATS billing| N
BAL[account-balance] -->|reply verae.billing.*| N
E -->|HTTPS metered| M[verae-middleware]
M -->|HTTPS| C[Verae chain]
M -->|JetStream| N
Z[Zapier cloud] -->|HTTPS plane=zapier| AZ[access-zapier]
Web[customer browser] -->|HTTPS plane=web| AW[access-web]
API[customer API] -->|HTTPS plane=api| AA[access-api]
Leaf[S2S leaf] -->|verae.access.leaf.in| AL[access-leaf]
AZ --> Authz[access-authz]
AW --> Authz
AA --> Authz
AL --> Authz
CS[staff CS/sales] --> Authz
Authz -->|allow| N[NATS cluster]
BAL[account-balance] --> N
AZ -->|HTTPS| M[verae-middleware]
M --> N
N --> P[job-poller]
N --> W[webhook-deliver]
N --> A[archive-aggregator]
N --> R[WORM x N]
N --> T[tree-node x N]
P -->|HTTPS status| C
W -->|HTTPS REST Hook| Z
N --> R[WORM]
N --> T[tree-node]
P --> C[Verae chain]
M --> C
```
## 8.2 NATS.IO 3-server cluster

View file

@ -54,7 +54,7 @@ Operator console (loopback): http://127.0.0.1:3850/ · [CONSOLE.pdf](https://zap
Prefix: `https://git.georgelambert.org/marchon/`
overview · verae-nats-process · verae-ops · master-zapier-plan-draft · zappier-edge · verae-middleware · verae-zapier-app · verae-activate · verae-request-splitter · verae-archive-worm · verae-archive-aggregator · verae-tree-node · verae-fleet · verae-zapier-simulator · zapier-user-docs · zapier-docs-master
overview · verae-nats-process · verae-ops · master-zapier-plan-draft · zappier-edge · verae-access-authz · verae-access-web · verae-access-api · verae-access-leaf · verae-access-zapier · verae-middleware · verae-zapier-app · verae-activate · verae-request-splitter · verae-archive-worm · verae-archive-aggregator · verae-tree-node · verae-fleet · verae-zapier-simulator · zapier-user-docs · zapier-docs-master
## Per-module contracts