fix(recovery): require one original client and refine native owner gates
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa
This commit is contained in:
parent
70f408ca23
commit
c52ca7f405
5 changed files with 270 additions and 26 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -54,6 +54,34 @@ class ArchiveTests(unittest.TestCase):
|
|||
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):
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue