tenant-engine/INTENT.md
tegwick 9370348d54 Bootstrap repo: State Hub registration, agent docs, TEN-WP-0001/0002
statehub register + repo-seed template scaffold (CLAUDE.md, .claude/rules/,
registry/). INTENT.md and SCOPE.md rewritten from the generated stub to
match net-kingdom's ratified tenant-engine-boundary-contract_v0.1.md
(Purpose, Responsibility Boundary, Non-Goals). topic_slug corrected from
the auto-assigned custodian default to netkingdom, matching key-cape and
user-engine.

TEN-WP-0001 (bootstrap) complete: files reviewed/refined, stack decided
(Python 3.12 + FastAPI, matching qonto-assistant's convention), first real
workplan seeded.

TEN-WP-0002 drafted: service skeleton, domain model (tenant/grouping/
capability-role/plan-grant), storage layer, and the three boundary-contract
API surfaces (cache-read for key-cape, live-lookup for flex-auth with an
explicit fail-closed requirement, write API behind a WriteAuthorizer seam
since real flex-auth integration is a declared non-goal for this pass).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 21:56:07 +02:00

131 lines
6.1 KiB
Markdown

---
repo: tenant-engine
updated: "2026-07-23"
---
# INTENT
## Purpose
`tenant-engine` exists to be the single, canonical source of truth for what a
**tenant** is on the NetKingdom platform — its existence, its onboarding
grouping, its capability roles, and its plan/subscription assignment —
separate from who its *users* are (`user-engine`), who *authenticates* it
(`key-cape`/Keycloak), who *authorizes* actions against it (`flex-auth`), and
what it *pays* for a given plan (`adaptive-pricing`).
Full ownership boundary, formally: `net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md`.
## Why This Exists
No service in the fleet currently owns tenant-as-an-entity facts as a
queryable resource. `user-engine`'s own boundary contract explicitly scopes
it to *consuming* tenant identifiers and *storing records scoped by* a
tenant — not owning the tenant record itself. The IAM Profile defines the
*shape* of the `tenant` claim, not a live directory of which tenants exist,
what they're allowed to do, or what plan they're on.
That gap became concrete during Binky Hedgehog GmbH's onboarding as the
platform's first tenant outside `tenant:coulomb`
(`key-cape/workplans/KEY-WP-0004-binky-hedgehog-tenant-onboarding.md`): a
tenant's **capability roles** (`PLTF`/`IAM`/`VEN`/`CUS`, non-exclusive — a
tenant can hold several at once, and its roles can change independently of
how it was onboarded) needed a real owner, a real carrying mechanism, and a
real governance model (role grants are usually a consequence of a paid
plan). See `net-kingdom/docs/adr/ADR-0013-tenant-onboarding-grouping-taxonomy.md`
and `ADR-0014-tenant-capability-roles-and-tenant-engine-ownership.md`.
## Primary Utility
`tenant-engine` provides:
- **Tenant records**: existence, identifier, and onboarding grouping
(`trial`/`friendly`/`single`/`small`/`medium`/`large`/`enterprise`/
`consumer`/`family`/`community`/`association`/`agentic`, per ADR-0013).
- **Capability role grants**: `PLTF`/`IAM`/`VEN`/`CUS`, with an audited
grant/revoke trail linking most grants to a plan-assignment change.
- **Plan/subscription assignment**: which `adaptive-pricing` plan a tenant
currently holds, referenced by id — never a duplicated copy of plan terms.
- **A cache-read API** `key-cape` calls at token-issuance time to source the
optional `tenant_roles` token claim (IAM Profile v0.3).
- **A live-lookup API** `flex-auth` calls synchronously for privileged,
high-stakes decisions — the case where a cached claim isn't trustworthy
enough (a stale `VEN` grant surviving a plan cancellation is not an
acceptable risk for money-movement or credential-vending actions).
- Reserved, not yet implemented: **guardrail/quota policy** (spend limits,
entity/action counts) — `trial`-grouped tenants default to a **zero**
spend budget; design is future work.
## Intended Users
- `key-cape` / Keycloak, at token issuance time (cache-read API).
- `flex-auth`, at authorization-decision time (live-lookup API, and the
target of write-authorization for grant/revoke/plan mutations).
- Operators and tenant administrators, indirectly, through whatever admin
surface eventually consumes `tenant-engine`'s APIs (not yet built).
- `adaptive-pricing`, as the source `tenant-engine` references for plan
*definitions* (not the other way around).
## Strategic Role
`tenant-engine` sits **beside** `user-engine`, not inside it — a deliberate
bounded-context split, not an oversight. `user-engine`'s aggregate root is
the *person*; `tenant-engine`'s is the *tenant*. Consumers that only need a
fast, security-critical tenant-role lookup (`flex-auth` on every privileged
decision, `key-cape` on every token issuance) should never need to depend on
`user-engine`'s much larger surface (registration flows, factor models,
family dataspace onboarding) to get it. This matches the fleet's existing
convention of many small, single-purpose `-engine`/`-core` services rather
than one large one.
## Responsibility Boundary
`tenant-engine` owns tenant-as-an-entity facts. It never re-derives or
duplicates facts another system already owns.
### tenant-engine Owns
- Tenant existence, identifier, and onboarding grouping.
- Capability role grants and their audit trail.
- Plan/subscription assignment (by reference, not by copying plan terms).
- Reserved: guardrail/quota policy, once designed.
### Other Systems Own
| Concern | Owner |
| --- | --- |
| OIDC discovery, login, token issuance | `key-cape`, Keycloak |
| Tenant identifier format and role vocabulary | NetKingdom (IAM Profile, ADR-0013, ADR-0014) |
| Users, profiles, memberships | `user-engine` |
| Authorization decisions | `flex-auth` |
| Pricing-model / plan definitions | `adaptive-pricing` |
| Runtime secrets | OpenBao / `secrets-engine` |
| Payment processing | Not yet identified — `tenant-engine` records plan assignment, not payment execution |
## Non-Goals
- Not an identity provider. Never issues, verifies, or refreshes tokens.
- Not a policy decision point. Never makes an authorization decision itself
— it answers queries `flex-auth` issues.
- Not a billing processor. Records plan assignment, not payment execution.
- Not a pricing-model engine. References `adaptive-pricing` plan ids.
- Not the user/membership domain. Never stores user accounts or profiles.
## Governing Principle
This repository should stay focused on the purpose above. Work that changes
its authority, ownership boundaries, or operational promises should be
captured in a workplan before implementation, and should stay consistent
with `net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md`
if the two drift, the canon contract wins and this file should be corrected.
## Related
- `net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md` — the
formal ownership contract
- `net-kingdom/canon/standards/iam-profile_v0.3.md` — the `tenant_roles`
claim and carrying mechanism this service implements
- `net-kingdom/docs/adr/ADR-0013-tenant-onboarding-grouping-taxonomy.md`
- `net-kingdom/docs/adr/ADR-0014-tenant-capability-roles-and-tenant-engine-ownership.md`
- `key-cape/workplans/KEY-WP-0004-binky-hedgehog-tenant-onboarding.md` — the
first tenant this service will record