sharness.ai / evidence · this page as markdown

Evidence

Every figure on this page was observed as of 24 Oct 2026, in one Claude agent workspace (claude.ai, cloud session). One environment, one day. Re-run the probes before relying on them elsewhere: other platforms, and later versions of this one, may differ.

Three labels are used across the site, and this page is where they are earned:

LabelMeans
measuredprobed or timed in the environment below, with the method stated
designed / proposeda description of how SHarness would work; nothing is built
not yet measurednamed in the design, not tested: seccomp filters, read-only bind mounts, every side door on Enforcing the process tree, and AWS KMS compatibility

1. The environment

FactObserved
IsolationFirecracker microVM; PID 1 is /process_api --firecracker-init … (not systemd)
OS / kernelUbuntu 24.04.5, Linux 6.18.44, x86_64
Agent's identityuid 0 (root), full capability set (CapEff 000001fffeffffff)
Hardening presentno seccomp, NoNewPrivs 0, no Yama (/proc/sys/kernel/yama absent)
Core dumpsulimit -c 0; core_pattern = core
Python / cryptoPython 3.13.17; cryptography 50.0.1
sgitpip install sgit-ai → 0.24.0 (the version the origin article analysed, at commit 182cfc1)
Hardware keysno /dev/tpm*
Egressevery outbound HTTPS goes through a platform proxy at 127.0.0.1:43305; send.sgraph.ai, pki.sgit.ai, cli.sgit.ai reachable (HTTP 200)
Scratch spacethe agent's scratchpad is root-only (other uids get EACCES)
Process lifetimeper the platform: a process detached with nohup/& is stopped within minutes of the agent's reply; a tool-managed background process can run up to 2 h. Not measured
Firewall toolsiptables, nft present; OUTPUT policy ACCEPT, empty
cgroupsv1: blkio, cpu, cpuacct, cpuset, devices, freezer, memory, pids, systemd, unified
FUSE/dev/fuse (root-only), fusermount3 present

Kernel configuration (/proc/config.gz)

OptionValueRelevance
CONFIG_SECURITY_LANDLOCKy (ABI 7)file and TCP port sandboxing
CONFIG_SECCOMPysyscall allowlists
CONFIG_SECRETMEMymemfd_secret
CONFIG_CGROUP_FREEZERyfreeze the KMS between calls
CONFIG_CHECKPOINT_RESTOREyCRIU possible (binary not installed)
CONFIG_FUSE_FSysharness.fs as a mount
CONFIG_ASYMMETRIC_KEY_TYPEykernel asymmetric keys …
CONFIG_PKCS8_PRIVATE_KEY_PARSERnot set… but no private keys, so kernel-held decryption is unavailable
CONFIG_TRUSTED_KEYSnot set(needs a TPM anyway)
CONFIG_ENCRYPTED_KEYSysymmetric blobs only

2. sgit 0.24.0, checked

Claim (from the origin article)ResultMethod
pki keygen makes RSA-OAEP 4096 + ECDSA P-256, sha256: + 16 hex✔ran it with a throwaway HOME
private keys encrypted with PBKDF2 at 2,048 iterations✔ INTEGER :0800 on both private_key.pem and signing_private.pemopenssl asn1parse
Secrets__Store uses a fixed salt✔ salt = f'{SECRETS_SALT_PREFIX}:master'source
BestAvailableEncryption used for keys✔ crypto/PKI__Crypto.py:37source
the vault key is read in many places65 references in 23 files for _read_vault_key|load_vault_key|vault_key_path (broad grep including imports; the article counts 27 read sites in 17 files)grep
key file modespublic_key.pem 0644; private PEMs 0600ls -l

3. Memory

