TEN-WP-0008. railiance/app.toml declares criticality=high, empty secrets, isolated canary, and the live PostgreSQL digest as previous_stable. Manifests render through kustomize (deploy/ and deploy/canary/). Stage 1 passed. Stage 2/3 Helm-only CLI gap requested as RAIL-BS-IN-0001 rather than a dummy chart. Assistant: grok Assistant-Session: 01a04cea-e5e8-7081-a0fc-808ebbc35fa9
6.9 KiB
SCOPE
Lightweight boundary for agents and contributors. Full contract:
net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md. Aspirational role:INTENT.md. Layer declaration: Engine / PIP (INTENT.mdfrontmatter;TEN-DEC-2026-001).
One-liner
Canonical PIP of tenant-as-an-entity facts for NetKingdom: existence, lifecycle, onboarding grouping, capability roles, plan/subscription assignment, and guardrail ceilings.
Core Idea
tenant-engine answers "what is this tenant, what roles does it hold, what
plan is it on, and how far may it go" for two consumers: key-cape
(cached, at token issuance) and access-engine / flex-auth (live, for
high-stakes decisions). It never stores users, issues tokens, evaluates
approvals, or makes authorization decisions. Tenancy context is an input to
the decision, not a decision.
Layer
| Key | Value |
|---|---|
| Layer | Engine |
| Role | PIP |
| Statute | net-kingdom/canon/standards/security-layer-model_v0.7.md |
| Companion | net-kingdom/SECURITY-COMPANION.md |
| Catalog row | tenant-as-an-entity facts (§4) |
| Tooling contacts | none (key-cape and OpenBao are not clients of this repo) |
| Non-Tooling clients | PostgreSQL / SQLite (own store); flex-auth POST /v1/check (Engine API on the write and authorized-read path); State Hub (work records, not a runtime dependency) |
| Write path | PEP-shaped: fail-closed when access-engine is unset or unreachable |
| Conformance today | Declaration is in our own voice. Mechanical layer.yaml check, persisted decision records, published stance map, and independent evidence custody are not yet shipped — see the review and TEN-WP-0011. |
In Scope
- Tenant records: identifier, lifecycle (
active/retired), current onboarding grouping (ADR-0013). Grouping is mutable through an audited reclassification, not by renamingtenant_id. - Capability role grants/revocations:
PLTF/IAM/VEN/CUS(ADR-0014), audited, mostly plan-linked. - Plan/subscription assignment, referenced by
adaptive-pricingplan id. - Guardrail/quota policy: spend / entity-count / action-count ceilings,
resolved as a total function of grouping, plan, override, and lifecycle.
Seeded key:
spend.monthly.trialdefaults to zero. - Cache-read API for
key-cape(token-issuance-timetenant_rolesclaim source):GET /tenants/{id}/roles. - Live-lookup API for
access-engine(high-stakes,aal2-class decisions):GET /tenants/{id}/roles/live. Store unavailability returns503, never200plus empty roles. - Write API for create / grant / revoke / plan / metadata / retire /
reactivate / grouping / guardrail mutations, authorization-gated by
flex-auth. Unset or unreachable authorizer denies. - Authoritative tenant read with ETag / If-Match / idempotency on lifecycle and guardrail mutations.
Out of Scope
- Identity, authentication, MFA, token issuance —
key-cape/Keycloak. - Authorization decisions —
access-engineis the PDP;tenant-engineis a data source it queries, never the other way around. - Approval objects and approval lifecycle —
approval-engine. Contested inTEN-DEC-2026-001; this repo will not grow one. - Users, profiles, memberships —
user-engine.tenant_idis the only key shared between the two services. - Pricing-model / plan term definitions —
adaptive-pricing. - Payment processing — not yet identified as owned by any repo.
- Runtime secret custody — OpenBao /
secrets-engine. - Metering / consumption counters — whoever meters the resource writes them; this service does not observe spend.
- Rate limiting / traffic shaping — gateway concern, not
action_count. - Containment / actuation — unowned and held at zero estate-wide.
- Irreversible operational decisions without human approval.
- Direct Tooling-layer clients — Staff and agents reach tenant facts through this Engine, not past it.
Current State
Production service, not a bootstrap. Finished workplans TEN-WP-0001
through TEN-WP-0007, TEN-WP-0009, and TEN-WP-0010 shipped the domain
model, the three boundary-contract APIs, the flex-auth write authorizer,
lifecycle, guardrails, PostgreSQL as the production store, and mutable
grouping. TEN-WP-0008 (staged-promotion onboarding) is still ready,
not done.
| Surface | Shipped | Notes |
|---|---|---|
| Domain model + SQLite/in-memory store | yes | TEN-WP-0002 |
| Cache-read / live-lookup / write APIs | yes | TEN-WP-0002 |
flex-auth WriteAuthorizer |
yes | Fail-closed; is_allowed() returns a bool and discards the decision envelope |
| Production runtime | yes | TEN-WP-0004; image pin in deploy/base/tenant-engine.yaml |
| Lifecycle (update / retire / reactivate) | yes | TEN-WP-0005; no hard-delete |
| Guardrail policy | yes | TEN-WP-0006 / 0007; docs/tenant-guardrail-policy.md |
| PostgreSQL production store | yes | TEN-WP-0009; deploy mounts TENANT_ENGINE_DATABASE_URL_FILE |
| Mutable grouping | yes | TEN-WP-0010; identifier segment stays historical |
| Staged promotion | yes (declared) | TEN-WP-0008; railiance/app.toml; live pin recorded as previous_stable. Helm CLI apply is a railiance-bootstrap gap (RAIL-BS-IN-0001). |
Machine-readable layer.yaml |
yes | TEN-WP-0011-T01; check in scripts/check_layer_conformance.py |
Persisted authorization_decision_id |
yes | authz_records plus mutation event payload (TEN-WP-0011-T02) |
| Published unreachable-engine stance map | yes | pep-stance.yaml, fail-closed, tested equal to shipped behaviour |
| Independent audit-core emission | path shipped, sender pending | Local outbox + POST /v1/events; AUDIT-IN-0002 |
| Bounded event-read interface | yes | events_for(tenant_id) only (TEN-WP-0011-T05) |
| Claim freshness / input-class lifetime | yes | pip-claims.yaml (TEN-WP-0011-T03) |
The boundary contract still labels guardrail policy "reserved, not
implemented" and still calls this repo "not a policy enforcement point".
Both sentences are stale: guardrails shipped, and the write path is
PEP-shaped even though this repo is not a PDP. Amendment is a
net-kingdom change, requested from TEN-WP-0011.
Getting Oriented
- Start with:
INTENT.md - Working companion:
net-kingdom/SECURITY-COMPANION.md - Statute:
net-kingdom/canon/standards/security-layer-model_v0.7.md - Ownership contract:
net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md - Claim/carrying mechanism:
net-kingdom/canon/standards/iam-profile_v0.3.md - Layer declaration:
decisions/decisions.mdTEN-DEC-2026-001 - Review:
history/2026-08-29-security-layer-intent-scope-review.md - Evolution workplan:
workplans/TEN-WP-0011-security-layer-conformance.md - flex-auth write-authorization integration:
docs/flex-auth-integration.md - Guardrail contract:
docs/tenant-guardrail-policy.md - Lifecycle contract:
docs/tenant-lifecycle-api.md - Agent instructions:
AGENTS.md,CLAUDE.md - Workplans:
workplans/