sand-boxer/tests/test_runtime_store.py
tegwick df5e941814
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
feat(runtime): install pinned artifacts in a private owner store
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-08 21:08:18 +02:00

111 lines
4.1 KiB
Python

from pathlib import Path
import pytest
from sandboxer.extensions import runtime_store
from sandboxer.extensions.runtime import runtime_digest, verified_runtime
@pytest.fixture
def inputs(tmp_path, monkeypatch):
home = tmp_path / "owner-home"
home.mkdir(mode=0o700)
monkeypatch.setenv("HOME", str(home))
source = tmp_path / "candidate"
(source / "bin").mkdir(parents=True)
(source / "pyvenv.cfg").write_text("home = /usr/bin\n")
(source / "bin/python3").write_bytes(b"fixture executable")
(source / "bin/python3").chmod(0o755)
(source / "bin/python").symlink_to("python3")
return source, home / "runtimes", runtime_digest(source)
def test_install_preserves_pin_and_does_not_share_mutable_source(inputs):
source, store, digest = inputs
result = runtime_store.install_runtime(source, store, digest)
installed = verified_runtime(result)
assert installed == store / digest
assert store.stat().st_mode & 0o777 == 0o700
assert not result["profile_activated"]
assert not result["credential_delivery_configured"]
assert (installed / "bin/python").is_symlink()
(source / "bin/python3").write_bytes(b"changed after installation")
assert verified_runtime(result) == installed
def test_repeat_is_idempotent_but_never_repairs_or_overwrites_existing_artifact(inputs):
source, store, digest = inputs
first = runtime_store.install_runtime(source, store, digest)
assert runtime_store.install_runtime(source, store, digest)["reused"]
installed = Path(first["runtime"]["path"])
target = installed / "bin/python3"
target.write_bytes(b"tampered installed artifact")
with pytest.raises(ValueError, match="digest"):
runtime_store.install_runtime(source, store, digest)
assert target.read_bytes() == b"tampered installed artifact"
def test_wrong_digest_refuses_before_creating_store(inputs):
source, store, _ = inputs
with pytest.raises(ValueError, match="digest"):
runtime_store.install_runtime(source, store, "0" * 64)
assert not store.exists()
def test_copy_tampering_never_publishes(inputs, monkeypatch):
source, store, digest = inputs
copytree = runtime_store.shutil.copytree
def corrupt(src, dst, *args, **kwargs):
result = copytree(src, dst, *args, **kwargs)
if Path(src) == source:
(Path(dst) / "bin/python3").write_bytes(b"corrupted during copy")
return result
monkeypatch.setattr(runtime_store.shutil, "copytree", corrupt)
with pytest.raises(ValueError, match="digest"):
runtime_store.install_runtime(source, store, digest)
assert not (store / digest).exists()
assert not list(store.glob(".install-*"))
@pytest.mark.parametrize("mode", [0o777, 0o775, 0o755])
def test_store_must_be_private(inputs, mode):
source, store, digest = inputs
store.mkdir(mode=mode)
store.chmod(mode)
with pytest.raises(ValueError, match="permissions"):
runtime_store.install_runtime(source, store, digest)
assert not (store / digest).exists()
def test_store_symlink_is_refused(inputs):
source, store, digest = inputs
actual = store.parent / "actual"
actual.mkdir(mode=0o700)
store.symlink_to(actual)
with pytest.raises(ValueError, match="canonical"):
runtime_store.install_runtime(source, store, digest)
@pytest.mark.parametrize("mode", [0o777, 0o4755, 0o2755])
def test_even_a_matching_pin_cannot_admit_unsafe_artifact_modes(inputs, mode):
source, store, _ = inputs
(source / "bin/python3").chmod(mode)
digest = runtime_digest(source)
with pytest.raises(ValueError, match="unsafe permission"):
runtime_store.install_runtime(source, store, digest)
assert not (store / digest).exists()
def test_world_writable_parent_is_refused(inputs):
source, store, digest = inputs
store.parent.chmod(0o777)
with pytest.raises(ValueError, match="permissions"):
runtime_store.install_runtime(source, store, digest)
def test_store_outside_owner_home_is_refused(inputs):
source, store, digest = inputs
with pytest.raises(ValueError, match="below the owner home"):
runtime_store.install_runtime(source, store.parent.parent / "other", digest)