# tenant-engine — PIP claim freshness contract # # Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md §9.3, §9.7 # Companion: net-kingdom/SECURITY-COMPANION.md v0.2 # Named from: layer.yaml (pip_claims) # Validate: tests/test_pip_claims.py # # access-engine states a deadline per input class. This file is the input # class description it is owed for tenant facts. schema_version: "0.1" framework: netkingdom-security-layer-model standard_version: "0.7" repository: tenant-engine role: pip input_classes: tenant_roles_cached: surface: "GET /tenants/{id}/roles" consumer: key-cape carrying: "IAM Profile v0.3 optional tenant_roles token claim" lifetime: "the issuing token's lifetime; this engine does not push-invalidate" cross_request_cache_by_this_engine: false notes: >- The token claim is a point-in-time copy. Privileged decisions MUST not trust it; they use tenant_roles_live. tenant_roles_live: surface: "GET /tenants/{id}/roles/live" consumer: access-engine carrying: "current active capability roles" lifetime: "this response only" cross_request_cache_by_consumer: false request_scoped_memoization: true notes: >- Boundary contract: request-scoped memoization inside one decision is allowed. Cross-request caching of live-lookup results is not — that would recreate the staleness the live path exists to avoid (§6.1). tenant_record: surface: "GET /tenants/{id}" consumer: user-engine operator UI and other admin surfaces carrying: "existence, grouping, lifecycle, metadata, version ETag" lifetime: "until the ETag changes" cross_request_cache_by_this_engine: false tenant_guardrails: surface: "GET /tenants/{id}/guardrails" consumer: access-engine carrying: "effective ceilings per registered limit key" lifetime: "this response only" cross_request_cache_by_consumer: false request_scoped_memoization: true notes: >- A ceiling is a claim, never an allow. Unavailability must not be read as "no limits". degradation: store_unavailable: http_status: 503 body_never: "200 with empty roles or empty limits" consumer_meaning: "input degradation at access-engine (§9.3); fail to reduced authority" surfaces: - tenant_roles_cached - tenant_roles_live - tenant_record - tenant_guardrails live_lookup_authorization: action: tenant.role.read.live check_consumes_tenant_roles: false reenters_tenant_engine: false evidence: docs/flex-auth-integration.md notes: >- The check is a service-identity question (who may call this PIP), not a tenant-capability-role question. flex-auth's tenant-engine policy package matches subject id and action only and does not consult tenant_roles. Its live-roles adapter is built and unwired. Therefore GET /roles/live → POST /v1/check does not re-enter this engine.