Harden release source execution

This commit is contained in:
2026-07-22 21:37:14 +02:00
parent 349a099e5a
commit 7ecf1f17b0
11 changed files with 3331 additions and 58 deletions

View File

@@ -23,6 +23,7 @@ from govoplan_release.catalog import canonical_hash # noqa: E402
from govoplan_release.selective_catalog import ( # noqa: E402
build_selective_catalog_candidate,
enforce_selected_source_provenance,
parse_signing_key,
public_key_base64,
signature,
)
@@ -159,6 +160,7 @@ class ReleaseSourceProvenanceTests(unittest.TestCase):
encryption_algorithm=serialization.NoEncryption(),
)
)
key_path.chmod(0o600)
output = self.root / "candidate"
with patch(
@@ -181,6 +183,25 @@ class ReleaseSourceProvenanceTests(unittest.TestCase):
self.assertEqual(git_text(core, "rev-parse", "refs/tags/v1.2.3"), selected["tag_object_sha"])
self.assertEqual("test-key", payload["signatures"][0]["key_id"])
def test_catalog_signing_key_must_be_operator_private(self) -> None:
private_key = Ed25519PrivateKey.generate()
key_path = self.root / "release.pem"
key_path.write_bytes(
private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
)
key_path.chmod(0o644)
with self.assertRaisesRegex(ValueError, "inaccessible to other users"):
parse_signing_key(f"test-key={key_path}")
key_path.chmod(0o600)
key_id, _parsed = parse_signing_key(f"test-key={key_path}")
self.assertEqual("test-key", key_id)
def test_catalog_publication_checks_every_preserved_source_ref(self) -> None:
core, _ = make_repo(self.workspace, self.root, "govoplan-core", "1.2.3")
git(core, "tag", "-a", "v1.2.3", "-m", "Core 1.2.3")
@@ -235,22 +256,21 @@ class ReleaseSourceProvenanceTests(unittest.TestCase):
self.assertIn("Array.isArray(result.notes)", ui)
self.assertIn("Validation and provenance details", ui)
def test_console_returns_actionable_conflict_for_candidate_provenance_gate(self) -> None:
with patch(
"server.app.build_selective_catalog_candidate",
side_effect=ValueError("Complete catalog source provenance gate failed: govoplan-core v1.2.3: missing"),
):
with TestClient(create_app(workspace_root=self.workspace)) as client:
response = client.post(
"/api/catalog-candidates",
json={
"repo_versions": {"govoplan-core": "1.2.3"},
"signing_keys": ["test=/unused/key.pem"],
},
)
def test_console_disables_unclaimed_legacy_candidate_signing(self) -> None:
with TestClient(
create_app(workspace_root=self.workspace, token="token")
) as client:
response = client.post(
"/api/catalog-candidates",
headers={"X-Release-Console-Token": "token"},
json={
"repo_versions": {"govoplan-core": "1.2.3"},
"signing_keys": ["test=/unused/key.pem"],
},
)
self.assertEqual(409, response.status_code)
self.assertIn("govoplan-core v1.2.3: missing", response.json()["detail"])
self.assertIn("durable release run", response.json()["detail"])
def test_read_only_ref_checks_can_reuse_the_same_gitea_https_endpoint(self) -> None:
self.assertEqual(