Add owner-mediated bwrap execution boundary
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06def-6490-7033-8448-2eab2d12ed44
This commit is contained in:
parent
877676d1f1
commit
d79e3fe358
23 changed files with 1321 additions and 86 deletions
|
|
@ -5,7 +5,14 @@ from unittest.mock import patch
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from sandboxer.api.app import app
|
||||
from sandboxer.models import ActorType, Consumer, SandboxState, SandboxStatus, SnapshotRecord
|
||||
from sandboxer.models import (
|
||||
ActorType,
|
||||
Consumer,
|
||||
SandboxExecResult,
|
||||
SandboxState,
|
||||
SandboxStatus,
|
||||
SnapshotRecord,
|
||||
)
|
||||
|
||||
|
||||
def test_list_sandboxes_empty() -> None:
|
||||
|
|
@ -148,4 +155,59 @@ def test_expire_sandboxes() -> None:
|
|||
client = TestClient(app)
|
||||
resp = client.post("/v1/sandboxes/expire")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()[0]["action"] == "dry-run"
|
||||
assert resp.json()[0]["action"] == "dry-run"
|
||||
|
||||
|
||||
def test_exec_api_fails_closed_when_owner_token_unconfigured(monkeypatch) -> None:
|
||||
monkeypatch.delenv("SANDBOXER_EXEC_TOKEN", raising=False)
|
||||
client = TestClient(app)
|
||||
resp = client.post(
|
||||
"/v1/sandboxes/abc12345/exec",
|
||||
json={
|
||||
"command": ["true"],
|
||||
"consumer": {"actor": "agt", "project": "glas-harness", "run_id": "run-1"},
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 503
|
||||
|
||||
|
||||
def test_exec_api_requires_bearer_and_returns_execution(monkeypatch) -> None:
|
||||
from datetime import UTC, datetime
|
||||
|
||||
monkeypatch.setenv("SANDBOXER_EXEC_TOKEN", "owner-capability")
|
||||
now = datetime.now(UTC)
|
||||
consumer = Consumer(actor="agt", project="glas-harness", run_id="run-1")
|
||||
result = SandboxExecResult(
|
||||
sandbox_id="abc12345",
|
||||
profile_id="profile.bwrap-local",
|
||||
extension_id="ext.bwrap",
|
||||
consumer=consumer,
|
||||
command_name="true",
|
||||
exit_code=0,
|
||||
duration_seconds=0.1,
|
||||
workspace_dir="/tmp/sandboxer-bwrap/abc12345",
|
||||
network_default="deny",
|
||||
started_at=now,
|
||||
completed_at=now,
|
||||
)
|
||||
payload = {
|
||||
"command": ["true"],
|
||||
"consumer": consumer.model_dump(mode="json"),
|
||||
}
|
||||
with patch("sandboxer.api.app._manager") as mgr:
|
||||
mgr.execute.return_value = result
|
||||
client = TestClient(app)
|
||||
denied = client.post(
|
||||
"/v1/sandboxes/abc12345/exec",
|
||||
json=payload,
|
||||
headers={"Authorization": "Bearer wrong"},
|
||||
)
|
||||
allowed = client.post(
|
||||
"/v1/sandboxes/abc12345/exec",
|
||||
json=payload,
|
||||
headers={"Authorization": "Bearer owner-capability"},
|
||||
)
|
||||
|
||||
assert denied.status_code == 401
|
||||
assert allowed.status_code == 200
|
||||
assert allowed.json()["exit_code"] == 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue