From ac72fe50a0e555ed6f576109858b7bc946ed3f1f Mon Sep 17 00:00:00 2001 From: Chris Busillo Date: Tue, 2 Jun 2026 17:08:51 -0400 Subject: [PATCH] Evaluate effective runtime secret binding --- control_plane/runtime_key_safety.py | 24 ++++++++++- tests/test_runtime_key_safety.py | 66 +++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/control_plane/runtime_key_safety.py b/control_plane/runtime_key_safety.py index 2d428c4a..f0b72cb2 100644 --- a/control_plane/runtime_key_safety.py +++ b/control_plane/runtime_key_safety.py @@ -116,7 +116,8 @@ def evaluate_runtime_key_safety( ) ) continue - if len(bindings) > 1: + effective_bindings = _effective_bindings_for_target(bindings, target=target) + if len(effective_bindings) > 1: findings.append( RuntimeKeySafetyFinding( code="ambiguous_binding", @@ -126,7 +127,7 @@ def evaluate_runtime_key_safety( ) continue - binding = bindings[0] + binding = effective_bindings[0] if binding.status != "configured": findings.append( RuntimeKeySafetyFinding( @@ -193,6 +194,25 @@ def _bindings_by_binding_key( return {key: tuple(bindings) for key, bindings in grouped.items()} +def _effective_bindings_for_target( + bindings: tuple[SecretBinding, ...], *, target: RuntimeKeySafetyTarget +) -> tuple[SecretBinding, ...]: + highest_rank = max(_binding_route_rank(binding=binding, target=target) for binding in bindings) + return tuple( + binding + for binding in bindings + if _binding_route_rank(binding=binding, target=target) == highest_rank + ) + + +def _binding_route_rank(*, binding: SecretBinding, target: RuntimeKeySafetyTarget) -> int: + if binding.context == target.context and binding.instance == target.instance: + return 2 + if binding.context == target.context and not binding.instance: + return 1 + return 0 + + def _evaluate_binding_rule( *, target: RuntimeKeySafetyTarget, diff --git a/tests/test_runtime_key_safety.py b/tests/test_runtime_key_safety.py index a3c38054..332f5f0a 100644 --- a/tests/test_runtime_key_safety.py +++ b/tests/test_runtime_key_safety.py @@ -180,6 +180,72 @@ def test_missing_or_disabled_secret_binding_fails_closed(self) -> None: self.assertEqual(disabled_evaluation.status, "fail") self.assertEqual(disabled_evaluation.findings[0].code, "binding_disabled") + def test_more_specific_binding_satisfies_target_when_context_binding_also_exists( + self, + ) -> None: + evaluation = evaluate_runtime_key_safety( + target=RuntimeKeySafetyTarget( + context="opw", + instance="testing", + environment_class="testing", + ), + required_binding_keys=("SHOPIFY_ACCESS_TOKEN",), + secret_bindings=( + _binding( + binding_key="SHOPIFY_ACCESS_TOKEN", + binding_id="binding-context-token", + secret_id="secret-context-token", + ).model_copy(update={"instance": ""}), + _binding( + binding_key="SHOPIFY_ACCESS_TOKEN", + binding_id="binding-instance-token", + secret_id="secret-instance-token", + ), + ), + secret_rules=( + RuntimeSecretSafetyRule( + binding_key="SHOPIFY_ACCESS_TOKEN", + secret_class="testing", + allowed_contexts=("opw",), + allowed_instances=("testing",), + ), + ), + ) + + self.assertEqual(evaluation.status, "pass") + self.assertEqual(evaluation.findings, ()) + + def test_equally_specific_duplicate_bindings_remain_ambiguous(self) -> None: + evaluation = evaluate_runtime_key_safety( + target=RuntimeKeySafetyTarget( + context="opw", + instance="testing", + environment_class="testing", + ), + required_binding_keys=("SHOPIFY_ACCESS_TOKEN",), + secret_bindings=( + _binding( + binding_key="SHOPIFY_ACCESS_TOKEN", + binding_id="binding-first-token", + secret_id="secret-first-token", + ), + _binding( + binding_key="SHOPIFY_ACCESS_TOKEN", + binding_id="binding-second-token", + secret_id="secret-second-token", + ), + ), + secret_rules=( + RuntimeSecretSafetyRule( + binding_key="SHOPIFY_ACCESS_TOKEN", + secret_class="testing", + ), + ), + ) + + self.assertEqual(evaluation.status, "fail") + self.assertEqual(evaluation.findings[0].code, "ambiguous_binding") + def test_context_and_instance_restrictions_fail_closed(self) -> None: evaluation = evaluate_runtime_key_safety( target=RuntimeKeySafetyTarget(