All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 37s
Engine/PIP declaration is now checkable (layer.yaml plus a Tooling-client scan). Writes persist a decision record or the published fail-closed stance, live-lookup freshness is published, events_for is tenant-scoped, and mutation evidence drains to audit-core from a local outbox without blocking the mutation. Sender registration is requested as AUDIT-IN-0002. Boundary-contract amendment is requested as NET-IN-0002. Assistant: grok Assistant-Session: 01a04cea-e5e8-7081-a0fc-808ebbc35fa9
80 lines
2.9 KiB
YAML
80 lines
2.9 KiB
YAML
# 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.
|