net-kingdom/sso-mfa/k8s/keycape/bind-env-adapter.md
tegwick cbadd359ba NK-WP-0048 r5 adapters: OW-1.3-C1 attended change lane, RAPPS-1.3-C1 human actor, RAPPS-1.3-C2 handover observations
Lane key-cape-oidc-login -> keycape-attended-case-change in the register-client,
ensure-groups and bind-env descriptors; deliver-consumer-secret actor agent ->
human; verify_consumer reports a value-free, exactly-once probe record list bound
into the observation digest. Composition artifacts, type.yaml and admit/compose
tests are left for the orchestrator to regenerate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 903097@bnt-lap001
Assistant-Session: aa320c8f-c3fa-46e7-8541-0b58e1e45d23
2026-10-17 11:59:14 +02:00

43 lines
2.7 KiB
Markdown

# Bind-env adapter source candidate (NK-WP-0048-T27)
Status: **unexercised source candidate**. Not reviewed, pinned, admitted or run.
`bind-env-adapter.py` adds one `env` entry to the `keycape` container of the
`sso/keycape` Deployment, binding the helper-derived name
(`KEYCAPE_<CLIENT>_CLIENT_SECRET`) to `valueFrom.secretKeyRef` on the delivered
secret reference (`keycape-<client>-client`, key `client-secret`). It handles
references only: a binding carrying `value`, or an existing entry of that name
bound to anything else (including a literal), is refused.
- Case parsing reuses `keycape-client.py` (`client_from_case`, `env_binding`), so
canonical `oidc-browser-relying-party@1.1` stays the default; public clients
and `allow_unimplemented` are refused.
- `read`/`write` are injected capabilities; `write` is compare-and-swap on the
observed `resourceVersion`. No kubectl, credential or secret value is used.
- `build(...)` returns a closed Warden v1 `Adapter` (T13 pattern). It pins the
owner source digest over the full local import closure (`bind-env-adapter.py`,
`keycape-client.py`, `portal-client-rollout.py`, `openbao-client-config.py`,
`register-user-engine-portal.py` — closure checked by
`test_adapter_source_closure.py`), the
descriptor digest (`Pins.adapter`), case source and acceptance digests, and the
admitted invocation (step `bind-env`, actor `human`, lane `keycape-attended-case-change`,
created object `keycape-env-binding`, not retry-safe, `parent-session` scope).
Every attempt is rebound to that invocation and re-checks source drift.
- `publish`, `authenticate` and `revoke_session` are mandatory injected
capabilities. The parent session is revoked in `finally`, also on refusal; a
missing revocation or invalid/reused evidence identifier is never success.
Evidence payload is closed metadata (`netkingdom.keycape-bind-env.attempt.v1`:
invocation, source, outcome, env name, before/after revision) with no values.
- An identical existing binding is `no-change` and is not rollbackable.
- Rollback removes only the entry this process created, whose evidence still
authenticates (a fresh process has no creation authority), and only while the
Deployment is still at the revision that creation produced; otherwise owner
reconciliation is required.
Tests: `PYTHONPATH=~/ops-warden/src ~/ops-warden/.venv/bin/python -m pytest -q
test_bind_env_adapter.py` (synthetic only).
Not supplied: kernel-level admission/dispatch tests with fixture trust (as in T13),
owner confirmation of the proposed step/lane/schema/object names, NetKingdom
runtime owner source review before pinning, the real owner evidence and
revocation capabilities, and any native action. Those remain separate gates.