NK-WP-0054-T04: KeyCape live view compared; rapp-qonto-client declared by its live name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 149903@bnt-lap001 Assistant-Session: 4c20a536-1452-4a85-bc09-e1987d9817d6
This commit is contained in:
parent
6252ab8d7e
commit
ff7e295fd0
4 changed files with 405 additions and 4 deletions
|
|
@ -78,3 +78,28 @@ The founder re-exported with the RPF-WP-0067-T03 commands. Both exited 0, and no
|
|||
|
||||
The executor's write role `net-kingdom-bind-executor-svc-authelia-write` is absent, which CCR-2026-0058 requires
|
||||
between admitted runs. The checker now treats that absence as conformant (`window_scoped`).
|
||||
|
||||
## KeyCape live view, 2026-11-07 (KEY-WP-0045-T02)
|
||||
|
||||
The founder ran `keycape identity-facts` on the deployed `sso/keycape-config`, streamed without writing the config
|
||||
to disk. Output: `keycape-identity-facts-20261107.json`, sha256 `755ab2c27be251e0db6ebef8e2754734c584e920070b23d939dc6b4e3b9087cd`. It holds no secret-shaped values, and
|
||||
KeyCape's own `findings` list is empty.
|
||||
|
||||
**Matches the declaration:**
|
||||
- the service clients `approval-engine-operator`, `informed-decision-sitting-requester` (now including
|
||||
`approval:read`, so the 2026-10-31 live step is in place), `secrets-engine-approval`, `secrets-engine-openbao`
|
||||
and `secrets-engine-requester`, all with exactly the declared scopes;
|
||||
- the directory bind `svc-keycape`, which is not a directory admin (T05 split live);
|
||||
- the factor service with `require_for_all: true`.
|
||||
|
||||
**Items for key-cape:**
|
||||
1. `approval-engine-operator` is still registered with `approval:approve`. The declaration noted it as withdrawn
|
||||
(KEY-WP-0013-T02). A service client that can approve conflicts with GH-DEC-2026-026: a service relies on an
|
||||
approval and must never be one of its approvers.
|
||||
2. `upstream_oidc.client_secret` is `inline`: the Authelia client secret sits in the config instead of an env
|
||||
reference.
|
||||
3. The declared `rapp-qonto` is live as `rapp-qonto-client` (`qonto:read`, role `qonto-reader`). That resolves its
|
||||
`unknown`; the declaration needs the live name.
|
||||
|
||||
The human public clients and `nk-bind-executor-approval` are covered elsewhere (relying parties;
|
||||
`bounded-executor.yaml`). `observe.py` does not yet compare KeyCape automatically.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,369 @@
|
|||
{
|
||||
"schema": "keycape-identity-facts/v0.1",
|
||||
"issuer": "https://kc.coulomb.social",
|
||||
"environment": "production",
|
||||
"token_lifetime": "15m",
|
||||
"clients": [
|
||||
{
|
||||
"client_id": "approval-engine-operator",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"approval:create",
|
||||
"approval:read",
|
||||
"approval:approve",
|
||||
"approval:revoke",
|
||||
"approval:supersede",
|
||||
"approval:observe",
|
||||
"approval:emit"
|
||||
],
|
||||
"service_subject": "service:approval-engine-operator",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"approval-operator"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "coulomb-social",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "coulomb-social",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"mfa_required": false,
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "demo-app",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "demo-app",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "forgejo",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "forgejo",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"mfa_required": true,
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "informed-decision-approver",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"approval:read",
|
||||
"approval:approve"
|
||||
],
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"mfa_required": true,
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "informed-decision-sitting-requester",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"approval:create",
|
||||
"approval:read"
|
||||
],
|
||||
"service_subject": "informed-decision",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"informed-decision-sitting-requester"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "netkingdom-bootstrap-console",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "netkingdom-bootstrap-console",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "nk-bind-executor-approval",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"approval:create",
|
||||
"approval:read",
|
||||
"approval:consume"
|
||||
],
|
||||
"service_subject": "service:nk-bind-executor",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"bounded-executor"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "nk-synthetic-journey",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "nk-synthetic-journey",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"mfa_required": true,
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "openbao-admin",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "openbao-admin",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "rapp-qonto-client",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "rapp-qonto-client",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"qonto:read"
|
||||
],
|
||||
"service_subject": "rapp-qonto",
|
||||
"tenant": "tenant:friendly:binky",
|
||||
"roles": [
|
||||
"qonto-reader"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "secrets-engine-approval",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"approval:read",
|
||||
"approval:consume"
|
||||
],
|
||||
"service_subject": "service:secrets-engine",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"secrets-engine"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "secrets-engine-openbao",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "secrets-engine-openbao",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openbao:login"
|
||||
],
|
||||
"service_subject": "service:secrets-engine",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"secrets-engine"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "secrets-engine-requester",
|
||||
"principal_type": "SERVICE",
|
||||
"client_type": "confidential",
|
||||
"grant_types": [
|
||||
"client_credentials"
|
||||
],
|
||||
"audience": "approval-engine",
|
||||
"audience_source": "registration",
|
||||
"scopes": [
|
||||
"approval:create"
|
||||
],
|
||||
"service_subject": "secrets-engine",
|
||||
"tenant": "tenant:platform",
|
||||
"roles": [
|
||||
"secrets-engine-requester"
|
||||
],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "env-ref"
|
||||
},
|
||||
{
|
||||
"client_id": "user-engine-portal",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "user-engine-portal",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "none"
|
||||
},
|
||||
{
|
||||
"client_id": "vergabe-demo-company",
|
||||
"principal_type": "HUMAN",
|
||||
"client_type": "public",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
],
|
||||
"audience": "vergabe-demo-company",
|
||||
"audience_source": "client-id-default",
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"groups"
|
||||
],
|
||||
"roles": [],
|
||||
"token_lifetime": "15m",
|
||||
"credential": "none"
|
||||
}
|
||||
],
|
||||
"directory_bind": {
|
||||
"url": "ldap://lldap.sso.svc.cluster.local:3890",
|
||||
"bind_dn": "uid=svc-keycape,ou=people,dc=netkingdom,dc=local",
|
||||
"base_dn": "dc=netkingdom,dc=local",
|
||||
"password_in_config": false,
|
||||
"password_source": "",
|
||||
"bind_is_directory_admin": false
|
||||
},
|
||||
"factor_service": {
|
||||
"base_url": "http://privacyidea.mfa.svc.cluster.local:8080",
|
||||
"realm": "coulomb",
|
||||
"admin_credential": "file",
|
||||
"require_for_all": true
|
||||
},
|
||||
"upstream_oidc": {
|
||||
"base_url": "http://authelia.sso.svc.cluster.local:9091",
|
||||
"client_id": "keycape",
|
||||
"client_secret": "inline"
|
||||
},
|
||||
"admin_surfaces": [
|
||||
{
|
||||
"path": "/platform/authentication-policy",
|
||||
"enabled": "when KEYCAPE_POLICY_PATH is set (deployment env, not config)",
|
||||
"authority": "KeyCape token with azp user-engine-portal, role platform-operator, assurance aal2 with mfa within 300s"
|
||||
},
|
||||
{
|
||||
"path": "/introspect",
|
||||
"enabled": "no",
|
||||
"authority": "confidential client authentication; only tokens issued to the caller"
|
||||
},
|
||||
{
|
||||
"path": "/revoke",
|
||||
"enabled": "no",
|
||||
"authority": "confidential client authentication; only tokens issued to the caller"
|
||||
}
|
||||
],
|
||||
"findings": []
|
||||
}
|
||||
|
|
@ -74,12 +74,12 @@ identities:
|
|||
owner: "key-cape owners and the consuming service owner"
|
||||
rotation: {path: "Mint in custody, then deliver (credential broker); KeyCape reads it at start", coupling: [keycape, informed-decision-sitting]}
|
||||
status: active
|
||||
- name: rapp-qonto
|
||||
- name: rapp-qonto-client
|
||||
principal_type: SERVICE
|
||||
purpose: "Confidential OIDC client; its token scopes are not established in the repository"
|
||||
purpose: "Confidential OIDC client for rapp-qonto: scope qonto:read, role qonto-reader, tenant tenant:friendly:binky (live view 2026-11-07, KEY-WP-0045-T02)"
|
||||
grants:
|
||||
- {mode: USE, scope: keycape, activation: STANDING, environments: [PRODUCTION], note: "client credentials"}
|
||||
- {mode: unknown, scope: "token scopes", note: "reference config: rapp-qonto-client, qonto:read; confirm live (KEY-WP-0045-T02)"}
|
||||
- {mode: OBSERVE, scope: "qonto: qonto:read", activation: STANDING, environments: [PRODUCTION], note: "role qonto-reader; observed live 2026-11-07"}
|
||||
interactive_login: false
|
||||
second_factor: not_applicable
|
||||
custody: [delivered-secret]
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ status: wait
|
|||
priority: medium
|
||||
assignee: claude-code
|
||||
depends_on: [NK-WP-0054-T03]
|
||||
blocking_reason: "Rerun 2026-11-07 on a fresh export: 0 non-conformant (keycape alias disabled, confirmed). Open: railiance-platform answers on the platform-admin max TTL and 14 undeclared roles, the founder's KeyCape live view (KEY-WP-0045-T02), then the posture-feedback feed."
|
||||
blocking_reason: "Rerun 2026-11-07 on a fresh export: 0 non-conformant (keycape alias disabled, confirmed). Open: railiance-platform answers on the platform-admin max TTL and 14 undeclared roles, key-cape on approval-engine-operator and the inline upstream secret (KeyCape live view done), then the posture-feedback feed."
|
||||
state_hub_task_id: "c8db4607-9306-572b-a3cb-c35ca5989ec7"
|
||||
```
|
||||
|
||||
|
|
@ -255,6 +255,13 @@ remains, and the session survived. **Confirmed by the 14:34Z fresh export:** the
|
|||
non-conformant and 14 unknown among undeclared roles. The executor's write role is absent between runs, as
|
||||
CCR-2026-0058 requires, and is now checked as window-scoped.
|
||||
|
||||
**2026-11-07 KeyCape live view** (KEY-WP-0045-T02, founder-run;
|
||||
[evidence](../docs/evidence/2026-11-07-nk-wp-0054-t04-conformance/README.md)). The five declared service clients
|
||||
match their live scopes, the directory bind is `svc-keycape` (not admin), and the factor service has
|
||||
`require_for_all`. The declaration now uses the live name `rapp-qonto-client` (`qonto:read`). Routed to key-cape
|
||||
(message `0e9c2553`): `approval-engine-operator` is still registered with `approval:approve`, and the upstream
|
||||
Authelia secret is inline in config.
|
||||
|
||||
## Split the directory bind from the human admin
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue