NK-WP-0048-T16 r5: 1.3 step text states how each step runs; canon clarifies kernel-dispatched attended steps
Folds NK-1.3-C1/C2, RPF-1.3-C1/C2, RAPPS-1.3-C3, KC-1.3-C1 and the OW-1.3-C1 lane names. Parameters untouched (fingerprint unchanged). The execution_descriptors map is regenerated after the adapter changes land. 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
This commit is contained in:
parent
239a528d62
commit
aba012eba2
2 changed files with 96 additions and 40 deletions
|
|
@ -101,6 +101,19 @@ A type is a directory `security-case-types/<type-id>/` in net-kingdom containing
|
|||
standing credential for the step; that would make it a broker (ops-warden
|
||||
ADR-0002). *(Clarified 2026-10-09 from ops-warden's review,
|
||||
WARDEN-WP-0044-T01 R1–R3.)*
|
||||
|
||||
A step listed in the type's `execution_descriptors` is admissible to
|
||||
ops-warden's case kernel whatever its `warden_executes` value, and the kernel
|
||||
enforces the step's mode. For an `attended` step, "kernel-dispatched" means
|
||||
the reviewed adapter runs only inside the attended human session (descriptor
|
||||
actor `human`, the step's own lane, parent-session revocation per attempt),
|
||||
never under an agent or a standing credential. The human session is the
|
||||
authority, and the kernel is only the dispatcher. For an owner-path step
|
||||
(neither `warden_executes` nor `attended`), the lane must resolve to the
|
||||
owner's own delegated path, and ops-warden holds no owner credential.
|
||||
`warden_executes` keeps its caller-proxy meaning above for unattended steps.
|
||||
*(Clarified 2026-10-17 from the 1.3 owner reviews, NK-1.3-C2 and ops-warden
|
||||
KERNEL-3.)*
|
||||
- `verification`: the checks that prove a case is live (positive and
|
||||
negative), runnable without reading a secret value
|
||||
- `rollback`: the exact inverse of each step
|
||||
|
|
|
|||
|
|
@ -232,14 +232,15 @@ spec:
|
|||
follow_through:
|
||||
- id: ensure-groups
|
||||
owner: net-kingdom
|
||||
entry_point: identity-provisioner ensure_service_groups, run inside the provisioner
|
||||
pod through the session's contained cluster access (groups {access_groups};
|
||||
members exactly {initial_members} as recorded in the accepted case, nothing
|
||||
else)
|
||||
auth: operator cluster access in the attended register-client session; the in-pod
|
||||
call uses the provisioner's own directory binding, and no provisioner or user-engine
|
||||
token is read or sent
|
||||
lane: key-cape-oidc-login
|
||||
entry_point: reviewed adapter net-kingdom/keycape-ensure-groups, dispatched by Warden's
|
||||
case kernel inside the attended session; it calls identity-provisioner
|
||||
ensure_service_groups in the provisioner pod through the session's contained
|
||||
cluster access (groups {access_groups}; members exactly {initial_members} as
|
||||
recorded in the accepted case, nothing else)
|
||||
auth: the attended human session on lane keycape-attended-case-change (actor human,
|
||||
parent-session revoked per attempt); the in-pod call uses the provisioner's own
|
||||
directory binding, and no provisioner or user-engine token is read or sent
|
||||
lane: keycape-attended-case-change
|
||||
warden_executes: false
|
||||
attended: true
|
||||
value_handling: none
|
||||
|
|
@ -248,14 +249,17 @@ spec:
|
|||
would act as user-engine (ops-warden review R8; canon section 3; ops-warden
|
||||
ADR-0002). Running it in the session register-client already needs adds no attended
|
||||
session. It can become unattended once the provisioner has an operator credential
|
||||
of its own and an admitted path.
|
||||
of its own and an admitted path. Warden's case kernel dispatches the reviewed adapter only inside the one attended human session (descriptor actor human, lane keycape-attended-case-change, parent-session revoked per attempt); the human session is the authority and the kernel is only the dispatcher.
|
||||
- id: mint-secret
|
||||
owner: railiance-platform
|
||||
when: client_type == confidential
|
||||
entry_point: 'railiance-platform credential broker: generate a client secret inside
|
||||
custody at bao:platform/workloads/keycape/{client_id}'
|
||||
auth: the caller's broker grant for the case's KV path, through its lane; the
|
||||
value is generated in custody and never returned
|
||||
custody at bao:platform/workloads/keycape/{client_id}, through reviewed adapter
|
||||
railiance-platform/keycape-mint-secret'
|
||||
auth: a human caller (net-kingdom-admins, aal2) starts it; Warden runs it unattended
|
||||
through the broker lane under the caller's session, with the caller's broker grant
|
||||
for the case's KV path; agents and root are refused, and the value is generated
|
||||
in custody and never returned
|
||||
lane: keycape-client-secret-generate
|
||||
warden_executes: true
|
||||
attended: false
|
||||
|
|
@ -263,10 +267,14 @@ spec:
|
|||
- id: deliver-secret
|
||||
owner: railiance-platform
|
||||
when: client_type == confidential
|
||||
entry_point: ExternalSecret sso/keycape-{client_id}-client (key client-secret)
|
||||
from bao:platform/workloads/keycape/{client_id}
|
||||
auth: railiance-platform ESO delivery through role external-secrets-keycape-{client_id};
|
||||
no value leaves custody
|
||||
entry_point: reviewed adapter railiance-platform/keycape-deliver-secret, dispatched
|
||||
by Warden's case kernel; Platform's deliver capability applies ExternalSecret
|
||||
sso/keycape-{client_id}-client (key client-secret) through the ESO store for
|
||||
role external-secrets-keycape-{client_id}, from bao:platform/workloads/keycape/{client_id}
|
||||
auth: Platform's own delivery path on lane platform-secret-delivery, inside the human
|
||||
aal2 session; ESO reads custody through role external-secrets-keycape-{client_id};
|
||||
Warden holds no Platform credential, and no value leaves custody
|
||||
lane: platform-secret-delivery
|
||||
warden_executes: false
|
||||
attended: false
|
||||
value_handling: none
|
||||
|
|
@ -275,23 +283,30 @@ spec:
|
|||
- id: bind-env
|
||||
owner: net-kingdom
|
||||
when: client_type == confidential
|
||||
entry_point: 'patch Deployment sso/keycape: env KEYCAPE_{client_id:env}_CLIENT_SECRET
|
||||
from sso/keycape-{client_id}-client'
|
||||
auth: operator kube credentials for namespace sso
|
||||
lane: key-cape-oidc-login
|
||||
entry_point: 'reviewed adapter net-kingdom/keycape-bind-env, dispatched by Warden''s
|
||||
case kernel inside the attended session: patch Deployment sso/keycape env
|
||||
KEYCAPE_{client_id:env}_CLIENT_SECRET from sso/keycape-{client_id}-client, by
|
||||
reference only'
|
||||
auth: the attended human session on lane keycape-attended-case-change, with operator
|
||||
kube credentials for namespace sso (actor human, parent-session revoked per attempt)
|
||||
lane: keycape-attended-case-change
|
||||
warden_executes: false
|
||||
attended: true
|
||||
value_handling: none
|
||||
attended_justification: A change to the live identity provider's Deployment. It
|
||||
runs in the same attended operator session as register-client, before it, because
|
||||
KeyCape resolves a confidential client's secret at start and fails closed if
|
||||
the binding is missing.
|
||||
the binding is missing. Warden's case kernel dispatches the reviewed adapter only inside the one attended human session (descriptor actor human, lane keycape-attended-case-change, parent-session revoked per attempt); the human session is the authority and the kernel is only the dispatcher.
|
||||
- id: register-client
|
||||
owner: net-kingdom
|
||||
entry_point: sso-mfa/k8s/keycape/keycape-client.py apply --client-file <client-from-case>
|
||||
--case-acceptance <record> --check-config <keycape binary> (net-kingdom.keycape-client-registration)
|
||||
auth: operator write access to the live KeyCape client registry in namespace sso
|
||||
lane: key-cape-oidc-login
|
||||
entry_point: reviewed adapter net-kingdom/keycape-register-client, dispatched by Warden's
|
||||
case kernel inside the attended session; it runs sso-mfa/k8s/keycape/keycape-client.py
|
||||
apply --client-file <client-from-case> --case-acceptance <record> --check-config
|
||||
<keycape binary> (net-kingdom.keycape-client-registration)
|
||||
auth: the attended human session on lane keycape-attended-case-change, with operator
|
||||
write access to the live KeyCape client registry in namespace sso (actor human,
|
||||
parent-session revoked per attempt)
|
||||
lane: keycape-attended-case-change
|
||||
warden_executes: false
|
||||
attended: true
|
||||
value_handling: none
|
||||
|
|
@ -303,37 +318,63 @@ spec:
|
|||
authorization and handoff state in memory, so the restart drops in-flight logins
|
||||
and sessions for every client; runs go in a quiet window (key-cape type review
|
||||
R4). The rendered registry must pass KeyCape''s own startup checks (keycape
|
||||
check-config, key-cape c528daa, which keycape-client.py runs before it patches)
|
||||
check-config, the pinned checker artifact sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5
|
||||
built from key-cape 3c71226, which keycape-client.py runs before it patches)
|
||||
before the restart: a refused entry stops the single replica and every client
|
||||
loses sign-in (R1).'
|
||||
loses sign-in (R1). Warden''s case kernel dispatches the reviewed adapter only inside the one attended human session (descriptor actor human, lane keycape-attended-case-change, parent-session revoked per attempt); the human session is the authority and the kernel is only the dispatcher.'
|
||||
- id: deliver-consumer-secret
|
||||
owner: '{consumer_owner_repo}'
|
||||
when: client_type == confidential
|
||||
entry_point: Owner applies dedicated ServiceAccount {consumer_namespace}/{consuming_service}-keycape-{client_id}-eso
|
||||
entry_point: Reviewed adapter net-kingdom/keycape-deliver-consumer-secret, dispatched
|
||||
by Warden's case kernel inside the attended consumer-owner session; the owner's
|
||||
apply capability creates dedicated ServiceAccount {consumer_namespace}/{consuming_service}-keycape-{client_id}-eso
|
||||
(automount=false, no legacy tokens), namespace SecretStore openbao-keycape-{client_id}-consumer
|
||||
with serviceAccountRef and audiences [openbao], and ExternalSecret {consuming_service}-netkingdom-oidc-client
|
||||
with Owner target, Retain remote deletion and only CLIENT_SECRET from workloads/keycape/{client_id}.
|
||||
Admission validates actual installed ESO TokenRequest support and common controller
|
||||
RBAC before any owner-approved apply.
|
||||
auth: Consumer owner contained Kubernetes deployment authority; ESO authenticates
|
||||
to OpenBao role external-secrets-keycape-{client_id}-{consuming_service} with
|
||||
a TokenRequest for the dedicated namespaced serviceAccountRef; controller remains
|
||||
trusted
|
||||
auth: the attended consumer-owner session on lane consumer-owner-deployment (actor
|
||||
human, the consumer owner's operator deployment authority, on the founder's go
|
||||
for the change); ESO authenticates to OpenBao role external-secrets-keycape-{client_id}-{consuming_service}
|
||||
with a TokenRequest for the dedicated namespaced serviceAccountRef; controller
|
||||
remains trusted
|
||||
lane: consumer-owner-deployment
|
||||
warden_executes: false
|
||||
attended: false
|
||||
attended: true
|
||||
value_handling: none
|
||||
attended_justification: The consumer owner's only deployment authority in the consumer
|
||||
namespace is its operator credential, and production applies need the founder's
|
||||
go per change. No contained agent deployer identity exists, and the owner does
|
||||
not want a standing credential an agent could trigger. It runs in one attended
|
||||
consumer-owner session together with hand-over. Warden's case kernel dispatches
|
||||
the reviewed adapter only inside that session (actor human, parent-session
|
||||
revoked per attempt); the human session is the authority and the kernel is only
|
||||
the dispatcher.
|
||||
ready_check: Namespace SecretStore and ExternalSecret both report Ready=True;
|
||||
dedicated SA has no legacy token refs; status and fixed metadata only, never
|
||||
Secret values.
|
||||
- id: hand-over
|
||||
owner: '{consumer_owner_repo}'
|
||||
entry_point: configure {consuming_service} with issuer {issuer}, client {client_id}
|
||||
and custody bao:platform/workloads/keycape/{client_id}, and make it require
|
||||
one of {access_groups} in the groups claim before sign-in completes
|
||||
auth: the consumer owner's own deployment path
|
||||
entry_point: The consumer owner first makes its own Helm change configuring {consuming_service}
|
||||
with issuer {issuer}, client {client_id} and custody bao:platform/workloads/keycape/{client_id},
|
||||
requiring one of {access_groups} in the groups claim before sign-in completes.
|
||||
Then reviewed adapter net-kingdom/keycape-hand-over, dispatched by Warden's case
|
||||
kernel inside the attended consumer-owner session, verifies the consumer with
|
||||
four value-free probes (member-login, non-member-refused, membership-add-grants,
|
||||
membership-remove-revokes) and records the hand-over receipt.
|
||||
auth: the attended consumer-owner session on lane apps-consumer-handover (actor human,
|
||||
parent-session revoked per attempt); the consumer configuration itself is the
|
||||
owner's own deployment path
|
||||
lane: apps-consumer-handover
|
||||
warden_executes: false
|
||||
attended: false
|
||||
attended: true
|
||||
value_handling: none
|
||||
attended_justification: The verification needs a real member login and a refused
|
||||
non-member login, which only an attended session can perform, and it follows
|
||||
the owner's own Helm change in the same consumer-owner session as
|
||||
deliver-consumer-secret. Warden's case kernel dispatches the reviewed adapter
|
||||
only inside that session (actor human, parent-session revoked per attempt); the
|
||||
human session is the authority and the kernel is only the dispatcher.
|
||||
verification:
|
||||
- id: authorize-accepts-redirects
|
||||
check: GET {issuer}/authorize with client {client_id} and each of {redirect_uris}
|
||||
|
|
@ -389,8 +430,10 @@ spec:
|
|||
reads_secret_value: false
|
||||
rollback:
|
||||
- reverses: hand-over
|
||||
action: remove the OIDC source for {client_id} from {consuming_service} (owner
|
||||
{consumer_owner_repo})
|
||||
action: the adapter removes only its hand-over receipt. Removing the OIDC source
|
||||
for {client_id} from {consuming_service} is the owner's Helm rollback (owner
|
||||
{consumer_owner_repo}), done inside deliver-consumer-secret's owner_remove
|
||||
before any consumer object is removed
|
||||
- reverses: deliver-consumer-secret
|
||||
when: client_type == confidential
|
||||
action: After reverting consumer secret reference, delete only authenticated created
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue