Record native security preparation and owner checkpoints (2/7)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 8s

This commit is contained in:
codex 2026-10-17 07:51:36 +02:00
parent 275e034883
commit a6eee04d42
18 changed files with 5770 additions and 0 deletions

View file

@ -0,0 +1,27 @@
{
"schema": "custodian.native-identity-refinement.v1",
"revision": 2,
"status": "source_task_refinement_ready_not_published",
"task": "NK-WP-0049-T38",
"previous_task_count": 37,
"result_task_count": 38,
"old_task_blocks_preserved": true,
"uuid_assignment": "normal owner allocator; no UUID supplied",
"root_source_review": "accepted narrow guard and two-hash unexecuted successor scope in root instruction; no privileged/native approval inferred",
"knowledge_orientation": {
"package_version": "0.2.6",
"package_digest": "sha256:8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02",
"retrieval_status": "withheld",
"reason": "source changed",
"source_review": "current AGENTS, environment orientation, Security Companion and identity/start card source reviewed directly; knowledge is source-only orientation and grants no authority"
},
"frozen_r1_manifest_sha256": "sha256:6821e650a4ca07087697b5091a3db26b722456170c1c4816ca8c49bdf527fce4",
"files": {
"NK-WP-0049.postimage.md": "sha256:e0cd01320b366ab8961a0a52a908edc1524f98b3cfab7382a14fa915da2f60a2",
"NK-WP-0049.preimage.md": "sha256:5830c429f58a0317b28c7b4bcf22a1b46e6d01b41378cdae95f947c6d9317e44",
"task-refinement.patch": "sha256:a2e17aa51eb0313f1370ff366afb1198ce93624bb7451445dd62be9b663e70f0",
"updated-owner-source.patch": "sha256:552484c86a7ac8b443faea6222aeb6d660eb0148f5d596c90f94ac9c60c2a6b0"
},
"canonical_workplan_matches_postimage": true,
"diff_whitespace_check": "passed"
}

View file

