Provisions the first real NetKingdom tenant (tenant:customer:binky, matching the slug already live in production OpenBao paths) with a human tenant-admin user and a workload-identity OIDC client for qonto-assistant's MCP callers, routed through secrets-engine for secret custody and ops-warden for discoverable, minimal-touch credential access. Closes Gap #1 flagged in qonto-assistant's QONTO-WP-0003 closure (no OIDC issuer existed in the fleet). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
8.8 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated |
|---|---|---|---|---|---|---|---|---|---|
| KEY-WP-0004 | workplan | Binky Hedgehog GmbH as first NetKingdom tenant + qonto-assistant workload identity | infotech | key-cape | ready | codex | netkingdom | 2026-07-23 | 2026-07-23 |
Binky Hedgehog GmbH as first NetKingdom tenant + qonto-assistant workload identity
Binky Hedgehog GmbH ("binky") becomes the first real tenant provisioned in
the NetKingdom IAM stack, per the NetKingdom IAM Profile v0.2's tenant claim
model (net-kingdom/canon/standards/iam-profile_v0.2.md §"Tenant Claim") —
distinct from tenant:platform (control plane) and tenant:coulomb (the
ecosystem-development tenant this workstation already operates under).
This closes Gap #1 flagged in qonto-assistant's
workplans/QONTO-WP-0003-mcp-surface.md closure: no OIDC issuer existed
anywhere in the fleet, so qonto-assistant's MCP surface shipped with an
interim shared-secret bearer token instead of real workload identity.
key-cape is "Implementation complete (v0.1)" and already implements the
profile's client_credentials/workload-identity grant for service accounts
— it's the component that should close this gap, not user-engine
(downstream user/profile data layer, not an identity provider) or
identity-canon (terminology research only).
Depends on: key-cape v0.1 (done, KEY-WP-0001), NetKingdom IAM Profile
v0.2 tenant + service-account claim rules (already ratified canon — no new
profile work needed, this is provisioning against an existing contract).
Downstream, not in this workplan: once T03/T04 land, qonto-assistant
needs its own follow-up workplan to swap mcp_auth.BearerTokenAuthMiddleware
for FastMCP's built-in TokenVerifier + AuthSettings(issuer_url=<key-cape>)
against the client registered here. Tracked as a pointer only — not created
by this workplan, since it's a different repo's scope and code change.
Task: Confirm tenant identifier and provision the tenant plane
id: KEY-WP-0004-T01
status: todo
priority: high
The IAM profile's tenant identifiers (tenant:platform, tenant:coulomb,
tenant:sandbox:<name>, tenant:customer:<name>) are documented as
suggested, not exhaustive — but tenant:customer:<name> is the closest fit
for the first real operating/customer-plane tenant, distinct from the
tenant:coulomb ecosystem-development plane.
Recommended default, to confirm before implementing: tenant:customer:binky
— matching the slug already live in production OpenBao paths
(tenants/binky/qonto-api, used by qonto-assistant today) rather than
tenant:customer:binky-hedgehog, to avoid a slug mismatch between the new
IAM tenant claim and the existing secret-custody path convention. Flag to
Bernd for explicit confirmation before provisioning — tenant identifiers are
expensive to rename once tokens and downstream config reference them.
Provision whatever tenant/org-unit boundary key-cape's current backend
(LLDAP/Authelia) needs so tokens issued for subjects under this tenant
correctly carry tenant:customer:binky and nothing implies platform-root
authority for it (profile rule: tenant administration for a tenant must
never imply platform-root authority).
Done when: tenant identifier confirmed and recorded (decision record or
canon note); a test-subject token carries the correct tenant claim.
Task: Provision bernd.worsch@binky-hedgehog.com as tenant-admin
id: KEY-WP-0004-T02
status: todo
priority: high
Create the user in key-cape's current backend, enroll MFA per profile
requirements (assurance claim, net-kingdom/canon/standards/iam-profile_v0.2.md),
and assign a tenant-admin role/group scoped to tenant:customer:binky only.
Prerequisite outside this repo's control: the binky-hedgehog.com mailbox
for bernd.worsch@ must exist and be reachable for account verification and
MFA enrollment. Flag to Bernd before starting — this task cannot complete
without it.
Done when: bernd.worsch@binky-hedgehog.com completes OIDC/PKCE + MFA login
and receives a token carrying tenant:customer:binky and a tenant-admin role
claim; the same token does not grant access to tenant:platform or any
other tenant.
Task: Register a workload-identity OIDC client for qonto-assistant callers
id: KEY-WP-0004-T03
status: todo
priority: high
Register an OIDC client per the profile's service-account/workload-identity
flow (client_credentials or the documented workload-token-exchange
equivalent — §"Service Account Flow"), scoped to tenant:customer:binky,
with the minimum role/scope qonto-assistant's MCP and REST surfaces
actually need. No interactive login for this client — it's for agent-harness
sessions and other automated callers, not humans.
The resulting client_secret must never be pasted into chat, Git, this
workplan, or a State Hub message or progress event — hand-off happens only
through T04's secrets-engine/OpenBao lane.
Done when: a client_credentials token exchange against key-cape succeeds
for this client and produces a short-lived service token carrying
tenant:customer:binky; the client_id and granted scopes are documented
here; no secret material appears anywhere in this repo's history.
Task: Route client_secret custody through secrets-engine + OpenBao
id: KEY-WP-0004-T04
status: todo
priority: high
Coordinate with secrets-engine to create a scoped OpenBao lane for this
client_secret, mirroring the existing tenants/binky/qonto-api pattern
already in production use for the Qonto bank credential itself — so
qonto-assistant's runtime fetches this the same way it already fetches the
Qonto API key, via its own dedicated runtime role
(qonto-assistant-runtime, per qonto-assistant/specs/ArchitectureBlueprint.md
§4.7), not a shared or ad hoc role.
Done when: qonto-assistant's runtime role can fetch the client_secret via
secrets-engine/OpenBao; Bernd never handles the raw value at any point in
this flow.
Task: Register the credential lane with ops-warden
id: KEY-WP-0004-T05
status: todo
priority: high
This is the task that directly minimizes Bernd's ongoing engagement: add an
entry to ops-warden's routing catalog (registry/routing/catalog.yaml)
pointing at this new OIDC client / login lane, following the pattern already
documented in ops-warden/SCOPE.md's "Issue vs route" table ("Login / OIDC /
MFA → key-cape / Keycloak → Assist — route; proxy login lane when
exec_capable"). ops-warden does not mint tokens or take custody here — it
routes/assists, same as every other credential lane it fronts.
Once the OpenBao lane from T04 exists, run ops-warden's workload security
posture conformance checker
(ops-warden/scripts/check_secret_posture_conformance.py) against the new
qonto-assistant workload to confirm it meets the expected maturity tier
(dev/test/prod posture, M0–M3 workload maturity) before this goes live with
real credentials, and record the result (pass or documented exception).
Done when: warden route show (or equivalent) resolves this lane correctly;
posture conformance check passes or exceptions are explicitly recorded; from
this point on, discovering and using this credential lane needs warden access, not direct key-cape/OpenBao admin knowledge.
Task: automation@binky-hedgehog.com service identity (deferred)
id: KEY-WP-0004-T06
status: todo
priority: low
Forward-looking per Bernd's framing ("I guess it will later be helpful") —
do not provision until a concrete automation workflow actually needs its
own identity distinct from the qonto-assistant workload client from T03.
Dormant service-account credentials are themselves a posture risk (unused
attack surface, nothing to rotate against), so this stays parked rather than
front-loaded.
When a real consuming workflow exists: same pattern as T02 but scoped to an
automation-appropriate role (not tenant-admin), likely paired with its own
client_credentials registration for whichever agent/service authenticates
as it, following T03/T04/T05's pattern rather than inventing a new one.
Done when: explicitly triggered by a named consuming workflow — until then
this task stays todo and does not block closing the rest of this workplan.
Task: Closure review
id: KEY-WP-0004-T07
status: todo
priority: low
Mark workplan finished when T01–T05 are done (T06 may legitimately remain
todo/parked by design — see its own task note). Confirm end to end: a
human token (bernd.worsch@binky-hedgehog.com, tenant-admin) and a service
token (qonto-assistant workload client) both resolve to tenant:customer:binky
and nothing else; the credential lane is discoverable via warden access
without Bernd touching key-cape/OpenBao admin surfaces directly. Note the
qonto-assistant-side follow-up workplan (swap bearer token for
TokenVerifier) as the next step, out of this workplan's scope. Run
statehub fix-consistency.