tenant-engine/SCOPE.md
tegwick 76677bffc5 Declare Engine/PIP and open TEN-WP-0011 for v0.7 conformance
The security layer model is accepted at v0.7. INTENT.md now declares
Engine / PIP in this repository's own voice (TEN-DEC-2026-001), SCOPE.md
is brought current with shipped APIs, and the intent/scope/implementation
review is history/2026-08-29-security-layer-intent-scope-review.md.

TEN-IN-0003 is absorbed by the declaration. Approvals stay with
approval-engine. TEN-IN-0001 and TEN-IN-0002 promote into TEN-WP-0011.

Assistant: grok
Assistant-Session: 01a04cea-e5e8-7081-a0fc-808ebbc35fa9
2026-08-29 11:57:37 +02:00

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.md frontmatter; 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 renaming tenant_id.
  • Capability role grants/revocations: PLTF/IAM/VEN/CUS (ADR-0014), audited, mostly plan-linked.
  • Plan/subscription assignment, referenced by adaptive-pricing plan 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. trial defaults to zero.
  • Cache-read API for key-cape (token-issuance-time tenant_roles claim source): GET /tenants/{id}/roles.
  • Live-lookup API for access-engine (high-stakes, aal2-class decisions): GET /tenants/{id}/roles/live. Store unavailability returns 503, never 200 plus 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-engine is the PDP; tenant-engine is a data source it queries, never the other way around.
  • Approval objects and approval lifecycle — approval-engine. Contested in TEN-DEC-2026-001; this repo will not grow one.
  • Users, profiles, memberships — user-engine. tenant_id is 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/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 no TEN-WP-0008
Machine-readable layer.yaml no Frontmatter declaration is in INTENT.md
Persisted authorization_decision_id no Boundary contract requires it; FlexAuthCheckClient drops the envelope
Published unreachable-engine stance map no Behaviour is fail-closed in code; companion §5 requires it published and tested equal to shipped behaviour
Independent audit-core emission no Local events table only (TEN-IN-0001)
Bounded event-read interface no In-process TenantStore.events() is unfiltered (TEN-IN-0002)
Claim freshness / input-class lifetime no Token lifetime covers the cache-read path by profile convention; live-lookup has no declared deadline

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.md TEN-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/