ProbeResult
prctl(PR_SET_DUMPABLE, 0), then root reads /proc/<pid>/memsecret found: root's CAP_SYS_PTRACE overrides
mlock / mlockallsucceed
memfd_secret (syscall 447)available
root reads a memfd_secret page through /proc/<pid>/memEIO
RSA-4096 OAEP open → copy into a secret page → no scrub; root sweeps all readable mappingsone copy found in the anonymous heap
the same, with scrubbing the returned bytesno copy found
RSA-4096 OAEP open time3.2–3.6 ms
kernel keyring add_key (process keyring)works
user keyring entry persists across separate agent tool calls✔
key in uid sgit-dec's user keyring, searched by uid sgit-runENOKEY
that key in root's /proc/keysnot listed
add_key("asymmetric", <PKCS#8 RSA-4096 DER>)EBADMSG (parser not built)
cgroup freezer: freeze / thaw a process (average of 20)0.28 ms / 0.13 ms; frozen state D

4. Process isolation

ProbeResult
create system users (useradd -r -M -s nologin)✔
setpriv --reuid --regid --clear-groups --no-new-privs --inh-caps=-all --bounding-set=-allCapEff 0, CapBnd 0, NoNewPrivs 1
another uid reads a root filedenied
unshare --net, then connect outENETUNREACH (101)
unshare --user --map-root-user --pid --fork --mount-proc✔
Landlock ABI7
RLIMIT_NPROC=0, then forkEAGAIN (blocked)
Landlock fs (read-only /usr /etc /lib /lib64 /proc): read /etc/hostnameallowed
Landlock fs: read a file elsewhereEACCES
Landlock fs: write /tmp/xEACCES
Landlock net (connect only to 43305): proxy portallowed
Landlock net: 127.0.0.1:22, 1.1.1.1:443EACCES
iptables -A OUTPUT -m owner --uid-owner <user> -j REJECTaccepted
SO_PEERCRED on a Unix socketreturns pid, uid, gid
abstract-namespace Unix socket✔
ephemeral user + firewall rule + locked launch + teardown (average of 10)49 ms
new net + pid + mount namespaces (average of 10)3.7 ms
seccomp filteravailable, not tested

5. Footprint

strace -f (file, network, process, ipc), successful opens only.

CommandPaths openedFoldersDistinct syscallsexecvesocket / connect
python3 -I -c print(1)39213110
sgit --version1,1042123810
sgit pki list1,1092153910
import sgit_ai.cli.CLI__Main529 modules, 146 ms
bare python3 -I -c pass start15 ms

6. Transport

Python ssl, TLS 1.3, P-256; the server is a thread in the benchmark process.

Connect + handshake600 B round tripBulk (64 MiB echo)
TCP plain0.10 ms15 µs~300 MB/s
TCP mutual TLS3.2 ms67 µs~320 MB/s
Unix plain0.09 ms56 µs~320 MB/s
Unix mutual TLS3.4 ms74 µs~420 MB/s
pipe to a separate process—34 µs—
TCP mutual TLS without server TCP_NODELAY46 ms

Session CA + four role certificates (P-256, 2 h validity): 24 ms.

Edge enforcement with roles in subjectAltName URIs, policy fs←{cli}, net←{cli}, kms←{net} (the probe named the app role cli, as sgit's CLI):

cli → fs   OK        fs  → kms  DENY
cli → net  OK        cli → kms  DENY
net → kms  OK        fs  → net  DENY

Figures are from the final of three runs. Across runs, round trips and bulk varied by up to ~25% (TCP mutual TLS bulk: 250, 275, 318 MB/s; Unix mutual TLS bulk: 349, 378, 418 MB/s); handshake times were stable. Microsecond figures are noisy because the server thread shares Python's interpreter lock with the client: treat them as upper bounds.

7. The agent loop in this environment (read-only observation)

Observed as of 24 Oct 2026; may differ elsewhere. Method: ps --forest, /proc/net/tcp mapped to socket inodes, environment variable names only, findmnt. TLS traffic was not inspected, no credentials or session identifiers were captured, and no configuration was changed.

ItemObserved
PID 1/process_api --firecracker-init … --block-local-connections
PID 89environment-manager task-run --stdin …, root; its own HTTPS connections to the model API address
PID 96/opt/claude-code/bin/claude, Claude Code 2.1.42, root; ~18 established HTTPS connections to the model API address; listens on a local port
the agent's Bashdirect child of PID 96
other processessbx-telemetry-collector (own uid), rclone-filestore multimount
model endpointANTHROPIC_BASE_URL=https://api.anthropic.com; /etc/hosts pins it; it is in no_proxy, so model calls bypass the egress proxy
credentialscarried in ANTHROPIC_CUSTOM_HEADERS; value deliberately not read
harness flags (names / booleans only)CLAUDE_CODE_REMOTE=true, CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1, CCR_AGENT_PROXY_ENABLED=1, CCR_UPSTREAM_PROXY_ENABLED=1, CLAUDE_CODE_PROXY_RESOLVES_HOSTS=true
/opt/claude-coderead-only mount
/root/.claude/settings.jsonwritable by root; no managed settings under /etc/claude-code/
/etc/hostswritable by root; its mtime changed mid-session
kernel cmdlinenomodule

8. Left in the environment

The probes left users sgit-dec and sgit-run, a folder of probe scripts (/opt/sgit-probe/) and a user-keyring entry sgit:persist-probe (root). All died with the VM.

Not yet measured

Source: 04-environment-evidence.