ops-warden/scripts/run_unit_tests.py
tegwick b593c87983
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
test: isolate ordinary unit runs from ambient credentials and provider I/O
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa
2026-10-17 21:30:12 +02:00

283 lines
15 KiB
Python

"""Run trusted unit tests with no inherited credentials or external I/O.
This is an accident guard for this suite, not an OS sandbox for hostile Python.
Direct pytest bypasses it. Use make test (already installed dependencies only).
"""
from __future__ import annotations
import hashlib
import json
import os
from pathlib import Path
import runpy
import socket
import subprocess
import sys
import tempfile
ROOT = Path(__file__).resolve().parents[1]
SELF = Path(__file__).resolve()
SHELL_FIXTURES = {
"printf 'the-secret-value'", "printf 'sekret'", "printf 'new'",
"printf '%s' '{\"wrap_info\":{\"token\":\"hvs.WRAP\"}}'",
"printf 'not-json'",
}
JOURNAL_CODE_SHA256 = '69aa18f302fd698104cb2253b4af0c3a077e72a0a427183e3dce1444c4926df9'
class IsolationDenied(PermissionError, subprocess.SubprocessError):
"""A unit test attempted an unreviewed external operation."""
def clean_environment(home: Path, temporary: Path) -> dict[str, str]:
# Construct, never copy/inventory the caller's environment.
return {'HOME': str(home), 'TMPDIR': str(temporary), 'PATH': '/usr/bin:/bin',
'LANG': 'C.UTF-8', 'PYTHONDONTWRITEBYTECODE': '1',
'PYTEST_DISABLE_PLUGIN_AUTOLOAD': '1'}
def inside(path: Path, roots: tuple[Path, ...]) -> bool:
return any(path == root or root in path.parents for root in roots)
class Guard:
def __init__(self, temporary: Path, read_roots: list[Path], child: bool = False, git_metadata: bool = False):
self.temporary = temporary.resolve()
self.read_roots = tuple(p.resolve() for p in read_roots)
self.child = child
self.git_metadata = git_metadata
self.loopback_test = False
self.endpoints: set[tuple[str, int]] = set()
self.launch = None
self.original_popen = subprocess.Popen
def fixture_path(self, value: str) -> Path:
path = Path(value).resolve()
if not inside(path, (self.temporary,)):
raise IsolationDenied('unit isolation: non-fixture path')
return path
def audit(self, event, args):
if event == 'open' and not isinstance(args[0], int):
path = Path(os.fsdecode(args[0])).resolve()
mode, flags = args[1:3]
write = ((isinstance(mode, str) and any(c in mode for c in 'wax+'))
or (isinstance(flags, int) and flags & (os.O_WRONLY | os.O_RDWR | os.O_CREAT | os.O_TRUNC | os.O_APPEND)))
roots = (self.temporary,) if write else self.read_roots
if path != Path('/dev/null') and not inside(path, roots):
raise IsolationDenied('unit isolation: file outside reviewed roots')
if event == 'subprocess.Popen':
if self.launch is None or tuple(args[1]) != self.launch:
raise IsolationDenied('unit isolation: unexpected process')
if event in {'os.system', 'os.exec', 'os.posix_spawn', 'os.fork', 'os.forkpty'}:
raise IsolationDenied('unit isolation: native execution disabled')
if event.startswith('socket.'):
if not self.loopback_test or self.child:
raise IsolationDenied('unit isolation: sockets disabled')
if event == 'socket.__new__':
if args[1] != socket.AF_INET or args[2] & 15 != socket.SOCK_STREAM:
raise IsolationDenied('unit isolation: socket family/type denied')
elif event == 'socket.bind':
if args[1] != ('127.0.0.1', 0):
raise IsolationDenied('unit isolation: only ephemeral fixture bind')
elif event == 'socket.connect':
if args[1] not in self.endpoints:
raise IsolationDenied('unit isolation: only this fixture endpoint')
elif event not in {'socket.gethostname'}:
raise IsolationDenied('unit isolation: DNS/socket operation denied')
def python_payload(self, argv):
"""Closed subprocess inventory; every allowed Python child installs guard."""
from warden import case_inputs
if (len(argv) == 5 and argv[:3] == [sys.executable, '-I', '-c']
and argv[3] == case_inputs._VALIDATE):
directory = self.fixture_path(argv[4])
if not directory.name.startswith('warden-case-validator-'):
raise IsolationDenied('unit isolation: validator fixture directory differs')
# Reverify copied modules immediately before launch, independently of caller.
for relative, digest in case_inputs.SOURCE_PINS.items():
if hashlib.sha256((directory / relative).read_bytes()).hexdigest() != digest:
raise IsolationDenied('unit isolation: validator source pin differs')
return {'code': argv[3], 'args': [str(directory)]}
if len(argv) == 3 and argv[:2] == [sys.executable, '-c'] and argv[2] == 'print("SYNTHETIC-SECRET")':
return {'code': argv[2], 'args': []}
if (len(argv) == 6 and argv[:3] == [sys.executable, '-B', '-c']
and hashlib.sha256(argv[3].encode()).hexdigest() == JOURNAL_CODE_SHA256):
self.fixture_path(argv[4])
if len(argv[5]) > 192:
raise IsolationDenied('unit isolation: journal source bound')
return {'code': argv[3], 'args': argv[4:]}
if len(argv) >= 2 and argv[0] in (sys.executable, 'python3'):
script = Path(argv[1]).resolve()
args = argv[2:]
if script == ROOT / 'tests/unit_isolation_probe.py' and len(args) == 1 and args[0] in {'state', 'socket', 'provider', 'home', 'nested'}:
return {'script': str(script), 'args': args}
if script == ROOT / 'scripts/check_layer_conformance.py' and not args:
return {'script': str(script), 'args': args}
if script == ROOT / 'scripts/emit_high_risk_paths.py' and args == ['--check']:
return {'script': str(script), 'args': args, 'git_metadata': True}
if script == ROOT / 'scripts/check_principals_drift.py' and len(args) == 4 and args[::2] == ['--inventory', '--infra']:
for value in args[1::2]:
self.fixture_path(value)
return {'script': str(script), 'args': args}
if script == ROOT / 'scripts/build_flex_auth_registry.py':
if (len(args) in (3, 5) and Path(args[0]).resolve() == ROOT / 'examples/inventory.seed.yaml'
and args[-2] == '-o' and (len(args) == 3 or args[1] == '--zone-resolutions')):
self.fixture_path(args[-1])
if len(args) == 5:
self.fixture_path(args[2])
return {'script': str(script), 'args': args}
raise IsolationDenied('unit isolation: command not in reviewed subprocess inventory')
def popen(self, argv, *pos, **kw):
if pos or kw.get('executable') or kw.get('preexec_fn') or kw.get('pass_fds') or kw.get('close_fds') is False:
raise IsolationDenied('unit isolation: unexpected process options')
if kw.pop('shell', False):
if self.child or not isinstance(argv, str) or argv not in SHELL_FIXTURES:
raise IsolationDenied('unit isolation: unreviewed shell command')
return self.spawn(['/bin/bash', '--noprofile', '--norc', '-c', argv], kw)
if not isinstance(argv, (list, tuple)):
raise IsolationDenied('unit isolation: argv list required')
argv = [os.fspath(x) for x in argv]
# Never run a real provider: the only shell fixture is an exact-byte double.
from warden.doubles import _DOUBLES
metadata_commands = (['git', 'log', '-1', '--format=%H %cI', '--', str(ROOT / 'registry/routing/catalog.yaml')],
['git', 'status', '--porcelain', '--', str(ROOT / 'registry/routing/catalog.yaml')])
if self.child and not (self.git_metadata and argv in metadata_commands):
raise IsolationDenied('unit isolation: nested process disabled')
candidate = Path(argv[0])
if not candidate.is_absolute():
import shutil
resolved = shutil.which(argv[0], path=kw.get('env', os.environ).get('PATH', ''))
candidate = Path(resolved) if resolved else candidate
if self.child and self.git_metadata:
if Path(kw.get('cwd', '.')).resolve() != ROOT:
raise IsolationDenied('unit isolation: metadata cwd differs')
command = ['/usr/bin/git', '-c', 'core.fsmonitor=false', '-c', 'core.hooksPath=/dev/null', '--no-pager', *argv[1:]]
elif candidate.is_absolute() and inside(candidate.resolve(), (self.temporary,)) and candidate.name in _DOUBLES:
if candidate.read_text() != _DOUBLES[candidate.name].script:
raise IsolationDenied('unit isolation: double bytes differ')
tail = argv[1:]
if (candidate.name == 'bao' and tail not in (
['kv', 'get', '-field=NPM_AUTH_TOKEN', 'platform/x/y'],
['kv', 'get', '-field=API_KEY', 'platform/x/y/z'],
['login', '-method=oidc'], ['write', 'secret/x'])) or (candidate.name == 'key-cape' and tail != ['login']):
raise IsolationDenied('unit isolation: double arguments differ')
command = ['/bin/bash', '--noprofile', '--norc', str(candidate), *tail]
else:
payload = self.python_payload(argv)
payload.update(temporary=str(self.temporary), read_roots=[str(x) for x in self.read_roots])
command = [sys.executable, '-I', str(SELF), '--child', json.dumps(payload)]
return self.spawn(command, kw)
def spawn(self, command, kw):
cwd = Path(kw.get('cwd') or ROOT).resolve()
if not inside(cwd, (ROOT, self.temporary)):
raise IsolationDenied('unit isolation: non-fixture working directory')
kw['cwd'] = str(cwd)
# env supplied by tests is never propagated: even synthetic token mutations
# remain in the parent. All approved children have only this fresh environment.
kw['env'] = clean_environment(self.temporary / 'home', self.temporary)
kw['env'].update(GIT_CONFIG_NOSYSTEM='1', GIT_CONFIG_GLOBAL='/dev/null', GIT_OPTIONAL_LOCKS='0')
self.launch = tuple(command)
try:
return self.original_popen(command, **kw)
finally:
self.launch = None
def install(self):
sys.addaudithook(self.audit)
subprocess.Popen = self.popen
guard = self
original_socket = socket.socket
class FixtureSocket(original_socket):
def bind(self, address):
super().bind(address)
guard.endpoints.add(self.getsockname())
socket.socket = FixtureSocket
def numeric_addresses(host, port, family=0, type=0, proto=0, flags=0):
if not guard.loopback_test or (host, port) not in guard.endpoints:
raise IsolationDenied('unit isolation: DNS/external endpoint denied')
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (host, port))]
socket.getaddrinfo = numeric_addresses
def local_name(host=''):
if not guard.loopback_test or host != '127.0.0.1':
raise IsolationDenied('unit isolation: hostname lookup denied')
return 'localhost'
socket.getfqdn = local_name
def pytest_configure(self, config):
config._unit_guard = self
# Exact single synthetic HTTP test only; no other test gets a loopback lease.
def pytest_runtest_setup(self, item):
self.loopback_test = item.nodeid == 'tests/test_desk.py::test_approve_flow_http_dry'
self.endpoints.clear()
def pytest_runtest_teardown(self, item):
self.loopback_test = False
self.endpoints.clear()
def worker(temporary: Path, arguments: list[str], netkingdom: Path | None, phase: Path | None):
sys.dont_write_bytecode = True
tempfile.tempdir = str(temporary)
paths = [ROOT / 'src']
if phase:
paths.append(phase / 'src')
# Explicit trusted source roots only, never ambient PYTHONPATH/plugins.
sys.path[:0] = [str(p) for p in paths]
roots = [ROOT, *paths, Path(sys.prefix), Path(sys.base_prefix), temporary]
if phase:
roots.append(phase / 'tests/fixtures/ops-warden-coordination-profile.json')
if netkingdom:
roots.append(netkingdom)
os.environ['WARDEN_TEST_NETKINGDOM_ROOT'] = str(netkingdom)
guard = Guard(temporary, roots)
guard.install()
# Pytest itself and collection run only after installation.
import pytest
raise SystemExit(pytest.main(['-p', 'no:cacheprovider', '--basetemp', str(temporary / 'pytest'), *arguments], plugins=[guard]))
def main():
if sys.argv[1:2] == ['--child']:
payload = json.loads(sys.argv[2])
temporary = Path(payload['temporary'])
sys.dont_write_bytecode = True
tempfile.tempdir = str(temporary)
sys.path.insert(0, str(ROOT / 'src'))
guard = Guard(temporary, [Path(p) for p in payload['read_roots']], child=True,
git_metadata=payload.get('git_metadata', False))
guard.install()
sys.argv = [payload.get('script', '-c'), *payload['args']]
if 'script' in payload:
runpy.run_path(payload['script'], run_name='__main__')
else:
exec(compile(payload['code'], '<reviewed-unit-child>', 'exec'), {'__name__': '__main__'})
return
if sys.argv[1:2] == ['--worker']:
temporary = Path(sys.argv[2])
netkingdom = Path(sys.argv[3]) if sys.argv[3] else None
phase = Path(sys.argv[4]) if sys.argv[4] else None
worker(temporary, sys.argv[5:], netkingdom, phase)
return
import argparse
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--netkingdom-root', type=Path, default=ROOT.parent / 'net-kingdom')
parser.add_argument('--phase-memory-root', type=Path, default=ROOT.parent / 'phase-memory')
options, arguments = parser.parse_known_args()
netkingdom = options.netkingdom_root.resolve() if options.netkingdom_root.is_dir() else None
phase = options.phase_memory_root.resolve() if (options.phase_memory_root / 'src').is_dir() else None
with tempfile.TemporaryDirectory(prefix='warden-unit-') as directory:
temporary = Path(directory)
home = temporary / 'home'
home.mkdir()
result = subprocess.run([sys.executable, '-I', str(SELF), '--worker', str(temporary),
str(netkingdom) if netkingdom else '', str(phase) if phase else '', *arguments],
cwd=ROOT, env=clean_environment(home, temporary))
raise SystemExit(result.returncode)
if __name__ == '__main__':
main()