From 97339f5aeead194b410c74f1e42c7339ca1bf64a Mon Sep 17 00:00:00 2001 From: Chris Busillo Date: Wed, 3 Jun 2026 09:15:22 -0400 Subject: [PATCH 1/2] Filter runtime secret bindings by target route --- control_plane/runtime_key_safety.py | 20 +++++++++++++++++--- tests/test_runtime_key_safety.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/control_plane/runtime_key_safety.py b/control_plane/runtime_key_safety.py index f0b72cb2..a6d65e1c 100644 --- a/control_plane/runtime_key_safety.py +++ b/control_plane/runtime_key_safety.py @@ -117,6 +117,15 @@ def evaluate_runtime_key_safety( ) continue effective_bindings = _effective_bindings_for_target(bindings, target=target) + if not effective_bindings: + findings.append( + RuntimeKeySafetyFinding( + code="binding_missing", + binding_key=binding_key, + detail=f"Required managed secret binding {binding_key!r} is missing.", + ) + ) + continue if len(effective_bindings) > 1: findings.append( RuntimeKeySafetyFinding( @@ -197,11 +206,16 @@ def _bindings_by_binding_key( 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) + ranked_bindings = tuple( + (binding, _binding_route_rank(binding=binding, target=target)) for binding in bindings + ) + highest_rank = max(rank for _, rank in ranked_bindings) + if highest_rank == 0: + return () return tuple( binding - for binding in bindings - if _binding_route_rank(binding=binding, target=target) == highest_rank + for binding, rank in ranked_bindings + if rank == highest_rank ) diff --git a/tests/test_runtime_key_safety.py b/tests/test_runtime_key_safety.py index 332f5f0a..3c4ff422 100644 --- a/tests/test_runtime_key_safety.py +++ b/tests/test_runtime_key_safety.py @@ -215,6 +215,35 @@ def test_more_specific_binding_satisfies_target_when_context_binding_also_exists self.assertEqual(evaluation.status, "pass") self.assertEqual(evaluation.findings, ()) + def test_unrelated_context_binding_does_not_satisfy_target(self) -> None: + evaluation = evaluate_runtime_key_safety( + target=RuntimeKeySafetyTarget( + context="opw", + instance="prod", + environment_class="prod", + ), + required_binding_keys=("ODOO_ADMIN_PASSWORD",), + secret_bindings=( + _binding( + binding_key="ODOO_ADMIN_PASSWORD", + binding_id="binding-cm-admin-password", + secret_id="secret-cm-admin-password", + ).model_copy(update={"context": "cm", "instance": "prod"}), + ), + secret_rules=( + RuntimeSecretSafetyRule( + binding_key="ODOO_ADMIN_PASSWORD", + secret_class="shared_safe", + allowed_contexts=("cm", "opw"), + allowed_instances=("testing", "prod"), + ), + ), + ) + + self.assertEqual(evaluation.status, "fail") + self.assertEqual(evaluation.findings[0].code, "binding_missing") + self.assertEqual(evaluation.findings[0].binding_key, "ODOO_ADMIN_PASSWORD") + def test_equally_specific_duplicate_bindings_remain_ambiguous(self) -> None: evaluation = evaluate_runtime_key_safety( target=RuntimeKeySafetyTarget( From 6646d4376e60234a5214c15e8b9349949de711bc Mon Sep 17 00:00:00 2001 From: Chris Busillo Date: Wed, 3 Jun 2026 09:21:50 -0400 Subject: [PATCH 2/2] Keep preview copied secret safety route-aware --- .../workflows/generic_web_preview.py | 31 +++++++++++++++--- .../workflows/verireel_preview_driver.py | 32 ++++++++++++++++--- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/control_plane/workflows/generic_web_preview.py b/control_plane/workflows/generic_web_preview.py index 072b0337..2b81a879 100644 --- a/control_plane/workflows/generic_web_preview.py +++ b/control_plane/workflows/generic_web_preview.py @@ -824,6 +824,23 @@ def _copied_secret_shaped_runtime_keys( return tuple(dict.fromkeys(copied_keys)) +def _retarget_secret_bindings_for_preview_safety( + *, + secret_bindings: tuple[SecretBinding, ...], + preview_context: str, + preview_slug: str, +) -> tuple[SecretBinding, ...]: + return tuple( + binding.model_copy( + update={ + "context": preview_context, + "instance": preview_slug, + } + ) + for binding in secret_bindings + ) + + def _enforce_preview_copied_runtime_key_safety( *, record_store: GenericWebPreviewProfileStore, @@ -859,11 +876,15 @@ def _enforce_preview_copied_runtime_key_safety( environment_class="preview", ), required_binding_keys=required_binding_keys, - secret_bindings=record_store.list_secret_bindings( - integration=control_plane_secrets.RUNTIME_ENVIRONMENT_SECRET_INTEGRATION, - context_name=template_lane.context, - instance_name=template_lane.instance, - limit=None, + secret_bindings=_retarget_secret_bindings_for_preview_safety( + secret_bindings=record_store.list_secret_bindings( + integration=control_plane_secrets.RUNTIME_ENVIRONMENT_SECRET_INTEGRATION, + context_name=template_lane.context, + instance_name=template_lane.instance, + limit=None, + ), + preview_context=profile.preview.context, + preview_slug=preview_slug, ), secret_rules=policy_record.rules, ) diff --git a/control_plane/workflows/verireel_preview_driver.py b/control_plane/workflows/verireel_preview_driver.py index 2df4336e..509c44d0 100644 --- a/control_plane/workflows/verireel_preview_driver.py +++ b/control_plane/workflows/verireel_preview_driver.py @@ -20,6 +20,7 @@ from control_plane.dokploy import JsonObject from control_plane.contracts.runtime_identity import RuntimeIdentity, runtime_identity_env from control_plane.contracts.runtime_key_safety_policy import RuntimeKeySafetyTarget +from control_plane.contracts.secret_record import SecretBinding from control_plane.runtime_key_safety import ( RuntimeKeySafetyPolicyReadStore, evaluate_runtime_key_safety, @@ -357,6 +358,23 @@ def _verireel_template_runtime_secret_keys( return tuple(dict.fromkeys(required_keys)) +def _retarget_secret_bindings_for_preview_safety( + *, + secret_bindings: tuple[SecretBinding, ...], + preview_context: str, + preview_slug: str, +) -> tuple[SecretBinding, ...]: + return tuple( + binding.model_copy( + update={ + "context": preview_context, + "instance": preview_slug, + } + ) + for binding in secret_bindings + ) + + def _enforce_verireel_preview_runtime_key_safety( *, record_store: RuntimeKeySafetyPolicyReadStore | None, @@ -385,11 +403,15 @@ def _enforce_verireel_preview_runtime_key_safety( environment_class="preview", ), required_binding_keys=required_binding_keys, - secret_bindings=record_store.list_secret_bindings( - integration=control_plane_secrets.RUNTIME_ENVIRONMENT_SECRET_INTEGRATION, - context_name=template_target.context, - instance_name=template_target.instance, - limit=None, + secret_bindings=_retarget_secret_bindings_for_preview_safety( + secret_bindings=record_store.list_secret_bindings( + integration=control_plane_secrets.RUNTIME_ENVIRONMENT_SECRET_INTEGRATION, + context_name=template_target.context, + instance_name=template_target.instance, + limit=None, + ), + preview_context=request.context, + preview_slug=request.preview_slug, ), secret_rules=policy_record.rules, )