test_provenance_security.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
12 hours ago
| 1 | """Security tests for Track P / P1 provenance (§P0.8).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import inspect |
| 6 | import json |
| 7 | |
| 8 | import pytest |
| 9 | import yaml |
| 10 | |
| 11 | from adapters.config import load_config |
| 12 | from adapters.errors import ConfigError |
| 13 | from cli.kit_root import kit_root |
| 14 | from tests.support import git_status_runner, load_honesty_config, run_cli, seed_honesty_repo |
| 15 | from tools.honesty import ed25519_util, ledger, provenance, status |
| 16 | |
| 17 | |
| 18 | def test_kit_modules_do_not_load_private_keys() -> None: |
| 19 | """Production honesty modules must not reference private-key APIs.""" |
| 20 | sources = ( |
| 21 | inspect.getsource(ed25519_util), |
| 22 | inspect.getsource(provenance), |
| 23 | inspect.getsource(ledger), |
| 24 | inspect.getsource(status), |
| 25 | ) |
| 26 | joined = "\n".join(sources) |
| 27 | assert "PrivateKey" not in joined |
| 28 | assert "private_key" not in joined |
| 29 | |
| 30 | |
| 31 | def test_malformed_sig_rejected_not_executed(repo_root) -> None: |
| 32 | config = load_honesty_config(repo_root) |
| 33 | body = { |
| 34 | "actor_role": "verifier", |
| 35 | "actor_session_id": "v1", |
| 36 | "artifact_sha256": "aa" * 32, |
| 37 | "passed": True, |
| 38 | "evidence": {"reexecuted": ["verify-step:x"]}, |
| 39 | "provenance": { |
| 40 | "agent_id": "cursor-agent", |
| 41 | "model_id": "gpt-5.6", |
| 42 | "pubkey": "ed25519:AA==", |
| 43 | "sig": "__import__('os').system('echo pwned')", |
| 44 | }, |
| 45 | } |
| 46 | from tools.honesty.ledger import append_entry |
| 47 | from tools.honesty.types import LedgerAppendOptions |
| 48 | |
| 49 | result = append_entry( |
| 50 | config=config, |
| 51 | repo_root=repo_root, |
| 52 | options=LedgerAppendOptions(kind="verdict", body=body), |
| 53 | ) |
| 54 | assert result.exit_code == 2 |
| 55 | |
| 56 | |
| 57 | def test_provenance_strings_treated_as_opaque_data(tmp_path) -> None: |
| 58 | seed_honesty_repo(tmp_path) |
| 59 | payload = { |
| 60 | "actor_role": "verifier", |
| 61 | "actor_session_id": "v1", |
| 62 | "artifact_sha256": "aa" * 32, |
| 63 | "passed": True, |
| 64 | "evidence": {"reexecuted": ["verify-step:x"]}, |
| 65 | "provenance": { |
| 66 | "agent_id": "<script>alert(1)</script>", |
| 67 | "model_id": "'; DROP TABLE ledger; --", |
| 68 | "human_ref": "../../../etc/passwd", |
| 69 | }, |
| 70 | } |
| 71 | path = tmp_path / "payload.json" |
| 72 | path.write_text(json.dumps(payload), encoding="utf-8") |
| 73 | code = run_cli( |
| 74 | ["ledger", "append", "--kind", "verdict", "--file", "payload.json"], |
| 75 | cwd=tmp_path, |
| 76 | runner=git_status_runner(), |
| 77 | kit=kit_root(), |
| 78 | ) |
| 79 | assert code == 0 |
| 80 | |
| 81 | |
| 82 | def test_git_only_cannot_force_require_agent_signature(tmp_path) -> None: |
| 83 | seed_honesty_repo(tmp_path) |
| 84 | cfg = tmp_path / ".overseer" / "config.yaml" |
| 85 | data = yaml.safe_load(cfg.read_text(encoding="utf-8")) |
| 86 | data["honesty"]["require_agent_signature"] = True |
| 87 | cfg.write_text(yaml.safe_dump(data), encoding="utf-8") |
| 88 | with pytest.raises(ConfigError) as exc: |
| 89 | load_config(cfg) |
| 90 | assert exc.value.exit_code == 26 |
File History
2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
12 hours ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439
feat: K1-P1 complete — agent provenance, build-verification…
Sonnet 4.6
patch
52 days ago