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
3.1 KiB
3.1 KiB
Apps hand-over adapter (source candidate, NK-WP-0048-T29)
handover-adapter.py is an unexercised, injection-only seam for Warden's v1
kernel, modelled on the T13 registration adapter. It covers step (f),
Apps-owned consumer verification and the hand-over receipt.
- Descriptor:
descriptor(owner)— stephand-over, owner is a parameter (type 1.2 declares{consumer_owner_repo}; the T30 composer passes it, e.g.railiance-apps), actorhuman, laneapps-consumer-handover, targetclient_id, effectchange, allowed created objecthandover-receipt, not retry-safe, revocation scopeparent-session(the Warden v1 kernel refuses an empty scope set).build()derives the descriptor fromadmitted.owner; a 1.2 case must carry a boundedconsumer_owner_repoequal to it. The lane name is still a candidate value for Apps owner review. - Case binding: canonical
oidc-browser-relying-party@1.1is the default;@1.2is reached only through an explicitversion_root='1.2'selection, and successor@1.3(1.2 plusexecution_descriptors) only throughversion_root='1.3', with the sameconsumer_owner_repoowner handling. No--allow-unimplementedadmission exists. Case, descriptor and acceptance pins are checked;access_groupsmust be non-empty, because 1.1 hand-over requires the consumer to enforce them (consumer-enforces-groups). - Injected capabilities (required, never strings or case parameters):
verify_consumer(client_id, groups)must return exactlyclient_id,enforces_groups=True, the case'sgroups,login_verified=Trueandobservations(RAPPS-1.3-C2): a value-free list of{probe, evidence}records, one each formember-login,non-member-refused,membership-add-grantsandmembership-remove-revokes, evidence an owner evidence identifier (IDENTIFIER pattern). Missing, extra, duplicate or unknown probes and any other key are refused; the observation digest covers the records in canonical probe order;record_handover(client_id, observation_digest) -> (identifier, created);remove_handover(identifier) -> True;publish(bytes) -> identifierandauthenticate(identifier, bytes) -> Truefor owner evidence;revoke_session(invocation) -> identifier, called in afinallyblock on every run and rollback (even failed ones) so the parent session always ends. A missing or malformed revocation identifier refuses before publication; the identifier is recorded in the evidence payload and returned assession_revocation_evidencewithrevoked=True. - Rollback is created-only: only a receipt this process created and whose
evidence the owner authenticates may be removed. An existing receipt is
no_changeand never rolled back; unconfirmed removal refuses and keeps the creation. Process loss and ambiguity stay for owner reconciliation (T31/T15).
Tests: python3 -m pytest sso-mfa/k8s/keycape/test_handover_adapter.py
(synthetic fixtures only; no consumer, store or credential is touched).
Not supplied here: Apps owner source review before pinning, actual consumer verifier and receipt store, admission, and any native action.