feat: accept KeyCape approval clients with tested recovery
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
ce826cfa8d
commit
303a584bd0
8 changed files with 810 additions and 20 deletions
|
|
@ -83,7 +83,7 @@ class RolloutTests(unittest.TestCase):
|
|||
changed['metadata']['resourceVersion'] = str(int(changed['metadata']['resourceVersion']) + 1)
|
||||
state[kind] = changed
|
||||
return copy.deepcopy(changed)
|
||||
with tempfile.TemporaryDirectory() as directory, patch.object(m, 'assert_cluster'), \
|
||||
with tempfile.TemporaryDirectory() as directory, patch.object(m, 'assert_cluster'), patch.object(m, 'verify_artifact'), \
|
||||
patch.object(m, 'get', side_effect=lambda kube, kind, name: copy.deepcopy(state[kind])), \
|
||||
patch.object(m, 'patch_object', side_effect=fake_patch), patch.object(m, 'ready', return_value={}), \
|
||||
patch.object(m, 'acceptance', side_effect=m.LaneError('synthetic_acceptance_failure')):
|
||||
|
|
@ -95,6 +95,29 @@ class RolloutTests(unittest.TestCase):
|
|||
self.assertEqual(state['deployment']['spec'], original['deployment']['spec'])
|
||||
self.assertEqual((Path(directory) / 'recovery.json').stat().st_mode & 0o777, 0o600)
|
||||
|
||||
def test_ready_matches_manifest_imageid_not_runtime_config_id(self):
|
||||
dep = deployment(); dep['metadata']['generation'] = 30
|
||||
dep['status'] = {'observedGeneration': 30, 'updatedReplicas': 1, 'readyReplicas': 1, 'availableReplicas': 1, 'replicas': 1}
|
||||
pod = {'metadata': {'uid': 'fixture-pod'}, 'status': {'containerStatuses': [
|
||||
{'name': 'keycape', 'ready': True, 'image': 'sha256:runtime-config-id', 'imageID': m.IMAGE}]}}
|
||||
from types import SimpleNamespace
|
||||
with patch.object(m, 'get', return_value=dep), patch.object(m, 'command', return_value=SimpleNamespace(stdout=json.dumps({'items': [pod]}).encode())):
|
||||
self.assertTrue(m.ready([], m.IMAGE, timeout=1)['single_ready_replica'])
|
||||
|
||||
def test_iat_skew_matches_native_contract_without_extending_expiry(self):
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
now = int(m.time.time())
|
||||
claims = {'iss': m.ISSUER, 'aud': 'approval-engine', 'sub': 'synthetic-service', 'iat': now + 2, 'exp': now + 902}
|
||||
encoded = m.jwt.encode(claims, key, algorithm='RS256')
|
||||
self.assertEqual(m.verified_claims(encoded, key.public_key())['iat'], now + 2)
|
||||
future = m.jwt.encode(dict(claims, iat=now+60), key, algorithm='RS256')
|
||||
with self.assertRaisesRegex(m.LaneError, 'issued_at_binding_failed'):
|
||||
m.verified_claims(future, key.public_key())
|
||||
expired = m.jwt.encode(dict(claims, iat=now-900, exp=now-1), key, algorithm='RS256')
|
||||
with self.assertRaises(m.jwt.ExpiredSignatureError):
|
||||
m.verified_claims(expired, key.public_key())
|
||||
|
||||
def test_unrelated_refusal_never_passes(self):
|
||||
for status, body in [(500, {}), (400, {'error': 'invalid_profile_usage', 'feature': 'client_id'}),
|
||||
(401, {'error': 'invalid_profile_usage', 'feature': 'scope'})]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue