glas-harness/scripts/prove-credential-command-scope.py
tegwick 7357115c83
All checks were successful
ci / validate (push) Successful in 3m32s
fix(harness): limit provider credential routes to workload commands
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 07:43:50 +02:00

55 lines
3.8 KiB
Python

"""No model/provider: actual bwrap transport proof with synthetic credentials."""
import json
import os
import sys
import tempfile
from pathlib import Path
from sandboxer.extensions.bwrap import BwrapExtension
from sandboxer.models import Profile
from glas_harness.contract import SandboxHandle
from glas_harness.transport import transport_from_sandbox
def main():
with tempfile.TemporaryDirectory(prefix="glas-command-scope-") as tmp:
root = Path(tmp)
sentinel = root / "admin-sentinel"
sentinel.write_text("synthetic-file-only")
provider = root / "provider.py"
provider.write_text("import os,subprocess,sys\nenv=os.environ.copy()\nenv['ANTHROPIC_API_KEY']='synthetic-provider-only'\nraise SystemExit(subprocess.call(sys.argv[sys.argv.index('--')+1:],env=env))\n")
ext = BwrapExtension({"base_dir": str(root / "sandboxes"), "credential_routes": {
"synthetic": {"profiles":["profile.scope-proof"], "projects":["scope-proof"], "actors":["agt"], "exec_argv":[sys.executable,str(provider),"--"]}}})
context = {"actor":"agt", "project":"scope-proof", "run_id":"scope-proof-1", "profile_id":"profile.scope-proof"}
# Inherited values are synthetic. Real owner credentials are never read.
before = {key:os.environ.get(key) for key in ("BAO_TOKEN","VAULT_TOKEN","AWS_SECRET_ACCESS_KEY","SSH_AUTH_SOCK")}
for key in before:
os.environ[key] = "synthetic-inherited-only"
handle = None
try:
handle = ext.provision(Profile(id="profile.scope-proof",version="1",extension="ext.bwrap"), {}, "localhost")
ext.wait_ready(handle)
sandbox = SandboxHandle(sandbox_id=handle["sandbox_id"],host="localhost",reachability={"pid":handle["pid"],"workspace_dir":handle["workspace_dir"]})
calls=[]
def execute(argv, input_text, timeout, routes=()):
calls.append(list(routes))
raw=ext.execute(handle,argv,credential_route_refs=list(routes),execution_context=context,timeout_seconds=timeout,max_output_bytes=4096,stdin_text=input_text)
return type("Result",(),raw)()
sandbox._owner_execute=execute
sandbox._owner_workload_execute=lambda argv,stdin,timeout: execute(argv,stdin,timeout,["synthetic"])
transport=transport_from_sandbox(sandbox)
probe = "import os,pathlib,subprocess; assert not pathlib.Path("+repr(str(sentinel))+").exists(); assert all(k not in os.environ for k in "+repr(list(before))+"); assert subprocess.check_output(['python3','-c',\"import os; print(os.environ.get('BAO_TOKEN','absent'))\"]).strip()==b'absent'; "
for workload in (False,True,False):
check = probe + ("assert os.environ['ANTHROPIC_API_KEY']=='synthetic-provider-only'; print(os.environ['ANTHROPIC_API_KEY'])" if workload else "assert 'ANTHROPIC_API_KEY' not in os.environ; print('clean')")
result=(transport.run_workload if workload else transport.run)(["python3","-c",check],timeout=10)
assert result.returncode==0, result.stderr
assert result.stdout == ("[REDACTED]\n" if workload else "clean\n")
assert calls==[[],["synthetic"],[]]
finally:
teardown=ext.teardown(handle) if handle else {}
for key,value in before.items():
if value is None: os.environ.pop(key,None)
else: os.environ[key]=value
assert teardown.get("workspace_removed")=="True"
print(json.dumps({"scope":"disposable bwrap via Glas transport; not interactive assignment", "model_calls":0,"real_credentials_read":False,"host_file_denied":True,"inherited_env_and_subprocess_denied":True,"credential_routes_by_command":calls,"provider_output_redacted":True,"subsequent_command_clean":True,"workspace_removed":True}))
if __name__ == "__main__": main()