Draft FLEX-WP-0008: tenant-engine consumer integration
Registers tenant-engine as a flex-auth protected-system consumer in both directions its boundary contract requires: tenant-engine's writes need authorization (FlexAuthWriteAuthorizer in TEN-WP-0003 currently gets deny/not_applicable for everything until a policy package exists), and flex-auth's own decisions for other protected systems need tenant capability roles as context input via a live-lookup adapter. Scoped closer to FLEX-WP-0006/0007 (ops-warden's small security-lane integration) than FLEX-WP-0003 (Markitect's CARING-benchmark integration) -- tenant-engine's resource/action vocabulary is small. Registered, not implemented. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0ed11a7520
commit
67b1f9161a
1 changed files with 125 additions and 0 deletions
125
workplans/FLEX-WP-0008-tenant-engine-consumer-integration.md
Normal file
125
workplans/FLEX-WP-0008-tenant-engine-consumer-integration.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
---
|
||||||
|
id: FLEX-WP-0008
|
||||||
|
type: workplan
|
||||||
|
title: "tenant-engine Consumer Integration"
|
||||||
|
domain: infotech
|
||||||
|
repo: flex-auth
|
||||||
|
status: ready
|
||||||
|
owner: codex
|
||||||
|
topic_slug: flex-auth
|
||||||
|
planning_priority: P1
|
||||||
|
planning_order: 80
|
||||||
|
depends_on_workplans:
|
||||||
|
- FLEX-WP-0007
|
||||||
|
related_workplans:
|
||||||
|
- TEN-WP-0003
|
||||||
|
- KEY-WP-0005
|
||||||
|
created: "2026-07-23"
|
||||||
|
updated: "2026-07-23"
|
||||||
|
---
|
||||||
|
|
||||||
|
# FLEX-WP-0008: tenant-engine Consumer Integration
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Make `tenant-engine` a registered protected-system consumer of flex-auth,
|
||||||
|
in both directions its boundary contract requires
|
||||||
|
(`net-kingdom/canon/standards/tenant-engine-boundary-contract_v0.1.md`):
|
||||||
|
|
||||||
|
1. **tenant-engine's writes need authorization.** `tenant-engine`'s
|
||||||
|
`FlexAuthWriteAuthorizer` (`TEN-WP-0003`) calls `POST /v1/check` for
|
||||||
|
every mutation (`tenant.create`, `tenant.role.grant`, `tenant.role.revoke`,
|
||||||
|
`tenant.plan.assign`). Until a policy package exists here, every check
|
||||||
|
resolves to `deny`/`not_applicable` — correct fail-closed behavior, but
|
||||||
|
it means `tenant-engine` cannot actually perform any write yet. This
|
||||||
|
workplan is what makes real `allow` decisions reachable.
|
||||||
|
2. **flex-auth's own decisions need tenant capability roles as input**, for
|
||||||
|
any protected system whose policy depends on a tenant's `PLTF`/`IAM`/
|
||||||
|
`VEN`/`CUS` roles (ADR-0014) at `aal2`-class decision time. flex-auth
|
||||||
|
must call `tenant-engine`'s live-lookup endpoint
|
||||||
|
(`GET /tenants/{id}/roles/live`) to enrich decision context, the same
|
||||||
|
role a `context` adapter plays for any other external fact source.
|
||||||
|
|
||||||
|
Closer in shape to `FLEX-WP-0006`/`FLEX-WP-0007` (ops-warden's small,
|
||||||
|
security-lane SSH-certificate integration) than `FLEX-WP-0003` (Markitect's
|
||||||
|
document-heavy, CARING-benchmark integration) — `tenant-engine`'s resource
|
||||||
|
and action vocabulary is small and doesn't need CARING descriptor mapping.
|
||||||
|
|
||||||
|
## Task: Define tenant-engine resource and action vocabulary
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: FLEX-WP-0008-T01
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
Resource types: `tenant`, `role-grant`, `plan-assignment`. Actions:
|
||||||
|
`tenant.create`, `tenant.role.grant`, `tenant.role.revoke`,
|
||||||
|
`tenant.plan.assign` — matching `TEN-WP-0003-T02`'s action-name mapping
|
||||||
|
exactly (coordinate values, don't let the two repos invent different
|
||||||
|
strings for the same action). Model on `examples/ops-warden`'s fixture
|
||||||
|
shape (`schemas/check_request.schema.json`'s `resource{id,type,system}`,
|
||||||
|
`system: "tenant-engine"`), not Markitect's.
|
||||||
|
|
||||||
|
Done when: resource/action vocabulary documented under `docs/` following
|
||||||
|
the `markitect-resource-namespace.md` / `markitect-action-vocabulary.md`
|
||||||
|
naming pattern (`tenant-engine-resource-namespace.md`,
|
||||||
|
`tenant-engine-action-vocabulary.md`).
|
||||||
|
|
||||||
|
## Task: Author and register the tenant-engine policy package
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: FLEX-WP-0008-T02
|
||||||
|
status: todo
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
Policy: writes require an `aal2`+ assurance actor holding an appropriate
|
||||||
|
capability role for the action (e.g. `tenant.plan.assign` might require
|
||||||
|
`PLTF` or a platform-operator subject type; exact rules are a design
|
||||||
|
decision for this task, not pre-specified here — coordinate with ADR-0014's
|
||||||
|
role semantics, not invented fresh). Register in `registry/` per the
|
||||||
|
existing pattern; add fixtures (`allow`/`deny` request/response pairs)
|
||||||
|
mirroring `examples/ops-warden/check_request_allow_adm.json`.
|
||||||
|
|
||||||
|
Done when: `POST /v1/check` against a request matching `TEN-WP-0003`'s
|
||||||
|
`FlexAuthCheckClient` shape returns `allow` for an authorized actor/action
|
||||||
|
and `deny` for an unauthorized one, exercised by `main_test.go`-style
|
||||||
|
integration tests.
|
||||||
|
|
||||||
|
## Task: tenant-engine live-lookup context adapter
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: FLEX-WP-0008-T03
|
||||||
|
status: todo
|
||||||
|
priority: medium
|
||||||
|
```
|
||||||
|
|
||||||
|
A context-enrichment adapter (mirrors `internal/adapters/{relationship,rule,topaz}`'s
|
||||||
|
shape) that calls `tenant-engine`'s `GET /tenants/{id}/roles/live` and
|
||||||
|
attaches the result to decision context for policies that need it — used by
|
||||||
|
*other* protected systems' policies that key off tenant capability role,
|
||||||
|
not only by tenant-engine's own policy from T02. Must fail closed: adapter
|
||||||
|
error or `tenant-engine` unavailability must not silently produce an empty
|
||||||
|
role list indistinguishable from "no roles granted" (same rule
|
||||||
|
`tenant-engine`'s own read endpoints already enforce — don't weaken it on
|
||||||
|
the consuming side).
|
||||||
|
|
||||||
|
Done when: a policy package referencing tenant capability role context
|
||||||
|
correctly denies when the adapter call fails, not just when it succeeds
|
||||||
|
with an empty result.
|
||||||
|
|
||||||
|
## Task: Closure review
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: FLEX-WP-0008-T04
|
||||||
|
status: todo
|
||||||
|
priority: low
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm T01–T03 done; run flex-auth's existing test suite plus the new
|
||||||
|
fixtures. Note in closure: `TEN-WP-0003`'s `FlexAuthWriteAuthorizer` should
|
||||||
|
be re-verified against a real `allow` decision once this workplan's policy
|
||||||
|
package exists (it was only tested against `deny`/`not_applicable`
|
||||||
|
responses when built, since this workplan didn't exist yet). Run `statehub
|
||||||
|
fix-consistency`.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue