Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P Assistant: claude-code Assistant-Model: opus Assistant-Process: 713576@bnt-lap001 Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2.3 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| KEY-WP-0024 | workplan | Wire tenant_roles as explicit opt-in configuration | infotech | key-cape | finished | claude | tenant-roles-opt-in-wiring | 2026-09-08 | 2026-09-08 | d75f52f2-df0d-5a56-8394-892feeec4b4d |
Closes gap G07. The tenant-engine client and TokenHandler.TenantEngine were
implemented and tested, but main.go supplied no client and exposed no
configuration, so the stock executable left the field nil and never emitted
tenant_roles. The capability existed at library level only.
Wired rather than documented away as library-only: the claim is cheap, the adapter already fails open, and leaving a tested capability unreachable from the binary invites the same gap being rediscovered later.
Add opt-in configuration and wire the client
id: KEY-WP-0024-T01
status: done
priority: medium
state_hub_task_id: "0e53485b-7e94-5dd8-8e02-1d18f5413a78"
Added a tenantEngine config block with baseURL and an optional timeout.
An empty baseURL disables the claim, which keeps the stock server's behaviour
exactly as it was — enabling it is a deliberate act.
Validation treats a configured source as one that must work: the URL must be
http/https with a host, and the timeout must parse and fall in (0, 10s], since it
sits on the synchronous token-issuance path. A timeout set without a baseURL
is rejected rather than ignored — it means someone expected the claim to be on
and it silently would not have been.
Verify it in the built executable
id: KEY-WP-0024-T02
status: done
priority: medium
state_hub_task_id: "c4279ce0-f6f8-5612-a48a-c1d2fd3da3b6"
G07's closure criterion is the built executable, not the wiring, so all three
behaviours were checked by running bin/keycape and inspecting real tokens
rather than by reading the code:
- configured against a stub tenant-engine, a
client_credentialstoken carriestenant_roles: [capability:approve, capability:observe]; - with no
tenantEngineblock, the claim is absent; - configured but with the source down, issuance still succeeds and the claim is absent — the fail-open behaviour the adapter documents, confirmed end to end.
Nine validation cases cover the accepted and rejected configurations.