@ -0,0 +1,96 @@
--- a/workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md
+++ b/workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md
@@ -1130,23 +1130,15 @@
`recovery-owner-handoffs-r1` source review; independent ID/UUID/status/remote
readback is recorded separately when performed.
-2026-10-17 exact-selector source preparation: the adapter now requires exactly
-one selected client in the already-restored archived configuration before further
-runtime environment reads, signer-key parsing or native checker invocation.
-Absent, duplicate (identical or conflicting) and empty selectors refuse early;
-existing unique registration behavior is retained. This check cannot run before
-private archive decryption or its key prompt. Current KeyCape Go configuration
-also rejects duplicate IDs; this is an explicit adapter guard, not a claim that
-the pinned native issuer admitted duplicates. Tests use public/synthetic config
-and mocked native calls only. Changed adapter bytes require a fresh reviewed
-source/dependency and admission binding; old actual fixture receipts are retained.
-The exact eight-field current consumer selector independently passes its offline
-AST-only preflight. TLS public provenance/private custody, archive-time selector
-binding, current owner recovery assent and outage-compatible actual consumer
-proof remain open under T35/T36 and the existing owner tasks. No actual archive,
-key, Secret object, token exchange, OpenBao login, rotation or native action was
-performed. Source evidence and proposed owner declaration/consumer plan:
-Custodian docs/changes/netkingdom-target-2026-10-17/native-identity-r1/.
+2026-10-17 source checkpoint refinement: the completed exact-one original
+selector guard and its bounded refusal/unique-selector proof are extracted into
+T38. T36 retains exact archive-to-selector binding, current actual service-owner
+recovery assent and outage-compatible private admission/consumer preparation.
+The current eight-field source-selector correspondence is evidenced separately;
+it does not complete those remaining obligations or any T18/T19 native gate.
+T33 continues to require the complete reviewed TLS/custody/admission packet.
+This extraction records one source outcome rather than counting it again as
+original registration validation or consumer continuity.
## Verify actual SOPS compatibility and sealed-descriptor read/write custody
@@ -1188,6 +1180,51 @@
T35 TLS/trust disposition and T36 original registration/private admission remain
open under their existing owner boundaries.
+## Deliver exact-one original selector guard and bounded source refusal proof
+
+```task
+id: NK-WP-0049-T38
+status: done
+priority: high
+assignee: codex
+depends_on: [NK-WP-0049-T34]
+```
+
+Completed 2026-10-17 as source preparation, independently reviewed by the
+coordinating Custodian agent. The adapter now requires exactly one selected
+registration in the already-restored archive configuration before further runtime
+environment reads, signer-key parsing or native checker invocation. Absent,
+empty, identical-duplicate and conflicting-duplicate selectors refuse before
+those later inputs; the existing unique-selector mocked native path still passes.
+Current KeyCape Go configuration also rejects duplicate IDs; this makes the
+adapter's own boundary explicit and establishes no native duplicate exploit.
+The guard cannot run before archive decryption or the original key prompt.
+
+The 39 adapter checks passed, including four added early-refusal regressions.
+Running those four cases against the retained original adapter failed the new
+refusal contract as expected. The broader 77-check source run retained 76 passes
+and one stale fixture-proposal source-hash refusal. Only the two affected hashes
+and scope of that unexecuted/unapproved successor proposal were then refreshed;
+all four affected fixture-plan checks passed. The original manifest preimage and
+failure receipt remain retained, and frozen actual R6 runtime receipts were not
+changed or claimed as proof of this successor. No broader native rerun occurred.
+
+Evidence: Custodian
+`docs/changes/netkingdom-target-2026-10-17/native-identity-r1/`:
+`owner-source.patch`, `verification.json`, `manifest.json`, retained preimages,
+`original-behavior-regression.txt` and `focused-regressions.stderr.txt`.
+The later task extraction and exact workplan successor bytes are in
+`refinement-r2/`; the original source-proof packet remains immutable.
+Canonical owner publication, allocator-assigned Hub UUID and projection must be
+recorded separately through the normal owner process; none is claimed here.
+
+This completes only the source guard/refusal deliverable extracted from T36.
+T35 original TLS public provenance/private custody or accepted reissue, T36 exact
+archive binding/current owner assent/consumer custody preparation, T33 complete
+attempt readiness, T18 actual recovery/consumer acceptance and T19 retained-factor
+MFA remain open. No actual archive, private key, Secret object, token exchange,
+OpenBao login, rotation, production action or owner assent was exercised.
+
## Accept remaining recovery and caller evidence and close the G08 handoff
```task
@@ -1207,7 +1244,7 @@
G08 receiving the final evidence. The completed archive/job milestones remain
accepted independently of this final gate.
-**Done when:** T02 and T15–T37 have their stated completed or explicitly accepted
+**Done when:** T02 and T15–T38 have their stated completed or explicitly accepted
handoff outcomes; service authentication/token/audit proof and current/legacy
caller dispositions are accepted; the source workplan and projected tasks agree;
and G08 has an exact evidence/handoff record. Record actionable residuals as live

View file

@ -0,0 +1,189 @@
--- a/tools/bootstrap-recovery/isolated-keycape.py
+++ b/tools/bootstrap-recovery/isolated-keycape.py
@@ -322,6 +322,23 @@
def run_verifier(session, admission, payload):
+ # Select from the already-restored config before further private/runtime reads.
+ # This is not public preflight before archive decryption or its key prompt.
+ import yaml
+ cfg = yaml.safe_load(base64.b64decode(payload['files']['/etc/keycape/config.yaml'],validate=True))
+ if not isinstance(cfg,dict) or cfg.get('issuer') != admission['issuer']:
+ raise Refused()
+ consumer = admission['consumer']
+ clients = cfg.get('clients')
+ if not isinstance(clients,list) or any(not isinstance(client,dict) for client in clients):
+ raise Refused()
+ matches = [client for client in clients if client.get('clientId') == consumer['client_id']]
+ if len(matches) != 1:
+ raise Refused()
+ client = matches[0]
+ if (client.get('secretRef') != 'env:'+consumer['secret_env'] or client.get('clientType') != 'confidential'
+ or 'client_credentials' not in client.get('grantTypes',[])):
+ raise Refused()
issuer = session['issuer']
if {v['target'] for v in session.get('volumes',{}).values()}!={'/etc/keycape','/var/lib/keycape-policy','/etc/keycape-factor','/recovery-tls'}:raise Refused()
from urllib.parse import urlsplit
@@ -352,15 +369,7 @@
if durable!={k:v for k,v in files.items() if k.startswith('/var/lib/keycape-policy/')}:
raise Refused()
equal()
- # Reading YAML is data parsing only; no archived executable is evaluated.
- import yaml
- cfg = yaml.safe_load(files['/etc/keycape/config.yaml'])
- if cfg['issuer'] != admission['issuer']:
- raise Refused()
- consumer = admission['consumer']
- client = next(x for x in cfg['clients'] if x['clientId']==consumer['client_id'])
- if (client['secretRef']!='env:'+consumer['secret_env'] or client['clientType']!='confidential'
- or 'client_credentials' not in client['grantTypes'] or not env.get(consumer['secret_env'])):
+ if not env.get(consumer['secret_env']):
raise Refused()
from cryptography.hazmat.primitives import serialization
key=serialization.load_pem_private_key(files['/etc/keycape/key.pem'],password=None)
--- a/tests/test_isolated_keycape_recovery.py
+++ b/tests/test_isolated_keycape_recovery.py
@@ -53,6 +53,34 @@
for row in self.manifest['files']:
if row['path'].endswith('/deployment/keycape.json'):row.update(bytes=len(raw),sha256=hashlib.sha256(raw).hexdigest())
with self.assertRaises(a.Refused):self.payload()
+
+
+class OriginalSelectorTests(unittest.TestCase):
+ """Already-restored public fixture config; no archive/key/native action."""
+ def assert_refused_before_further_inputs(self,clients):
+ import yaml
+ cfg={'issuer':'https://issuer.example','clients':clients}
+ payload={'files':{'/etc/keycape/config.yaml':base64.b64encode(yaml.safe_dump(cfg).encode()).decode(),
+ '/etc/keycape/key.pem':'deliberately-not-base64'}}
+ admission={'issuer':'https://issuer.example','consumer':{'client_id':'existing','secret_env':'KEYCAPE_ORIGINAL_SECRET'}}
+ # Empty session/no env and an undecodable key also expose early private access.
+ from contextlib import ExitStack
+ with ExitStack() as stack:
+ blocked=[stack.enter_context(patch.object(a,name,side_effect=AssertionError('later input or native call')))
+ for name in ('container_file','runtime_file','runtime_files','command','check_jwks','process')]
+ with self.assertRaises(a.Refused):a.run_verifier({},admission,payload)
+ for call in blocked:call.assert_not_called()
+ def client(self):
+ return {'clientId':'existing','clientType':'confidential','secretRef':'env:KEYCAPE_ORIGINAL_SECRET',
+ 'grantTypes':['client_credentials']}
+ def test_absent_original_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([dict(self.client(),clientId='unrelated')])
+ def test_identical_duplicate_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([self.client(),self.client()])
+ def test_conflicting_duplicate_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([self.client(),dict(self.client(),secretRef='env:OTHER')])
+ def test_empty_registry_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([])
class NativeTests(unittest.TestCase):
def setUp(self):
--- a/tests/isolated-keycape-native-fixture-manifest.json
+++ b/tests/isolated-keycape-native-fixture-manifest.json
@@ -7,7 +7,7 @@
"tests/run_isolated_keycape_native_fixture.py": "sha256:ecbadecc475622eaaf20a726110aebef5f4fe7af141110a98aca1640179b4a03",
"tests/test_identity_bundle.py": "sha256:be5ce74097594cc7f7e77dbccd6cb53aa72f263cd1bb442ce5464038aed1116c",
"tests/test_isolated_keycape_fixture_plan.py": "sha256:5945619f4c5957187763276cc900870a9f08f9475b63c240694688e0c2eca7dd",
- "tests/test_isolated_keycape_recovery.py": "sha256:247e9a87f5be2ee9f20f7edbb4a9f612ab7cb0cd940392c3caeca8b046605f55",
+ "tests/test_isolated_keycape_recovery.py": "sha256:5f729e077db51dd6b17d00dc3eb71c0e652849f55fe68505a07befa663c91dea",
"tests/test_isolated_keycape_session.py": "sha256:cbdf51efde26eff337e9303a2c431f80b333b8846d763eb62853f81eb3f13e2c",
"tools/bootstrap-recovery/capture-identity.py": "sha256:47dca7c4dc96fa7eb9fb02c81fca9ca8dc5281aac918979eb7367148168ba705",
"tools/bootstrap-recovery/check-privacyidea-database.py": "sha256:90f454c87998d7f5d625e3c6656c3418f8f56275dc1879a9d19ed605431b94a4",
@@ -25,7 +25,7 @@
"tools/bootstrap-recovery/inventory-scaleway.py": "sha256:a219df205708fa4ed44b763a418585d63c820c25434bc0fd14e805eb5c2f79d3",
"tools/bootstrap-recovery/inventory-storage-share.py": "sha256:673f9b17fb2f3fef6fcdb5c50a2bcca69e3df3157a9e5582a2d995c6b87640b5",
"tools/bootstrap-recovery/isolated-keycape-session.py": "sha256:8fa38efe28167b59a6307f342b2ac8fcda78ecda60e6228f22017424d2343c22",
- "tools/bootstrap-recovery/isolated-keycape.py": "sha256:f67627b7d1647d75187dd899874efe22383bc91de5d97dabb9801076668ab3c2",
+ "tools/bootstrap-recovery/isolated-keycape.py": "sha256:86f37add7221e4c73e3f9d878c09a3cc81061627cbf024ed6887d973d929b718",
"tools/bootstrap-recovery/isolated-lldap.py": "sha256:35bfa8411186ad936a199bd450c7e18c2ad51059301a6db9650e6bd055ab1b81",
"tools/bootstrap-recovery/isolated-privacyidea.py": "sha256:4df7196678aac1ad594f32abf45c68dc21a9d2760d9e8a536a215a4a3c5d277f",
"tools/bootstrap-recovery/prepare-identity-coverage.py": "sha256:cd5f3067d28b4c7cc93ed08b8cf3869218bdecf7c54b5dffed22d697de71dbb1",
@@ -81,7 +81,7 @@
"synthetic_source_root": "private /dev/shm/nk49-keycape-fixture-<suffix>",
"safe_result": "private /tmp/nk49-keycape-native-fixture-review-<suffix>/result.json"
},
- "scope": "candidate itself on complete synthetic format/integrity archive fixture; no native PI/LLDAP/Authelia proof, real custody, real factor or real client credential; successor binds sealed-descriptor custody preparation sources; synthetic fixture itself overrides custody with generated fixture key as before",
+ "scope": "candidate itself on complete synthetic format/integrity archive fixture; no native PI/LLDAP/Authelia proof, real custody, real factor or real client credential; successor binds sealed-descriptor custody preparation sources; synthetic fixture itself overrides custody with generated fixture key as before; unexecuted exact-one-selector adapter successor: no new native outcome inferred from earlier fixtures",
"mutations": [
"conditional creation of exact fresh local containers and local-driver tmpfs volumes",
"private synthetic file import to those volumes",
--- a/workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md
+++ b/workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md
@@ -1130,6 +1130,16 @@
`recovery-owner-handoffs-r1` source review; independent ID/UUID/status/remote
readback is recorded separately when performed.
+2026-10-17 source checkpoint refinement: the completed exact-one original
+selector guard and its bounded refusal/unique-selector proof are extracted into
+T38. T36 retains exact archive-to-selector binding, current actual service-owner
+recovery assent and outage-compatible private admission/consumer preparation.
+The current eight-field source-selector correspondence is evidenced separately;
+it does not complete those remaining obligations or any T18/T19 native gate.
+T33 continues to require the complete reviewed TLS/custody/admission packet.
+This extraction records one source outcome rather than counting it again as
+original registration validation or consumer continuity.
+
## Verify actual SOPS compatibility and sealed-descriptor read/write custody
```task
@@ -1170,6 +1180,51 @@
T35 TLS/trust disposition and T36 original registration/private admission remain
open under their existing owner boundaries.
+## Deliver exact-one original selector guard and bounded source refusal proof
+
+```task
+id: NK-WP-0049-T38
+status: done
+priority: high
+assignee: codex
+depends_on: [NK-WP-0049-T34]
+```
+
+Completed 2026-10-17 as source preparation, independently reviewed by the
+coordinating Custodian agent. The adapter now requires exactly one selected
+registration in the already-restored archive configuration before further runtime
+environment reads, signer-key parsing or native checker invocation. Absent,
+empty, identical-duplicate and conflicting-duplicate selectors refuse before
+those later inputs; the existing unique-selector mocked native path still passes.
+Current KeyCape Go configuration also rejects duplicate IDs; this makes the
+adapter's own boundary explicit and establishes no native duplicate exploit.
+The guard cannot run before archive decryption or the original key prompt.
+
+The 39 adapter checks passed, including four added early-refusal regressions.
+Running those four cases against the retained original adapter failed the new
+refusal contract as expected. The broader 77-check source run retained 76 passes
+and one stale fixture-proposal source-hash refusal. Only the two affected hashes
+and scope of that unexecuted/unapproved successor proposal were then refreshed;
+all four affected fixture-plan checks passed. The original manifest preimage and
+failure receipt remain retained, and frozen actual R6 runtime receipts were not
+changed or claimed as proof of this successor. No broader native rerun occurred.
+
+Evidence: Custodian
+`docs/changes/netkingdom-target-2026-10-17/native-identity-r1/`:
+`owner-source.patch`, `verification.json`, `manifest.json`, retained preimages,
+`original-behavior-regression.txt` and `focused-regressions.stderr.txt`.
+The later task extraction and exact workplan successor bytes are in
+`refinement-r2/`; the original source-proof packet remains immutable.
+Canonical owner publication, allocator-assigned Hub UUID and projection must be
+recorded separately through the normal owner process; none is claimed here.
+
+This completes only the source guard/refusal deliverable extracted from T36.
+T35 original TLS public provenance/private custody or accepted reissue, T36 exact
+archive binding/current owner assent/consumer custody preparation, T33 complete
+attempt readiness, T18 actual recovery/consumer acceptance and T19 retained-factor
+MFA remain open. No actual archive, private key, Secret object, token exchange,
+OpenBao login, rotation, production action or owner assent was exercised.
+
## Accept remaining recovery and caller evidence and close the G08 handoff
```task
@@ -1189,7 +1244,7 @@
G08 receiving the final evidence. The completed archive/job milestones remain
accepted independently of this final gate.
-**Done when:** T02 and T15–T37 have their stated completed or explicitly accepted
+**Done when:** T02 and T15–T38 have their stated completed or explicitly accepted
handoff outcomes; service authentication/token/audit proof and current/legacy
caller dispositions are accepted; the source workplan and projected tasks agree;
and G08 has an exact evidence/handoff record. Record actionable residuals as live

View file

@ -0,0 +1,77 @@
{
"credential_request_performed": false,
"queries": [
{
"query": "original KeyCape ingress TLS certificate recovery independent custody",
"candidates": [
{
"id": "keycape-client-secret-generate",
"owner_repo": "railiance-platform",
"resolvable": false,
"warden_executes": false
},
{
"id": "openrouter-llm-connect",
"owner_repo": "railiance-platform",
"resolvable": true,
"warden_executes": false
},
{
"id": "openbao-structure-survey",
"owner_repo": "ops-mason",
"resolvable": false,
"warden_executes": false
},
{
"id": "agent-harness-forgejo-deploy",
"owner_repo": "railiance-platform",
"resolvable": true,
"warden_executes": false
},
{
"id": "key-cape-oidc-login",
"owner_repo": "key-cape",
"resolvable": false,
"warden_executes": false
}
],
"interpretation": "Discovery only; no exact independent original TLS custody route or new credential authority inferred; unrelated generation/rotation lanes not selected."
},
{
"query": "KeyCape secrets-engine-openbao client secret custody",
"candidates": [
{
"id": "keycape-client-secret-generate",
"owner_repo": "railiance-platform",
"resolvable": false,
"warden_executes": false
},
{
"id": "rapp-qonto-keycape-client",
"owner_repo": "key-cape",
"resolvable": true,
"warden_executes": false
},
{
"id": "secrets-engine-approval-client-login",
"owner_repo": "railiance-platform",
"resolvable": true,
"warden_executes": false
},
{
"id": "database-dynamic-credentials",
"owner_repo": "rapp-postgres",
"resolvable": false,
"warden_executes": false
},
{
"id": "openbao-api-key",
"owner_repo": "railiance-platform",
"resolvable": false,
"warden_executes": false
}
],
"interpretation": "Discovery only; no exact independent original TLS custody route or new credential authority inferred; unrelated generation/rotation lanes not selected."
}
]
}

View file

@ -0,0 +1,28 @@
{
"command": [
"python3",
"tools/check-keycape-recovery-selector.py",
"--selector",
"docs/keycape-recovery-selector.json",
"--source-sha256",
"sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0"
],
"exit_code": 0,
"result": {
"schema": "secrets-engine.recovery-selector-preflight.v1",
"status": "source_selector_matches_not_native_assent",
"source_sha256": "sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0",
"consumer": {
"client_id": "secrets-engine-openbao",
"secret_env": "KEYCAPE_SECRETS_ENGINE_OPENBAO_CLIENT_SECRET",
"audience": "secrets-engine-openbao",
"scope": "openbao:login",
"subject": "service:secrets-engine",
"tenant": "tenant:platform",
"roles": "secrets-engine",
"deny_scope": "openbao:admin"
},
"credential_source_exercised": false,
"network_contacted": false
}
}

View file

@ -0,0 +1,80 @@
--- a/tools/bootstrap-recovery/isolated-keycape.py
+++ b/tools/bootstrap-recovery/isolated-keycape.py
@@ -322,6 +322,23 @@
def run_verifier(session, admission, payload):
+ # Select from the already-restored config before further private/runtime reads.
+ # This is not public preflight before archive decryption or its key prompt.
+ import yaml
+ cfg = yaml.safe_load(base64.b64decode(payload['files']['/etc/keycape/config.yaml'],validate=True))
+ if not isinstance(cfg,dict) or cfg.get('issuer') != admission['issuer']:
+ raise Refused()
+ consumer = admission['consumer']
+ clients = cfg.get('clients')
+ if not isinstance(clients,list) or any(not isinstance(client,dict) for client in clients):
+ raise Refused()
+ matches = [client for client in clients if client.get('clientId') == consumer['client_id']]
+ if len(matches) != 1:
+ raise Refused()
+ client = matches[0]
+ if (client.get('secretRef') != 'env:'+consumer['secret_env'] or client.get('clientType') != 'confidential'
+ or 'client_credentials' not in client.get('grantTypes',[])):
+ raise Refused()
issuer = session['issuer']
if {v['target'] for v in session.get('volumes',{}).values()}!={'/etc/keycape','/var/lib/keycape-policy','/etc/keycape-factor','/recovery-tls'}:raise Refused()
from urllib.parse import urlsplit
@@ -352,15 +369,7 @@
if durable!={k:v for k,v in files.items() if k.startswith('/var/lib/keycape-policy/')}:
raise Refused()
equal()
- # Reading YAML is data parsing only; no archived executable is evaluated.
- import yaml
- cfg = yaml.safe_load(files['/etc/keycape/config.yaml'])
- if cfg['issuer'] != admission['issuer']:
- raise Refused()
- consumer = admission['consumer']
- client = next(x for x in cfg['clients'] if x['clientId']==consumer['client_id'])
- if (client['secretRef']!='env:'+consumer['secret_env'] or client['clientType']!='confidential'
- or 'client_credentials' not in client['grantTypes'] or not env.get(consumer['secret_env'])):
+ if not env.get(consumer['secret_env']):
raise Refused()
from cryptography.hazmat.primitives import serialization
key=serialization.load_pem_private_key(files['/etc/keycape/key.pem'],password=None)
--- a/tests/test_isolated_keycape_recovery.py
+++ b/tests/test_isolated_keycape_recovery.py
@@ -53,6 +53,34 @@
for row in self.manifest['files']:
if row['path'].endswith('/deployment/keycape.json'):row.update(bytes=len(raw),sha256=hashlib.sha256(raw).hexdigest())
with self.assertRaises(a.Refused):self.payload()
+
+
+class OriginalSelectorTests(unittest.TestCase):
+ """Already-restored public fixture config; no archive/key/native action."""
+ def assert_refused_before_further_inputs(self,clients):
+ import yaml
+ cfg={'issuer':'https://issuer.example','clients':clients}
+ payload={'files':{'/etc/keycape/config.yaml':base64.b64encode(yaml.safe_dump(cfg).encode()).decode(),
+ '/etc/keycape/key.pem':'deliberately-not-base64'}}
+ admission={'issuer':'https://issuer.example','consumer':{'client_id':'existing','secret_env':'KEYCAPE_ORIGINAL_SECRET'}}
+ # Empty session/no env and an undecodable key also expose early private access.
+ from contextlib import ExitStack
+ with ExitStack() as stack:
+ blocked=[stack.enter_context(patch.object(a,name,side_effect=AssertionError('later input or native call')))
+ for name in ('container_file','runtime_file','runtime_files','command','check_jwks','process')]
+ with self.assertRaises(a.Refused):a.run_verifier({},admission,payload)
+ for call in blocked:call.assert_not_called()
+ def client(self):
+ return {'clientId':'existing','clientType':'confidential','secretRef':'env:KEYCAPE_ORIGINAL_SECRET',
+ 'grantTypes':['client_credentials']}
+ def test_absent_original_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([dict(self.client(),clientId='unrelated')])
+ def test_identical_duplicate_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([self.client(),self.client()])
+ def test_conflicting_duplicate_selector_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([self.client(),dict(self.client(),secretRef='env:OTHER')])
+ def test_empty_registry_refused_before_further_inputs(self):
+ self.assert_refused_before_further_inputs([])
class NativeTests(unittest.TestCase):
def setUp(self):

View file

@ -0,0 +1,173 @@
{
"status": "pre_edit_reviewed_public_source_snapshot",
"references": [
{
"repo": "net-kingdom",
"path": "AGENTS.md",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:95158b1d5c15e6cf8be980f5c0e3b48aeef252654846273887f40516b3fa6a78",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "SECURITY-COMPANION.md",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:06374445ca888549f1bf79527d1345d94918d7a7ec363160d8427d0e7a31d643",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "sso-mfa/k8s/keycape/ingress.yaml",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:bc5c7524a82de5e8b9755e7d7d408b4a66e034424cb2663c1d21352d292d5a72",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "tools/bootstrap-recovery/identity-backup-profile.json",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:40f9e5b5bb957e5b23e03b31701702b850502d16a92a0fa0ebf92618cc3f18a1",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "tools/bootstrap-recovery/isolated-keycape.py",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:f67627b7d1647d75187dd899874efe22383bc91de5d97dabb9801076668ab3c2",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "tools/bootstrap-recovery/isolated-keycape-session.py",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:8fa38efe28167b59a6307f342b2ac8fcda78ecda60e6228f22017424d2343c22",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "tools/bootstrap-recovery/prepare-isolated-keycape.py",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:5098bdfa4e0ad30627c1716e5e355a2c78dca6ccc607bd2148a2e06126632288",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "tools/bootstrap-recovery/run-isolated-keycape.sh",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:0d994c9c14ebdffdbf7879bd7562042531083d0e8955424d0ae099898a141668",
"worktree_matches_head": true
},
{
"repo": "net-kingdom",
"path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md",
"head_observed": "70f408ca2389bf3722a91a03832fc6e8587355e5",
"worktree_sha256": "sha256:678ec04b73b57c026001791706c05c5d4d5a508a32f17210ae8ad03ab15d53b8",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "AGENTS.md",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:1b98e24f9eb35c4c56b96ee7cbac21919bbe3b928144bfa7f29cca1c3249d5d0",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "src/secrets_engine/service_auth.py",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:c0ade429edf452ad17f05d690b7ebef091db7f1a42b5ac350f1e40955c8586c0",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "src/secrets_engine/engine_auth.py",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:e0479cf6d8c13233cf99dc39491143478c021597941ae8b6ba0e37957a42f330",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "docs/keycape-recovery-selector.json",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:02077af3c18b24f5e4a85992a3d4d0df51a8e458de1e48b48f7eb5f482257012",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "docs/keycape-isolated-recovery-selector.md",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:ed23b0df3d4b49e4b76df795455153c805971ccd37886836c960f550709e0739",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "tools/check-keycape-recovery-selector.py",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:e3e5e3ee743a212247701d6cb40fcf5b7f19349126fa9b32cbef9a3cc9459150",
"worktree_matches_head": true
},
{
"repo": "secrets-engine",
"path": "workplans/SECRETS-WP-0015-original-keycape-recovery-selector.md",
"head_observed": "c59bbf568c0be8a72ac593508f48c9b1f61ec4c1",
"worktree_sha256": "sha256:b3cab4e8d14b3b03179fc72a6e9ce1c0ee840cfa3247c022c1324d60378bde5b",
"worktree_matches_head": true
},
{
"repo": "railiance-cluster",
"path": "AGENTS.md",
"head_observed": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
"worktree_sha256": "sha256:5cc7808a6d0e5cdebc7b3f13a0d7dce9cee5441ed6de4703b67cf3fe1800d45b",
"worktree_matches_head": true
},
{
"repo": "railiance-cluster",
"path": "docs/keycape-tls-recovery-boundary.md",
"head_observed": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
"worktree_sha256": "sha256:f4bcb1d1832c566f9c87793ed2a461c8cd8a00859dc4ae66cd3c160d7ceefa70",
"worktree_matches_head": true
},
{
"repo": "railiance-cluster",
"path": "tools/public-tls-metadata.py",
"head_observed": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
"worktree_sha256": "sha256:87c167e44f0fcf154c9f2afae2187bebd33e5f220c05f579c1233b58bfe4f30b",
"worktree_matches_head": true
},
{
"repo": "railiance-cluster",
"path": "tools/cmd/railiance-backup-s2",
"head_observed": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
"worktree_sha256": "sha256:35c60b7ccccd7b4d5a1cf2134c1f2ca78c45040a7ffcc55f2c32c385a0a682a3",
"worktree_matches_head": true
},
{
"repo": "railiance-cluster",
"path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md",
"head_observed": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
"worktree_sha256": "sha256:96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b",
"worktree_matches_head": true
},
{
"repo": "key-cape",
"path": "src/internal/config/validate.go",
"head_observed": "834b0d06a13bb2ece9cc98392cb39ba0e2167ecb",
"worktree_sha256": "sha256:8189ee82e7df74a2a4a1f53e213b1be0a5c737fd76d8f283f7ec9f8ed38c3a65",
"worktree_matches_head": true
},
{
"repo": "emergent-security",
"path": "knowledge/cards/start.md",
"head_observed": "6eead2a922ae2eb81593213f54bf1f35e1c9970f",
"worktree_sha256": "sha256:698a18f4a8f97a43da75ed0767aa0425c970e17c04a9cbea75cfab719564cc5d",
"worktree_matches_head": true
},
{
"repo": "emergent-security",
"path": "knowledge/cards/identity.md",
"head_observed": "6eead2a922ae2eb81593213f54bf1f35e1c9970f",
"worktree_sha256": "sha256:5137f088da301f2229d15f198e6b9a492f9e141eeb572cca37a44251f954fad0",
"worktree_matches_head": true
}
]
}

View file

@ -0,0 +1,70 @@
{
"status": "source_regressions_passed_not_native_assent",
"canonical_changed_paths": [
"tools/bootstrap-recovery/isolated-keycape.py",
"tests/test_isolated_keycape_recovery.py",
"tests/isolated-keycape-native-fixture-manifest.json",
"workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md"
],
"changes": [
{
"path": "tools/bootstrap-recovery/isolated-keycape.py",
"preimage_sha256": "sha256:f67627b7d1647d75187dd899874efe22383bc91de5d97dabb9801076668ab3c2",
"postimage_sha256": "sha256:86f37add7221e4c73e3f9d878c09a3cc81061627cbf024ed6887d973d929b718"
},
{
"path": "tests/test_isolated_keycape_recovery.py",
"preimage_sha256": "sha256:247e9a87f5be2ee9f20f7edbb4a9f612ab7cb0cd940392c3caeca8b046605f55",
"postimage_sha256": "sha256:5f729e077db51dd6b17d00dc3eb71c0e652849f55fe68505a07befa663c91dea"
},
{
"path": "tests/isolated-keycape-native-fixture-manifest.json",
"preimage_sha256": "sha256:1dcefbc7ca7b0c2be33135b1b7977b89ba657223ecbb1310cc691d151b3d916e",
"postimage_sha256": "sha256:936ee435be04b27f391391e7dda02def69e153bde3adcce92d569f33f308db2e"
},
{
"path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md",
"preimage_sha256": "sha256:678ec04b73b57c026001791706c05c5d4d5a508a32f17210ae8ad03ab15d53b8",
"postimage_sha256": "sha256:5830c429f58a0317b28c7b4bcf22a1b46e6d01b41378cdae95f947c6d9317e44"
}
],
"checks": [
{
"command": "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p test_isolated_keycape_recovery.py",
"tests": 39,
"exit_code": 0,
"evidence": "tool result; includes existing full unique-selector mocked flow and four new pre-further-input refusal tests"
},
{
"command": "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p test_isolated_keycape*.py",
"tests": 77,
"pass": 76,
"errors": 1,
"exit_code": 1,
"evidence": "focused-regressions.stderr.txt",
"finding": "unexecuted source manifest correctly refused changed adapter/test hashes; retained before two-hash/scope update"
},
{
"command": "PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p test_isolated_keycape_fixture_plan.py",
"tests": 4,
"exit_code": 0,
"evidence": "tool result; only affected fixture-plan checks repeated after two-hash/scope refresh"
},
{
"command": "git diff --check -- four changed paths",
"exit_code": 0
},
{
"command": "new refusal regressions against retained original adapter bytes",
"tests": 4,
"errors": 4,
"expected_original_contract_failure": true,
"evidence": "original-behavior-regression.txt"
}
],
"limit": "All fixtures synthetic/mocked. Exact-one check runs on already-restored config, not before decryption or initial key prompt; no runtime action or credential source performed. Current native Go validation also rejects duplicate IDs.",
"review_status": "pending root independent review; no owner publication/sync performed",
"hub_writes": false,
"frozen_runtime_receipts_changed": false,
"task_status_changes": false
}

View file

@ -0,0 +1,240 @@
"""Rebuild source-only registration review; no native calls or source mutation."""
from pathlib import Path
import ast
import dataclasses
import datetime
import hashlib
import importlib.util
import json
import subprocess
import sys
sys.dont_write_bytecode = True
import yaml
HERE = Path(__file__).resolve().parent
CUST = HERE.parents[3]
NK = Path('/home/worsch/net-kingdom')
WARDEN = Path('/home/worsch/ops-warden')
AUDIT = Path('/home/worsch/audit-core')
PLATFORM = Path('/home/worsch/railiance-platform')
CHECKER = Path('/tmp/nk-checker-environment-r2-rebuild/keycape')
CHECKER_DIGEST = 'sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5'
REGISTER = NK / 'sso-mfa/k8s/keycape/keycape-registration-adapter.py'
refs = {}
def sha(data):
return 'sha256:' + hashlib.sha256(data).hexdigest()
def source(path, symbols=()):
path = Path(path)
raw = path.read_bytes()
item = {'path': str(path), 'sha256': sha(raw), 'bytes': len(raw)}
if path.suffix == '.py':
tree = ast.parse(raw)
item['symbols'] = {n.name: {'line': n.lineno, 'end_line': n.end_lineno}
for n in ast.walk(tree) if isinstance(n, (ast.FunctionDef, ast.ClassDef))
and n.name in symbols}
refs[str(path)] = item
return raw
def emit(name, value):
(HERE / name).write_text(json.dumps(value, indent=2, sort_keys=True) + '\n')
before_paths = [NK / 'security-case-types/oidc-browser-relying-party/type.yaml',
NK / 'security-cases/forgejo-netkingdom-oidc.yaml',
NK / 'security-case-type-revisions/1.2/oidc-browser-relying-party/type.yaml',
NK / 'security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml',
NK / 'security-case-type-revisions/1.2/oidc-browser-relying-party/decision/acknowledgment.json',
NK / 'workplans/NK-WP-0048-security-case-types.md']
before = {str(p): sha(source(p)) for p in before_paths}
for p in [NK / 'AGENTS.md', WARDEN / 'AGENTS.md', NK / 'SECURITY-COMPANION.md',
WARDEN / 'INTENT.md', NK / 'canon/standards/security-case-types_v0.1.md',
NK / 'docs/security-case-execution-owner-review.md',
NK / 'sso-mfa/k8s/keycape/registration-adapter.md',
WARDEN / 'docs/security-case-execution-kernel-v1.md',
WARDEN / 'workplans/WARDEN-WP-0044-security-case-follow-through.md',
AUDIT / 'docs/audit-backend-contract.md',
CUST / 'docs/changes/netkingdom-target-2026-10-16/browser-checker-environment-r2/build-receipt.json',
CUST / 'docs/changes/netkingdom-target-2026-10-16/browser-checker-artifact-next/coordinator-build-review.json']:
source(p)
source(REGISTER, ['build', 'source_digest', 'descriptor', 'execute', 'verify', 'checker_snapshot'])
source(WARDEN / 'src/warden/case_run.py', ['Journal', 'load', 'save', 'Executor', 'admit', 'run', 'rollback', 'reconcile', '_attempt', '_result'])
source(WARDEN / 'src/warden/case_receipt_state.py', ['recover', 'begin_rollback'])
source(WARDEN / 'src/warden/case_inputs.py', ['BrowserInputs', 'target'])
source(NK / 'tools/security-case-types/security_case_evidence.py', ['read_journal', 'check_steps', 'audit'])
source(NK / 'tools/security-case-types/security_case_validator.py', ['load_type', 'validate_execution_descriptors'])
source(NK / 'sso-mfa/k8s/keycape/test_keycape_registration_adapter.py', ['test_process_loss_does_not_reconstruct_created_authority', 'test_kernel_lost_readback_retains_uncertain_and_refuses_replay_and_undo'])
source(AUDIT / 'audit_core/ingestion.py', ['_read', 'normalize'])
source(AUDIT / 'audit_core/senders.py', ['SenderIdentity', 'evidence_declaration'])
source(AUDIT / 'audit_core/interface.py', ['AuditEvent', 'AcceptResult'])
source(PLATFORM / 'scripts/keycape_client_secret_generate.py', ['check_case', 'run', 'record_state_hub'])
# Generate the one existing real owner descriptor from current maintained source.
# Importing this source installs no adapters and performs no tooling operation.
sys.path.insert(0, str(WARDEN / 'src'))
spec = importlib.util.spec_from_file_location('registration_review_adapter', REGISTER)
adapter = importlib.util.module_from_spec(spec)
spec.loader.exec_module(adapter)
from warden.case_run import Descriptor
for name in adapter.SOURCE_FILES:
source(REGISTER.parent / name)
checker_bytes = CHECKER.read_bytes()
if sha(checker_bytes) != CHECKER_DIGEST:
raise SystemExit('reviewed existing checker bytes no longer match; stop')
source(CHECKER)
desc = adapter.descriptor(CHECKER_DIGEST)
descriptor_bytes = json.dumps(dataclasses.asdict(desc), sort_keys=True, separators=(',', ':')).encode()
if Descriptor.decode(descriptor_bytes) != desc:
raise SystemExit('actual owner descriptor decode failed')
(HERE / 'register-client.proposed-descriptor.json').write_bytes(descriptor_bytes)
# Preserve real source versions and list every actual follow-through boundary.
types = {}
for version, root in [('1.1', NK / 'security-case-types'), ('1.2', NK / 'security-case-type-revisions/1.2')]:
typ = yaml.safe_load((root / 'oidc-browser-relying-party/type.yaml').read_text())
types[version] = typ
if typ['spec'].get('execution_descriptors'):
raise SystemExit('owner source gained descriptor admission; review must be refreshed')
remaining = {
'ensure-groups': {'owner': 'net-kingdom', 'existing_seam': 'identity-provisioner governed journal T14 with delivered PostgreSQL T21',
'missing': ['native dedicated CNPG consumer, checkpoint holder and backup/lost-store continuity', 'authoritative tenant/case/source/principal callbacks', 'all LDAP writers fenced or provider CAS/ABA exclusion', 'exact owner adapter/source/descriptor and revocation evidence; existing legacy ensure/revoke is not created-only undo'],
'rollback': 'Only independently authenticated created groups/memberships; preserve shared/preexisting membership and unresolved intents.'},
'mint-secret': {'owner': 'railiance-platform', 'existing_seam': 'scripts/keycape_client_secret_generate.py; RPF-WP-0054 and existing broker lane',
'missing': ['fixed kernel Adapter/Descriptor for exact admitted case/type and broker source', 'authoritative case materialization receipt and original CAS0 uncertainty reconciliation', 'independent broker-grant AND parent-session revocation receipts for exact current attempt'],
'rollback': 'Never regenerate after uncertain write; read-only metadata reconciliation does not establish creation or retry authority; owner custody delete only if exact created-only entitlement.'},
'deliver-secret': {'owner': 'railiance-platform', 'existing_seam': 'existing ESO delivery/role and structural materialization boundary',
'missing': ['exact delivery object UID/ownerReference prestate and admitted owner adapter', 'current Ready status/readback without value access', 'independent cleanup/revocation receipt and owner custody identity'],
'rollback': 'Delete only authenticated case-created delivery objects, preserve preexisting target and shared resources.'},
'bind-env': {'owner': 'net-kingdom', 'existing_seam': 'existing sso/keycape Deployment prerequisite checked by keycape-client.py; T12',
'missing': ['reviewed fixed exact Deployment UID/resourceVersion/env binding update adapter', 'created-only prestate/readback and owner evidence/session capabilities', 'separately reviewed quiet-window restart/readiness procedure; registry helper only reports restart_required'],
'rollback': 'Restore only exact case-created env binding under current revision; a whole Deployment rollback or deleting preexisting env is not admitted.'},
'register-client': {'owner': 'net-kingdom', 'existing_seam': 'keycape-registration-adapter.py build/publish/authenticate/revoke_session injection seam',
'missing': ['actual admitted durable owner publisher/authenticator and exact parent-session revoker', 'native executable storage/provenance and exact descriptor/type source admission', 'T15 original-attempt recovery contract; fresh adapter intentionally cannot undo prior-process creation'],
'rollback': 'Same-process authenticated successful creation only; exact original entry and unchanged postcreation UID/resourceVersion; post-restart stays refused.'},
'deliver-consumer-secret': {'owner': 'railiance-apps for Forgejo', 'existing_seam': 'acknowledged source1.2 dedicated SA/namespace SecretStore/ExternalSecret composition',
'missing': ['actual installed ESO TokenRequest/RBAC compatibility and consumer owner admission', 'fixed owner adapter/descriptor for exact identities with created/preexisting readback', 'receiver evidence for Ready status and case-issued token revocation/expiry'],
'rollback': 'Revert consumer reference first; delete only authenticated created UID/ownerReference resources; SA/Store deletion alone does not immediately revoke OpenBao tokens.'},
'hand-over': {'owner': 'railiance-apps for Forgejo', 'existing_seam': 'consumer owner OIDC configuration and groups enforcement path',
'missing': ['owner exact deployment/source adapter/descriptor and accepted issuer/client/delivery binding', 'actual human login/group-denial and public authorization/MFA pin verifications', 'rollback and native receipt/custody acceptance'],
'rollback': 'Remove only this case-created OIDC source; preserve shared/preexisting auth sources and consumer state.'},
}
composition = []
for step in types['1.2']['spec']['follow_through']:
name = step['id']; item = remaining[name]
composition.append({'step': name, 'source_order': len(composition) + 1,
'declared_owner': step['owner'], 'resolved_first_consumer_owner': item['owner'],
'exists_in_default_1_1': name in [s['id'] for s in types['1.1']['spec']['follow_through']],
'source_step': step, 'existing_seam': item['existing_seam'],
'candidate_descriptor': json.loads(descriptor_bytes) if name == 'register-client' else None,
'candidate_descriptor_digest': sha(descriptor_bytes) if name == 'register-client' else None,
'missing_exact_owner_facts': item['missing'], 'rollback_requirement': item['rollback'],
'native_owner_assent': False, 'dispatch_permitted': False})
if set(remaining) != {s['id'] for s in types['1.2']['spec']['follow_through']}:
raise SystemExit('composition is incomplete for actual1.2 step inventory')
emit('descriptor-composition.json', {
'schema': 'custodian.registration-descriptor-review.v1',
'purpose': 'Review inventory only; this is not a Warden descriptor bundle or accepted SecurityCaseType.',
'source_versions': {v: {'status': t['spec']['status'], 'step_count': len(t['spec']['follow_through']), 'machine_descriptor_map_present': False} for v, t in types.items()},
'proposed_version_selection': {'first_consumer': 'Forgejo', 'review_base': 'explicit source-only oidc-browser-relying-party@1.2',
'why': 'Its dedicated consumer SA/ESO authentication boundary expresses the reviewed six-object structural design;1.1 does not.',
'default_loader': 'Keep canonical1.1 unchanged; select1.2 only through existing explicit version-root option for source review.',
'canonical_case': 'Keep1.1 accepted history unchanged and1.2 example proposed without acceptance fields.',
'descriptor_revision': 'Do not edit acknowledged source1.1/1.2 in place or inherit old acknowledgment for new descriptor bytes. Allocate the exact successor revision/version through NetKingdom canon section6 after the complete owner-reviewed set exists.',
'classification': 'Exact closed execution references and any changed trust/materialization/authentication must be classified by the existing owner; changed trust/authentication requires informed-decision acknowledgment, never self-classified as harmless validation.'},
'checker': {'path': str(CHECKER), 'sha256': CHECKER_DIGEST, 'bytes': len(checker_bytes), 'native_custody_admitted': False,
'runtime_contract': 'Current owner adapter rehashes source/file, snapshots exact checker into sealed memfd, executes same snapshot for live/proposed checks with empty environment; this does not establish parent-directory/interpreter/kernel custody.'},
'register_descriptor': {'path': 'register-client.proposed-descriptor.json', 'sha256': sha(descriptor_bytes), 'owner_source_composition': desc.adapter_source,
'decode': 'Actual Warden Descriptor.decode round-trip passed; no Executor admission or tooling invocation performed.'},
'composition': composition,
'verification_inventory': types['1.2']['spec']['verification'],
'rollback_inventory': types['1.2']['spec']['rollback'],
'run_order_and_completion': [
'Accepted exact case source and independently verified six-object native structural materialization before follow-through; a file status or rendered bundle is insufficient.',
'Preserve existing source follow-through order. Delivery Ready and exact Deployment env prerequisite before registry apply. Separate quiet-window restart/readiness after checked registration before real sign-in; registry changed receipt alone is not service activation.',
'Warden rechecks actual caller principal/actor/lane before each admitted dispatch. A session revoked at a step cannot be reused for later steps; owner must define fresh-session or admitted run-envelope grouping without weakening parent-session revocation.',
'Mint must carry separately authenticated broker-grant and parent-session revocation; every completed step requires independently authenticated owner and session evidence.',
'Verification is the complete declared positive/negative inventory plus actual human login/group denial. Reverse only independently confirmed creations, retaining uncertain intents and preserving shared/preexisting objects.'
],
'complete_executable_descriptor_set': False,
'missing_descriptor_steps': [s['step'] for s in composition if s['candidate_descriptor'] is None],
'native_complete': False, 'execution_permitted': False,
})
emit('original-attempt-review.json', {
'schema': 'custodian.registration-original-attempt-review.v1',
'task': 'NK-WP-0048-T15', 'disposition': 'Existing seams inspected; no admitted original-attempt holder/readback matches. Source contract review only; recovery remains refused.',
'actual_source_findings': [
{'source': str(REGISTER), 'symbol': 'build/execute/verify', 'fact': 'records and creation live only in the build closure; original payload publication is injected. Rebuilding the Adapter loses original creation, even if caller retains OwnerResult. Adapter.reconcile is absent.'},
{'source': str(WARDEN / 'src/warden/case_run.py'), 'symbol': 'Journal.save/load', 'fact': 'Durable rows keep attempt_id/operation and exact pins/created history but only digest(evidence identifier), digest(session reference) and digest(grant reference), not original owner payload or recoverable evidence identifier. Journal.load returns StepState and drops persisted attempt context.'},
{'source': str(WARDEN / 'src/warden/case_run.py'), 'symbol': 'Executor.run/reconcile/_attempt', 'fact': 'Crash recovery appends recovered state without invocation/evidence; historical intent rows remain but latest may have no original attempt identity. reconcile creates a fresh attempt identity and calls Adapter.reconcile(new_invocation), supplying no original attempt reference.'},
{'source': str(NK / 'tools/security-case-types/security_case_evidence.py'), 'symbol': 'read_journal/check_steps', 'fact': 'Read-only compatibility projection takes latest rows and explicitly returns native_authenticated false. It is not a holder authenticator or recovery authority.'},
{'source': str(AUDIT / 'audit_core/ingestion.py'), 'symbol': '_read/normalize', 'fact': 'Existing authenticated POST/v1/events and privileged tenant-filtered GET/v1/events/{event_id} can supply custody/readback, but this source review found no registration publisher/class admission or owner authenticator wiring to that surface. Generic custody readiness is not creation attribution.'},
{'source': str(AUDIT / 'audit_core/senders.py'), 'symbol': 'SenderIdentity', 'fact': 'Sender credential restricts allowed source/tenant; may_write does not imply may_read. Evidence defaults attributive; rollback-load-bearing source requires explicit owner declaration and emission atomicity/detection contract.'}
],
'reviewed_existing_holder_candidates': [
{'holder': 'Warden private SQLite Journal', 'use': 'Original intent/sequence lookup from existing immutable history rows after source/owner integrity checks.', 'not_sufficient': 'Has only hashed evidence references and reducer state; it cannot authenticate original creation or supply missing owner bytes.'},
{'holder': 'Actual registration owner publish/authenticate callbacks', 'use': 'The existing fixed injected owner capability is the intended successful-attempt custody seam.', 'not_sufficient': 'No native implementation, named holder or authenticated readback capability is present. The in-test dict authenticator is synthetic only.'},
{'holder': 'Audit Core existing event custody/readback', 'use': 'A concrete existing provider to consider, with source/tenant-scoped sender and separate reader through existing owner admission process.', 'not_sufficient': 'Not selected or admitted for registration; no invented registration sender, token, event authority, runtime verifier or new backend is created.'},
{'holder': 'State Hub progress/request, JSON receipt, current matching registry', 'use': 'Diagnostic/source references only.', 'not_sufficient': 'No creation custody/provenance guarantee. A current matching entry cannot distinguish an original successful write from preexisting or same-byte foreign creation.'}
],
'proposed_recovery_sequence_through_existing_seams': [
'Re-admit exact case/type/descriptor/catalog/acceptance and new current caller principal/actor/lane through normal Executor.admit. No old session is resurrected.',
'Under existing Journal process lock, owner retrieves original intended run attempt from immutable history: exact step/target/pins and original attempt_id/operation. Fresh reconcile attempt_id is distinct and must never substitute for this original identity.',
'The selected admitted owner lookup authenticates exact original netkingdom.keycape-registration.attempt.v1 bytes by original attempt_id and admitted source scope. A case-supplied path, JSON payload or evidence identifier is not a capability. Journal fingerprints only detect correspondence after independent authentication.',
'Validate original payload against original full Invocation, current admission pins, reviewed adapter/helper/checker source, created-only SUCCESS (not NO_CHANGE), exact owner/target, before/after UID/resourceVersion and original session-revocation evidence. Tenant/realm provenance must come from the actual admitted owner/session context; Invocation has no independent tenant field, so do not add a caller label as a substitute.',
'Independently attest original result/session evidence; inspect current native registry through the maintained contained owner helper and match original exact created entry plus unchanged postcreation UID/resourceVersion. Hash equality alone and same client_id are insufficient.',
'Bind lookup result and original provenance to the NEW reconcile attempt and newly revoked parent-session evidence. Preserve original record and current uncertainty. Only after owner-reviewed provenance hydration and normal kernel verification could subsequent independently authorized rollback consider that exact creation.',
'If original receipt was never durably published, is missing/ambiguous/stale, shows NO_CHANGE, mismatches tenant/case/source/principal, or native revision drifted, retain UNCERTAIN and refuse add replay and undo. Do not infer FAILED_BEFORE from missing evidence. Lost-write/readback cases require attended owner reconciliation; no automatic creation attribution is introduced.'
],
'minimal_exact_owner_facts_before_implementation': [
{'owner': 'ops-warden; existing WARDEN-WP-0044-T03', 'fact': 'Approve exact original-intent lookup in existing Journal history and how original Invocation/evidence identifier is handed to a fixed reconciler alongside the fresh reconcile Invocation. Current method supplies only fresh attempt. Preserve historical rows and current no-replay behavior.'},
{'owner': 'NetKingdom registration evidence owner with Warden admission', 'fact': 'Name the actual existing publish/authenticate holder and its bounded authenticated original-attempt readback; supply public interface/source/tenant/principal provenance references and loss/unavailable/ambiguous dispositions. No secret value or new backend is requested.'},
{'owner': 'audit-core only if actual selected holder', 'fact': 'Admit the registration source/event class and load-bearing completeness/intent-to-result custody contract, concrete event-id/original-attempt mapping, normalized-data equality/redaction policy and separate tenant-scoped reader. Generic POST acceptance or counts do not authenticate native creation.'},
{'owner': 'Warden caller-session/revocation owner', 'fact': 'Name actual original and current session evidence purposes and verifier/capability source; original revocation does not authorize a new session, and each new reconcile/rollback attempt must revoke its own parent.'}
],
'targeted_existing_fixture_coverage': {'not_rerun': True, 'source': str(NK / 'sso-mfa/k8s/keycape/test_keycape_registration_adapter.py'),
'existing_cases': ['test_process_loss_does_not_reconstruct_created_authority', 'test_missing_or_tampered_evidence_never_verifies_or_authorizes_undo', 'test_kernel_lost_readback_retains_uncertain_and_refuses_replay_and_undo'],
'limits': 'Current synthetic Kubernetes/dict trust tests prove refusal; none supply original native custody. No duplicate fixture framework or fake native tests added.'},
'implementation_disposition': 'No source guard/adapter change is justified until the listed existing owner contracts identify authority. Existing fail-closed behavior is retained.',
'task_done': False, 'native_acceptance': False, 'retry_authorized': False, 'rollback_authorized': False,
})
# Read-only source selection demonstrates the actual default/version boundaries.
cli = NK / 'tools/security-case-types/security_case_validator.py'
commands = [
[sys.executable, '-B', str(cli), 'render', str(before_paths[1]), '--types', str(NK / 'security-case-types'), '--repos-root', '/home/worsch', '--allow-unimplemented'],
[sys.executable, '-B', str(cli), 'render', str(before_paths[3]), '--types', str(NK / 'security-case-types'), '--version-root', '1.2=' + str(NK / 'security-case-type-revisions/1.2'), '--repos-root', '/home/worsch', '--allow-unimplemented'],
[sys.executable, '-B', str(cli), 'validate-case', str(before_paths[3]), '--types', str(NK / 'security-case-types'), '--version-root', '1.2=' + str(NK / 'security-case-type-revisions/1.2')]
]
results=[]
for command in commands:
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=30, env={'PATH': '/usr/bin:/bin', 'PYTHONDONTWRITEBYTECODE': '1'})
row = {'argv': command, 'returncode': result.returncode, 'stdout_sha256': sha(result.stdout), 'stderr': result.stderr.decode()}
if result.returncode == 0 and command[3] == 'render':
data=json.loads(result.stdout); row.update(type=data['type'], render_digest=data['digest'], execution_permitted=data['execution']['permitted'])
results.append(row)
if [r['returncode'] for r in results] != [0,0,1] or any(r.get('execution_permitted') is not False for r in results[:2]):
raise SystemExit('actual source-selection/refusal behavior changed; inspect results')
after = {str(p): sha(p.read_bytes()) for p in before_paths}
if before != after:
raise SystemExit('reviewed canonical bytes changed during source inspection')
emit('source-verification.json', {'observed_at': datetime.datetime.now(datetime.timezone.utc).isoformat(),
'checks': results, 'canonical_pre_post_hashes_equal': True, 'canonical_hashes': after,
'descriptor_round_trip': True, 'checker_rehash_matches_delivered_artifact': True,
'closed_descriptor_count': 1, 'complete_review_step_count': len(composition),
'native_execution': False, 'tests_added_or_rerun': False,
'knowledge': {'package_version': '0.2.6', 'package_digest': '8d1d6a9d4d07fec7b619618de7dfe2254c1790f85f4198c7fe19db9751c02',
'cards': ['start','evidence'], 'status': 'withheld source changed; direct owner source reviewed, no offline guidance used as authority'}})
audit_path = CUST / 'docs/changes/netkingdom-target-2026-10-17/native-gates-r1/native-gate-audit.json'
if sha(audit_path.read_bytes()) != 'sha256:ab803e795af61fd027f5930d127592316133de38b68a8fe61b89a1f9803a9ff2':
raise SystemExit('immutable prior audit changed')
emit('source-manifest.json', {'sources': list(refs.values()), 'original_audit_immutable': {
'path': str(CUST / 'docs/changes/netkingdom-target-2026-10-17/native-gates-r1/native-gate-audit.json'),
'expected_sha256': 'sha256:ab803e795af61fd027f5930d127592316133de38b68a8fe61b89a1f9803a9ff2'}})
print(json.dumps({'descriptor_sha256': sha(descriptor_bytes), 'descriptor_owner_source': desc.adapter_source,
'complete_step_inventory': len(composition), 'source_checks': [r['returncode'] for r in results],
'native_authority': False}))

View file

@ -0,0 +1,402 @@
{
"checker": {
"bytes": 13633409,
"native_custody_admitted": false,
"path": "/tmp/nk-checker-environment-r2-rebuild/keycape",
"runtime_contract": "Current owner adapter rehashes source/file, snapshots exact checker into sealed memfd, executes same snapshot for live/proposed checks with empty environment; this does not establish parent-directory/interpreter/kernel custody.",
"sha256": "sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5"
},
"complete_executable_descriptor_set": false,
"composition": [
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "net-kingdom",
"dispatch_permitted": false,
"existing_seam": "identity-provisioner governed journal T14 with delivered PostgreSQL T21",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"native dedicated CNPG consumer, checkpoint holder and backup/lost-store continuity",
"authoritative tenant/case/source/principal callbacks",
"all LDAP writers fenced or provider CAS/ABA exclusion",
"exact owner adapter/source/descriptor and revocation evidence; existing legacy ensure/revoke is not created-only undo"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "net-kingdom",
"rollback_requirement": "Only independently authenticated created groups/memberships; preserve shared/preexisting membership and unresolved intents.",
"source_order": 1,
"source_step": {
"attended": true,
"attended_justification": "The provisioner's only HTTP credential is user-engine's runtime token, and its NetworkPolicy admits only user-engine pods. A proxy lane 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.",
"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",
"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)",
"id": "ensure-groups",
"lane": "key-cape-oidc-login",
"owner": "net-kingdom",
"value_handling": "none",
"warden_executes": false
},
"step": "ensure-groups"
},
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "railiance-platform",
"dispatch_permitted": false,
"existing_seam": "scripts/keycape_client_secret_generate.py; RPF-WP-0054 and existing broker lane",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"fixed kernel Adapter/Descriptor for exact admitted case/type and broker source",
"authoritative case materialization receipt and original CAS0 uncertainty reconciliation",
"independent broker-grant AND parent-session revocation receipts for exact current attempt"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "railiance-platform",
"rollback_requirement": "Never regenerate after uncertain write; read-only metadata reconciliation does not establish creation or retry authority; owner custody delete only if exact created-only entitlement.",
"source_order": 2,
"source_step": {
"attended": false,
"auth": "the caller's broker grant for the case's KV path, through its lane; the value is generated in custody and never returned",
"entry_point": "railiance-platform credential broker: generate a client secret inside custody at bao:platform/workloads/keycape/{client_id}",
"id": "mint-secret",
"lane": "keycape-client-secret-generate",
"owner": "railiance-platform",
"value_handling": "generated_in_custody",
"warden_executes": true,
"when": "client_type == confidential"
},
"step": "mint-secret"
},
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "railiance-platform",
"dispatch_permitted": false,
"existing_seam": "existing ESO delivery/role and structural materialization boundary",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"exact delivery object UID/ownerReference prestate and admitted owner adapter",
"current Ready status/readback without value access",
"independent cleanup/revocation receipt and owner custody identity"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "railiance-platform",
"rollback_requirement": "Delete only authenticated case-created delivery objects, preserve preexisting target and shared resources.",
"source_order": 3,
"source_step": {
"attended": false,
"auth": "railiance-platform ESO delivery through role external-secrets-keycape-{client_id}; no value leaves custody",
"entry_point": "ExternalSecret sso/keycape-{client_id}-client (key client-secret) from bao:platform/workloads/keycape/{client_id}",
"id": "deliver-secret",
"owner": "railiance-platform",
"ready_check": "the delivery for sso/keycape-{client_id}-client reports Ready=True (status only, no value read)",
"value_handling": "none",
"warden_executes": false,
"when": "client_type == confidential"
},
"step": "deliver-secret"
},
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "net-kingdom",
"dispatch_permitted": false,
"existing_seam": "existing sso/keycape Deployment prerequisite checked by keycape-client.py; T12",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"reviewed fixed exact Deployment UID/resourceVersion/env binding update adapter",
"created-only prestate/readback and owner evidence/session capabilities",
"separately reviewed quiet-window restart/readiness procedure; registry helper only reports restart_required"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "net-kingdom",
"rollback_requirement": "Restore only exact case-created env binding under current revision; a whole Deployment rollback or deleting preexisting env is not admitted.",
"source_order": 4,
"source_step": {
"attended": true,
"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.",
"auth": "operator kube credentials for namespace sso",
"entry_point": "patch Deployment sso/keycape: env KEYCAPE_{client_id:env}_CLIENT_SECRET from sso/keycape-{client_id}-client",
"id": "bind-env",
"lane": "key-cape-oidc-login",
"owner": "net-kingdom",
"value_handling": "none",
"warden_executes": false,
"when": "client_type == confidential"
},
"step": "bind-env"
},
{
"candidate_descriptor": {
"actor": "human",
"adapter": "net-kingdom/keycape-registration@v1",
"adapter_source": "sha256:7db1caa4d1e73e8f65b6744af53bcdce628bcd86732f74bdc125f85c531a22d1",
"allowed_created": [
"keycape-client"
],
"effect": "change",
"lane": "key-cape-oidc-login",
"owner": "net-kingdom",
"retry_safe": false,
"revocation_scopes": [
"parent-session"
],
"step": "register-client",
"target_parameter": "client_id",
"version": "warden.case.execution.v1"
},
"candidate_descriptor_digest": "sha256:1b86e9032845ec35a58d88a9f1108dbb7d8cee0c9c9176d4a694b893d9d7a3fa",
"declared_owner": "net-kingdom",
"dispatch_permitted": false,
"existing_seam": "keycape-registration-adapter.py build/publish/authenticate/revoke_session injection seam",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"actual admitted durable owner publisher/authenticator and exact parent-session revoker",
"native executable storage/provenance and exact descriptor/type source admission",
"T15 original-attempt recovery contract; fresh adapter intentionally cannot undo prior-process creation"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "net-kingdom",
"rollback_requirement": "Same-process authenticated successful creation only; exact original entry and unchanged postcreation UID/resourceVersion; post-restart stays refused.",
"source_order": 5,
"source_step": {
"attended": true,
"attended_justification": "The live KeyCape client registry is a Kubernetes Secret, and agents do not read or write Secrets. Until KeyCape loads clients from a non-secret registry with secrets referenced from custody, one attended operator session applies the rendered registration. ops-warden groups all attended steps of a run into that one session. KeyCape loads clients at startup and keeps login, 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) before the restart: a refused entry stops the single replica and every client loses sign-in (R1).",
"auth": "operator write access to the live KeyCape client registry in namespace sso",
"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)",
"id": "register-client",
"lane": "key-cape-oidc-login",
"owner": "net-kingdom",
"value_handling": "none",
"warden_executes": false
},
"step": "register-client"
},
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "{consumer_owner_repo}",
"dispatch_permitted": false,
"existing_seam": "acknowledged source1.2 dedicated SA/namespace SecretStore/ExternalSecret composition",
"exists_in_default_1_1": false,
"missing_exact_owner_facts": [
"actual installed ESO TokenRequest/RBAC compatibility and consumer owner admission",
"fixed owner adapter/descriptor for exact identities with created/preexisting readback",
"receiver evidence for Ready status and case-issued token revocation/expiry"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "railiance-apps for Forgejo",
"rollback_requirement": "Revert consumer reference first; delete only authenticated created UID/ownerReference resources; SA/Store deletion alone does not immediately revoke OpenBao tokens.",
"source_order": 6,
"source_step": {
"attended": false,
"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",
"entry_point": "Owner applies 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.",
"id": "deliver-consumer-secret",
"owner": "{consumer_owner_repo}",
"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.",
"value_handling": "none",
"warden_executes": false,
"when": "client_type == confidential"
},
"step": "deliver-consumer-secret"
},
{
"candidate_descriptor": null,
"candidate_descriptor_digest": null,
"declared_owner": "{consumer_owner_repo}",
"dispatch_permitted": false,
"existing_seam": "consumer owner OIDC configuration and groups enforcement path",
"exists_in_default_1_1": true,
"missing_exact_owner_facts": [
"owner exact deployment/source adapter/descriptor and accepted issuer/client/delivery binding",
"actual human login/group-denial and public authorization/MFA pin verifications",
"rollback and native receipt/custody acceptance"
],
"native_owner_assent": false,
"resolved_first_consumer_owner": "railiance-apps for Forgejo",
"rollback_requirement": "Remove only this case-created OIDC source; preserve shared/preexisting auth sources and consumer state.",
"source_order": 7,
"source_step": {
"attended": false,
"auth": "the consumer owner's own deployment path",
"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",
"id": "hand-over",
"owner": "{consumer_owner_repo}",
"value_handling": "none",
"warden_executes": false
},
"step": "hand-over"
}
],
"execution_permitted": false,
"missing_descriptor_steps": [
"ensure-groups",
"mint-secret",
"deliver-secret",
"bind-env",
"deliver-consumer-secret",
"hand-over"
],
"native_complete": false,
"proposed_version_selection": {
"canonical_case": "Keep1.1 accepted history unchanged and1.2 example proposed without acceptance fields.",
"classification": "Exact closed execution references and any changed trust/materialization/authentication must be classified by the existing owner; changed trust/authentication requires informed-decision acknowledgment, never self-classified as harmless validation.",
"default_loader": "Keep canonical1.1 unchanged; select1.2 only through existing explicit version-root option for source review.",
"descriptor_revision": "Do not edit acknowledged source1.1/1.2 in place or inherit old acknowledgment for new descriptor bytes. Allocate the exact successor revision/version through NetKingdom canon section6 after the complete owner-reviewed set exists.",
"first_consumer": "Forgejo",
"review_base": "explicit source-only oidc-browser-relying-party@1.2",
"why": "Its dedicated consumer SA/ESO authentication boundary expresses the reviewed six-object structural design;1.1 does not."
},
"purpose": "Review inventory only; this is not a Warden descriptor bundle or accepted SecurityCaseType.",
"register_descriptor": {
"decode": "Actual Warden Descriptor.decode round-trip passed; no Executor admission or tooling invocation performed.",
"owner_source_composition": "sha256:7db1caa4d1e73e8f65b6744af53bcdce628bcd86732f74bdc125f85c531a22d1",
"path": "register-client.proposed-descriptor.json",
"sha256": "sha256:1b86e9032845ec35a58d88a9f1108dbb7d8cee0c9c9176d4a694b893d9d7a3fa"
},
"rollback_inventory": [
{
"action": "remove the OIDC source for {client_id} from {consuming_service} (owner {consumer_owner_repo})",
"reverses": "hand-over"
},
{
"action": "After reverting consumer secret reference, delete only authenticated created ExternalSecret/owned target by UID and ownerReference, then SecretStore and dedicated SA; preserve preexisting-matched resources and never delete a shared target. Retain audit and ownership receipts; removing SecretStore/SA alone is not immediate OpenBao token revocation.",
"reverses": "deliver-consumer-secret",
"when": "client_type == confidential"
},
{
"action": "keycape-client.py apply --operation remove for {client_id}",
"reverses": "register-client"
},
{
"action": "remove env KEYCAPE_{client_id:env}_CLIENT_SECRET from Deployment sso/keycape, after register-client is reversed",
"reverses": "bind-env",
"when": "client_type == confidential"
},
{
"action": "delete ExternalSecret sso/keycape-{client_id}-client and its target",
"reverses": "deliver-secret",
"when": "client_type == confidential"
},
{
"action": "covered by client-secret-path: one metadata delete, after deliver-secret is reversed",
"reverses": "mint-secret",
"when": "client_type == confidential"
},
{
"action": "identity-provisioner revoke_service_groups inside the provisioner pod (attended, as ensure-groups) with the case's memberships; delete_if_empty only if no other case uses {access_groups}",
"reverses": "ensure-groups"
},
{
"action": "delete metadata and all versions at platform/workloads/keycape/{client_id}, after the ExternalSecret is gone (this also reverses mint-secret)",
"reverses": "client-secret-path",
"when": "client_type == confidential"
},
{
"action": "delete Kubernetes-auth role external-secrets-keycape-{client_id}",
"reverses": "eso-role",
"when": "client_type == confidential"
},
{
"action": "delete policy workload-kv-read-keycape-{client_id}-eso, after eso-role",
"reverses": "keycape-reader-policy",
"when": "client_type == confidential"
},
{
"action": "Delete only this case-created role external-secrets-keycape-{client_id}-{consuming_service}, before deleting consumer-reader-policy; revoke case-issued OpenBao tokens or prove expiration before declaring deactivation.",
"reverses": "consumer-eso-role",
"when": "client_type == confidential"
},
{
"action": "delete policy workload-kv-read-keycape-{client_id}-{consuming_service}",
"reverses": "consumer-reader-policy",
"when": "client_type == confidential"
},
{
"action": "remove catalog entry {consuming_service}-keycape-client",
"reverses": "catalog-entry"
}
],
"run_order_and_completion": [
"Accepted exact case source and independently verified six-object native structural materialization before follow-through; a file status or rendered bundle is insufficient.",
"Preserve existing source follow-through order. Delivery Ready and exact Deployment env prerequisite before registry apply. Separate quiet-window restart/readiness after checked registration before real sign-in; registry changed receipt alone is not service activation.",
"Warden rechecks actual caller principal/actor/lane before each admitted dispatch. A session revoked at a step cannot be reused for later steps; owner must define fresh-session or admitted run-envelope grouping without weakening parent-session revocation.",
"Mint must carry separately authenticated broker-grant and parent-session revocation; every completed step requires independently authenticated owner and session evidence.",
"Verification is the complete declared positive/negative inventory plus actual human login/group denial. Reverse only independently confirmed creations, retaining uncertain intents and preserving shared/preexisting objects."
],
"schema": "custodian.registration-descriptor-review.v1",
"source_versions": {
"1.1": {
"machine_descriptor_map_present": false,
"status": "acknowledged",
"step_count": 6
},
"1.2": {
"machine_descriptor_map_present": false,
"status": "acknowledged",
"step_count": 7
}
},
"verification_inventory": [
{
"check": "GET {issuer}/authorize with client {client_id} and each of {redirect_uris} returns the login page",
"expect": "present",
"id": "authorize-accepts-redirects",
"reads_secret_value": false
},
{
"check": "GET {issuer}/authorize with client {client_id} and an unregistered redirect returns an OAuth error",
"expect": "deny",
"id": "authorize-refuses-other-redirect",
"reads_secret_value": false
},
{
"check": "a default-only OpenBao identity has no read capability on bao:platform/workloads/keycape/{client_id}",
"expect": "deny",
"id": "custody-denied-to-default",
"reads_secret_value": false,
"when": "client_type == confidential"
},
{
"check": "policy workload-kv-read-keycape-{client_id}-{consuming_service} grants read on bao:platform/workloads/keycape/{client_id} (capabilities check only)",
"expect": "allow",
"id": "custody-allowed-to-consumer",
"reads_secret_value": false,
"when": "client_type == confidential"
},
{
"check": "LLDAP groups {access_groups} exist, with exactly the memberships of the accepted case added",
"expect": "present",
"id": "groups-present",
"reads_secret_value": false
},
{
"check": "{consuming_service}'s OIDC source for {client_id} (owner {consumer_owner_repo}) requires one of {access_groups} in the groups claim (configuration read, no secret value)",
"expect": "present",
"id": "consumer-enforces-groups",
"reads_secret_value": false
},
{
"check": "the delivery for sso/keycape-{client_id}-client reports Ready=True (status only)",
"expect": "present",
"id": "secret-delivered",
"reads_secret_value": false,
"when": "client_type == confidential"
},
{
"check": "keycape-client.py inspect for {client_id} shows the MFA pin on the registered client (non-secret client view)",
"expect": "present",
"id": "mfa-pinned",
"reads_secret_value": false,
"when": "mfa_required == true"
},
{
"check": "{consumer_namespace} SecretStore openbao-keycape-{client_id}-consumer and ExternalSecret {consuming_service}-netkingdom-oidc-client Ready=True, exact dedicated SA/audience role binding, fixed CLIENT_SECRET mapping; no Secret value read",
"expect": "present",
"id": "consumer-secret-delivered",
"reads_secret_value": false,
"when": "client_type == confidential"
}
]
}

View file

@ -0,0 +1,44 @@
{
"files": [
{
"path": "assemble_review.py",
"sha256": "554cc213824098e3b3599d9e801330a28aea72f19336b7492adacebbf84d62f4",
"bytes": 25834
},
{
"path": "descriptor-composition.json",
"sha256": "e097abe5f7b149e5688850cfb0ef7793a1b3206388b52f069b51137f6ca92170",
"bytes": 22885
},
{
"path": "original-attempt-review.json",
"sha256": "d0df5c45f53f7d61ac54589e55b09f1c9cff098ade63e5853e434ced8f83fe3c",
"bytes": 8753
},
{
"path": "register-client.proposed-descriptor.json",
"sha256": "1b86e9032845ec35a58d88a9f1108dbb7d8cee0c9c9176d4a694b893d9d7a3fa",
"bytes": 413
},
{
"path": "source-manifest.json",
"sha256": "33c475045cfe958bab5b7545783dea497427373448c83c1859888550e965c104",
"bytes": 10433
},
{
"path": "source-verification.json",
"sha256": "2ed179ecdcda85a29b0e86e7e19274fdce408d154e4e79f61bbccc80304c8dfd",
"bytes": 4054
},
{
"path": "summary.json",
"sha256": "3ede75b2d55190fb41236a92c4d2ed157be04c819ab5226e5d9c404d87d51bdd",
"bytes": 1878
},
{
"path": "work-record-proposal.json",
"sha256": "0aec5c8a8473232d1800c6c3b70661dd1412271e57effe0d7f19242201897134",
"bytes": 3009
}
]
}

View file

@ -0,0 +1,101 @@
{
"actual_source_findings": [
{
"fact": "records and creation live only in the build closure; original payload publication is injected. Rebuilding the Adapter loses original creation, even if caller retains OwnerResult. Adapter.reconcile is absent.",
"source": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/keycape-registration-adapter.py",
"symbol": "build/execute/verify"
},
{
"fact": "Durable rows keep attempt_id/operation and exact pins/created history but only digest(evidence identifier), digest(session reference) and digest(grant reference), not original owner payload or recoverable evidence identifier. Journal.load returns StepState and drops persisted attempt context.",
"source": "/home/worsch/ops-warden/src/warden/case_run.py",
"symbol": "Journal.save/load"
},
{
"fact": "Crash recovery appends recovered state without invocation/evidence; historical intent rows remain but latest may have no original attempt identity. reconcile creates a fresh attempt identity and calls Adapter.reconcile(new_invocation), supplying no original attempt reference.",
"source": "/home/worsch/ops-warden/src/warden/case_run.py",
"symbol": "Executor.run/reconcile/_attempt"
},
{
"fact": "Read-only compatibility projection takes latest rows and explicitly returns native_authenticated false. It is not a holder authenticator or recovery authority.",
"source": "/home/worsch/net-kingdom/tools/security-case-types/security_case_evidence.py",
"symbol": "read_journal/check_steps"
},
{
"fact": "Existing authenticated POST/v1/events and privileged tenant-filtered GET/v1/events/{event_id} can supply custody/readback, but this source review found no registration publisher/class admission or owner authenticator wiring to that surface. Generic custody readiness is not creation attribution.",
"source": "/home/worsch/audit-core/audit_core/ingestion.py",
"symbol": "_read/normalize"
},
{
"fact": "Sender credential restricts allowed source/tenant; may_write does not imply may_read. Evidence defaults attributive; rollback-load-bearing source requires explicit owner declaration and emission atomicity/detection contract.",
"source": "/home/worsch/audit-core/audit_core/senders.py",
"symbol": "SenderIdentity"
}
],
"disposition": "Existing seams inspected; no admitted original-attempt holder/readback matches. Source contract review only; recovery remains refused.",
"implementation_disposition": "No source guard/adapter change is justified until the listed existing owner contracts identify authority. Existing fail-closed behavior is retained.",
"minimal_exact_owner_facts_before_implementation": [
{
"fact": "Approve exact original-intent lookup in existing Journal history and how original Invocation/evidence identifier is handed to a fixed reconciler alongside the fresh reconcile Invocation. Current method supplies only fresh attempt. Preserve historical rows and current no-replay behavior.",
"owner": "ops-warden; existing WARDEN-WP-0044-T03"
},
{
"fact": "Name the actual existing publish/authenticate holder and its bounded authenticated original-attempt readback; supply public interface/source/tenant/principal provenance references and loss/unavailable/ambiguous dispositions. No secret value or new backend is requested.",
"owner": "NetKingdom registration evidence owner with Warden admission"
},
{
"fact": "Admit the registration source/event class and load-bearing completeness/intent-to-result custody contract, concrete event-id/original-attempt mapping, normalized-data equality/redaction policy and separate tenant-scoped reader. Generic POST acceptance or counts do not authenticate native creation.",
"owner": "audit-core only if actual selected holder"
},
{
"fact": "Name actual original and current session evidence purposes and verifier/capability source; original revocation does not authorize a new session, and each new reconcile/rollback attempt must revoke its own parent.",
"owner": "Warden caller-session/revocation owner"
}
],
"native_acceptance": false,
"proposed_recovery_sequence_through_existing_seams": [
"Re-admit exact case/type/descriptor/catalog/acceptance and new current caller principal/actor/lane through normal Executor.admit. No old session is resurrected.",
"Under existing Journal process lock, owner retrieves original intended run attempt from immutable history: exact step/target/pins and original attempt_id/operation. Fresh reconcile attempt_id is distinct and must never substitute for this original identity.",
"The selected admitted owner lookup authenticates exact original netkingdom.keycape-registration.attempt.v1 bytes by original attempt_id and admitted source scope. A case-supplied path, JSON payload or evidence identifier is not a capability. Journal fingerprints only detect correspondence after independent authentication.",
"Validate original payload against original full Invocation, current admission pins, reviewed adapter/helper/checker source, created-only SUCCESS (not NO_CHANGE), exact owner/target, before/after UID/resourceVersion and original session-revocation evidence. Tenant/realm provenance must come from the actual admitted owner/session context; Invocation has no independent tenant field, so do not add a caller label as a substitute.",
"Independently attest original result/session evidence; inspect current native registry through the maintained contained owner helper and match original exact created entry plus unchanged postcreation UID/resourceVersion. Hash equality alone and same client_id are insufficient.",
"Bind lookup result and original provenance to the NEW reconcile attempt and newly revoked parent-session evidence. Preserve original record and current uncertainty. Only after owner-reviewed provenance hydration and normal kernel verification could subsequent independently authorized rollback consider that exact creation.",
"If original receipt was never durably published, is missing/ambiguous/stale, shows NO_CHANGE, mismatches tenant/case/source/principal, or native revision drifted, retain UNCERTAIN and refuse add replay and undo. Do not infer FAILED_BEFORE from missing evidence. Lost-write/readback cases require attended owner reconciliation; no automatic creation attribution is introduced."
],
"retry_authorized": false,
"reviewed_existing_holder_candidates": [
{
"holder": "Warden private SQLite Journal",
"not_sufficient": "Has only hashed evidence references and reducer state; it cannot authenticate original creation or supply missing owner bytes.",
"use": "Original intent/sequence lookup from existing immutable history rows after source/owner integrity checks."
},
{
"holder": "Actual registration owner publish/authenticate callbacks",
"not_sufficient": "No native implementation, named holder or authenticated readback capability is present. The in-test dict authenticator is synthetic only.",
"use": "The existing fixed injected owner capability is the intended successful-attempt custody seam."
},
{
"holder": "Audit Core existing event custody/readback",
"not_sufficient": "Not selected or admitted for registration; no invented registration sender, token, event authority, runtime verifier or new backend is created.",
"use": "A concrete existing provider to consider, with source/tenant-scoped sender and separate reader through existing owner admission process."
},
{
"holder": "State Hub progress/request, JSON receipt, current matching registry",
"not_sufficient": "No creation custody/provenance guarantee. A current matching entry cannot distinguish an original successful write from preexisting or same-byte foreign creation.",
"use": "Diagnostic/source references only."
}
],
"rollback_authorized": false,
"schema": "custodian.registration-original-attempt-review.v1",
"targeted_existing_fixture_coverage": {
"existing_cases": [
"test_process_loss_does_not_reconstruct_created_authority",
"test_missing_or_tampered_evidence_never_verifies_or_authorizes_undo",
"test_kernel_lost_readback_retains_uncertain_and_refuses_replay_and_undo"
],
"limits": "Current synthetic Kubernetes/dict trust tests prove refusal; none supply original native custody. No duplicate fixture framework or fake native tests added.",
"not_rerun": true,
"source": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py"
},
"task": "NK-WP-0048-T15",
"task_done": false
}

View file

@ -0,0 +1 @@
{"actor":"human","adapter":"net-kingdom/keycape-registration@v1","adapter_source":"sha256:7db1caa4d1e73e8f65b6744af53bcdce628bcd86732f74bdc125f85c531a22d1","allowed_created":["keycape-client"],"effect":"change","lane":"key-cape-oidc-login","owner":"net-kingdom","retry_safe":false,"revocation_scopes":["parent-session"],"step":"register-client","target_parameter":"client_id","version":"warden.case.execution.v1"}

View file

@ -0,0 +1,323 @@
{
"original_audit_immutable": {
"expected_sha256": "sha256:ab803e795af61fd027f5930d127592316133de38b68a8fe61b89a1f9803a9ff2",
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/native-gates-r1/native-gate-audit.json"
},
"sources": [
{
"bytes": 16474,
"path": "/home/worsch/net-kingdom/security-case-types/oidc-browser-relying-party/type.yaml",
"sha256": "sha256:f705c64e4875e9b8e18a912fb51c135e77898926d6a451f5cb74ab3c0cbe4d1c"
},
{
"bytes": 1717,
"path": "/home/worsch/net-kingdom/security-cases/forgejo-netkingdom-oidc.yaml",
"sha256": "sha256:bcc2c6d5bae0d28242b3cdb71e74d8ca297c2afe04766b55d53597f86893351d"
},
{
"bytes": 19052,
"path": "/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/type.yaml",
"sha256": "sha256:9e60ff569fb0d860a2bbde7bbb0991a54d4b0688f62b56df0fa5d161fd624578"
},
{
"bytes": 722,
"path": "/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml",
"sha256": "sha256:1c868c1da7d9077fae97bc6bc029706ec3dc418cfeaae30dc0f92b5b4ba6f2ab"
},
{
"bytes": 4214,
"path": "/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/decision/acknowledgment.json",
"sha256": "sha256:2dcc220febf125a17b3769f7014f18b63979d7121e0f7056a2b0d8b1ae6031b0"
},
{
"bytes": 60503,
"path": "/home/worsch/net-kingdom/workplans/NK-WP-0048-security-case-types.md",
"sha256": "sha256:b737bfae4802c122b21619695a169d7d082672af96314b1709860dd5aff2a60f"
},
{
"bytes": 11186,
"path": "/home/worsch/net-kingdom/AGENTS.md",
"sha256": "sha256:95158b1d5c15e6cf8be980f5c0e3b48aeef252654846273887f40516b3fa6a78"
},
{
"bytes": 13132,
"path": "/home/worsch/ops-warden/AGENTS.md",
"sha256": "sha256:aa03031516b886b254d8c4b1fafa160c063c74aa0115ba51af3dd7326dccfad6"
},
{
"bytes": 12019,
"path": "/home/worsch/net-kingdom/SECURITY-COMPANION.md",
"sha256": "sha256:06374445ca888549f1bf79527d1345d94918d7a7ec363160d8427d0e7a31d643"
},
{
"bytes": 23003,
"path": "/home/worsch/ops-warden/INTENT.md",
"sha256": "sha256:3e9382fefa52ee0970dfac133cc799656e5034760b26dccc1bf9bab65fc538d9"
},
{
"bytes": 10233,
"path": "/home/worsch/net-kingdom/canon/standards/security-case-types_v0.1.md",
"sha256": "sha256:a4fda906d5138d2594a1f8d047c7c28e1cdf96b1eae051f543b9a5e5852bcb5e"
},
{
"bytes": 8821,
"path": "/home/worsch/net-kingdom/docs/security-case-execution-owner-review.md",
"sha256": "sha256:0f1637bfddbbdf50d336974791b7fbf4646efe7e32ca04beb3bf52effd0a28e6"
},
{
"bytes": 5229,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/registration-adapter.md",
"sha256": "sha256:2fadcbd28e34566173428bcb92e42ac464ef73c03909072d0fc2ee988b175e29"
},
{
"bytes": 8813,
"path": "/home/worsch/ops-warden/docs/security-case-execution-kernel-v1.md",
"sha256": "sha256:0eb563dbaea739fba928d04708c2c2bdac592783bbe68e1271041b0d1b1994cb"
},
{
"bytes": 13901,
"path": "/home/worsch/ops-warden/workplans/WARDEN-WP-0044-security-case-follow-through.md",
"sha256": "sha256:1df57687200f6a60a2a6f26a4066ce1e93ae663fc4e43db3884d04dc1d6e874e"
},
{
"bytes": 13867,
"path": "/home/worsch/audit-core/docs/audit-backend-contract.md",
"sha256": "sha256:a80ebeac99bd88b1ec55a2c0c3a25220749908e237d7d3c048f7e867bb0a9b1a"
},
{
"bytes": 1917,
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/browser-checker-environment-r2/build-receipt.json",
"sha256": "sha256:1a3bb61a958afdbe46664384963a53e275a5a6b53741bda9244e28f58b4453ff"
},
{
"bytes": 1073,
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/browser-checker-artifact-next/coordinator-build-review.json",
"sha256": "sha256:621702e9149d59fa187af2f6e5d140dab3b261bbe25a02bbc1f0ac5f0731b233"
},
{
"bytes": 11813,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/keycape-registration-adapter.py",
"sha256": "sha256:d7e3643cc794223dfaa310775eacbbeb4d353f9382e4481322d704d6b7ab1c51",
"symbols": {}
},
{
"bytes": 27272,
"path": "/home/worsch/ops-warden/src/warden/case_run.py",
"sha256": "sha256:afb5ce9c59b9748f85c9f1d4af04b255087632c58de8dcd8c9426fc1ed4db068",
"symbols": {
"Executor": {
"end_line": 710,
"line": 320
},
"Journal": {
"end_line": 317,
"line": 183
},
"_attempt": {
"end_line": 575,
"line": 566
},
"_result": {
"end_line": 532,
"line": 490
},
"admit": {
"end_line": 488,
"line": 344
},
"load": {
"end_line": 274,
"line": 221
},
"reconcile": {
"end_line": 710,
"line": 646
},
"rollback": {
"end_line": 644,
"line": 613
},
"run": {
"end_line": 611,
"line": 577
},
"save": {
"end_line": 317,
"line": 276
}
}
},
{
"bytes": 5456,
"path": "/home/worsch/ops-warden/src/warden/case_receipt_state.py",
"sha256": "sha256:a2cda7f187e77bd76d4d209505638de44a587fae0bc033ec75c23ee9ea9f73bc",
"symbols": {
"begin_rollback": {
"end_line": 138,
"line": 134
},
"recover": {
"end_line": 120,
"line": 114
}
}
},
{
"bytes": 4438,
"path": "/home/worsch/ops-warden/src/warden/case_inputs.py",
"sha256": "sha256:1334b0cd9897e763cfea2d306e997c659f3f284ecc3f9612140c2104835da7c7",
"symbols": {
"BrowserInputs": {
"end_line": 98,
"line": 42
},
"target": {
"end_line": 98,
"line": 48
}
}
},
{
"bytes": 11783,
"path": "/home/worsch/net-kingdom/tools/security-case-types/security_case_evidence.py",
"sha256": "sha256:da8efa59c52ad73283397ebe639ae259d0cb9c6348b5cb829135c24230dcdc75",
"symbols": {
"audit": {
"end_line": 205,
"line": 193
},
"check_steps": {
"end_line": 190,
"line": 131
},
"read_journal": {
"end_line": 128,
"line": 103
}
}
},
{
"bytes": 36729,
"path": "/home/worsch/net-kingdom/tools/security-case-types/security_case_validator.py",
"sha256": "sha256:1bcc62e9bc374c711363295549f3cd5bb0b32952671ed4b08fddc7f74742959b",
"symbols": {
"load_type": {
"end_line": 452,
"line": 419
},
"validate_execution_descriptors": {
"end_line": 215,
"line": 194
}
}
},
{
"bytes": 17073,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py",
"sha256": "sha256:cc5956d811db031e437ebca60bf70eb41177c87db75cc9478fe84075ad224464",
"symbols": {
"test_kernel_lost_readback_retains_uncertain_and_refuses_replay_and_undo": {
"end_line": 305,
"line": 289
},
"test_process_loss_does_not_reconstruct_created_authority": {
"end_line": 215,
"line": 209
}
}
},
{
"bytes": 38172,
"path": "/home/worsch/audit-core/audit_core/ingestion.py",
"sha256": "sha256:f5a225a204cf77d0ac5aa49298f2e4acd6f559e47fa4f19407672486537e97c6",
"symbols": {
"_read": {
"end_line": 333,
"line": 247
},
"normalize": {
"end_line": 679,
"line": 625
}
}
},
{
"bytes": 20214,
"path": "/home/worsch/audit-core/audit_core/senders.py",
"sha256": "sha256:bc091ce63dc2cd0fcdc9f26423b258cb94a6db863daced6706c11dba3bbf67e1",
"symbols": {
"SenderIdentity": {
"end_line": 185,
"line": 44
},
"evidence_declaration": {
"end_line": 156,
"line": 139
}
}
},
{
"bytes": 7438,
"path": "/home/worsch/audit-core/audit_core/interface.py",
"sha256": "sha256:4ecc5f6bdfe04181cce02ec5547fbfded0101868085909f315ea7d4c9eb9b573",
"symbols": {
"AcceptResult": {
"end_line": 146,
"line": 142
},
"AuditEvent": {
"end_line": 117,
"line": 82
}
}
},
{
"bytes": 9872,
"path": "/home/worsch/railiance-platform/scripts/keycape_client_secret_generate.py",
"sha256": "sha256:9576cd211cfc06526ec4cc9bd0a5b06f0f59287a68931bb2d6e3592a951ddc7d",
"symbols": {
"check_case": {
"end_line": 123,
"line": 98
},
"record_state_hub": {
"end_line": 191,
"line": 181
},
"run": {
"end_line": 178,
"line": 126
}
}
},
{
"bytes": 15565,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/keycape-client.py",
"sha256": "sha256:4b63161cf3365d34dd684a3116e2c935baaf7f6aa4b30983f6883546db3d6591",
"symbols": {}
},
{
"bytes": 7017,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/portal-client-rollout.py",
"sha256": "sha256:158e1d36eb881cdd0a2eda91b472adea5e8fde5061e00d26dda368580aeb871f",
"symbols": {}
},
{
"bytes": 13089,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/openbao-client-config.py",
"sha256": "sha256:1b908b4c36134212d78f9fbe7a2a201eb3ced06d31bb1dcea4a59d80689d84b1",
"symbols": {}
},
{
"bytes": 1691,
"path": "/home/worsch/net-kingdom/sso-mfa/k8s/keycape/register-user-engine-portal.py",
"sha256": "sha256:67173edc44f5457e7b6a3e0fb2321b398159cfce5dea8ead01eabf835fb38d76",
"symbols": {}
},
{
"bytes": 13633409,
"path": "/tmp/nk-checker-environment-r2-rebuild/keycape",
"sha256": "sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5"
}
]
}

View file

@ -0,0 +1,87 @@
{
"canonical_hashes": {
"/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/decision/acknowledgment.json": "sha256:2dcc220febf125a17b3769f7014f18b63979d7121e0f7056a2b0d8b1ae6031b0",
"/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml": "sha256:1c868c1da7d9077fae97bc6bc029706ec3dc418cfeaae30dc0f92b5b4ba6f2ab",
"/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/type.yaml": "sha256:9e60ff569fb0d860a2bbde7bbb0991a54d4b0688f62b56df0fa5d161fd624578",
"/home/worsch/net-kingdom/security-case-types/oidc-browser-relying-party/type.yaml": "sha256:f705c64e4875e9b8e18a912fb51c135e77898926d6a451f5cb74ab3c0cbe4d1c",
"/home/worsch/net-kingdom/security-cases/forgejo-netkingdom-oidc.yaml": "sha256:bcc2c6d5bae0d28242b3cdb71e74d8ca297c2afe04766b55d53597f86893351d",
"/home/worsch/net-kingdom/workplans/NK-WP-0048-security-case-types.md": "sha256:b737bfae4802c122b21619695a169d7d082672af96314b1709860dd5aff2a60f"
},
"canonical_pre_post_hashes_equal": true,
"checker_rehash_matches_delivered_artifact": true,
"checks": [
{
"argv": [
"/usr/bin/python3",
"-B",
"/home/worsch/net-kingdom/tools/security-case-types/security_case_validator.py",
"render",
"/home/worsch/net-kingdom/security-cases/forgejo-netkingdom-oidc.yaml",
"--types",
"/home/worsch/net-kingdom/security-case-types",
"--repos-root",
"/home/worsch",
"--allow-unimplemented"
],
"execution_permitted": false,
"render_digest": "sha256:e64b56e4590b57b858303fcda1a474693e3dd821bc83df26646fe78fc345498a",
"returncode": 0,
"stderr": "",
"stdout_sha256": "sha256:186461a1dc2d587ccc0cc9ea6e51f05214d6cfe94f4aa0764e3150ab197ad3cf",
"type": "oidc-browser-relying-party@1.1"
},
{
"argv": [
"/usr/bin/python3",
"-B",
"/home/worsch/net-kingdom/tools/security-case-types/security_case_validator.py",
"render",
"/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml",
"--types",
"/home/worsch/net-kingdom/security-case-types",
"--version-root",
"1.2=/home/worsch/net-kingdom/security-case-type-revisions/1.2",
"--repos-root",
"/home/worsch",
"--allow-unimplemented"
],
"execution_permitted": false,
"render_digest": "sha256:c0afd5576cdae0cbc807eccb2b9fa87ac668f15e32ec7cf79d295bdb23c75b35",
"returncode": 0,
"stderr": "",
"stdout_sha256": "sha256:96b25108335e2cf5f96af481fe8a7735831c8320d81b50f7c6e6d4e53d0c0f02",
"type": "oidc-browser-relying-party@1.2"
},
{
"argv": [
"/usr/bin/python3",
"-B",
"/home/worsch/net-kingdom/tools/security-case-types/security_case_validator.py",
"validate-case",
"/home/worsch/net-kingdom/security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml",
"--types",
"/home/worsch/net-kingdom/security-case-types",
"--version-root",
"1.2=/home/worsch/net-kingdom/security-case-type-revisions/1.2"
],
"returncode": 1,
"stderr": "ERROR case.spec.type: type 'oidc-browser-relying-party' is 'acknowledged'; only implemented types accept cases\n",
"stdout_sha256": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
],
"closed_descriptor_count": 1,
"complete_review_step_count": 7,
"descriptor_round_trip": true,
"knowledge": {
"cards": [
"start",
"evidence"
],
"package_digest": "8d1d6a9d4d07fec7b619618de7dfe2254c1790f85f4198c7fe19db9751c02",
"package_version": "0.2.6",
"status": "withheld source changed; direct owner source reviewed, no offline guidance used as authority"
},
"native_execution": false,
"observed_at": "2026-10-17T02:10:28.924934+00:00",
"tests_added_or_rerun": false
}