Release-note fact check — anthropic-experimental/sandbox-runtime

v0.0.65 → v0.0.66 · 43 commits · 24 files · +3732/−80 · judge: claude-cli/haiku
78minor gaps
100
correctness
claims supported
13
completeness
churn documented
100
risk
100 − flag penalties
repo: TypeScript 99% · JavaScript 1% · Shell 0% · 1.6 MB code
release cadence ~6 d
baseline (5 rel.): median churn ±7797 Churn per release (oldest → newest) v0.0.61: 4451 v0.0.62: 7797 v0.0.63: 10552 v0.0.64: 14212 v0.0.65: 3488 · coverage 23% Note coverage % per release (oldest → newest) v0.0.61: 23 v0.0.62: 43 v0.0.63: 17 v0.0.64: 41 v0.0.65: 23

Score derivation — components, flag penalties and the hard cap, per SCORING.md

0255075100perfect releaseperfect release100correctness 100 × 0.45 weighted share of claims the diff supportscorrectness 100 × 0.450completeness 13 × 0.25 churn-weighted share of commits the notes covercompleteness 13 × 0.25−21.8risk 100 × 0.3 no flag penaltiesrisk 100 × 0.3078/100 minor gaps78/100 minor gaps78

Claims at a glance

verified 8partial 0no-evidence 0contradicted 0skipped 2

Risk flags

No risk flags.

Diff map — tile = file, size = changed lines, color = documentation status, amber border = sensitive path, click opens the diff

test/sandbox/credential-mask-files.test.ts ±716 lines · evidence fns: describe, describe.if (click to open the compare view)credential-mask-files.test.tstest/sandbox/credential-mask.test.ts ±575 lines · evidence fns: describe, describe.if (click to open the compare view)credential-mask.test.tstest/sandbox/credential-mask-body.test.ts ±472 lines · covered (click to open the compare view)credential-mask-body.test.tstest/config-validation.test.ts ±374 lines · evidence fns: describe (click to open the compare view)config-validation.test.tstest/sandbox/credential-decode.test.ts ±280 lines · covered (click to open the compare view)credential-decode.test.tssrc/sandbox/sandbox-config.ts ±247 lines · evidence fns: z.string, z.object (click to open the compare view)sandbox-config.tstest/sandbox/body-substitution.test.ts ±213 lines · covered (click to open the compare view)body-substitution.test.tssrc/sandbox/body-substitution.ts ±164 lines · covered (click to open the compare view)body-substitution.tssrc/sandbox/credential-decode.ts ±162 lines · covered (click to open the compare view)credential-decode.tssrc/sandbox/credential-mask-files.ts ±150 lines · evidence fns: MaskedFileBuildResult, buildMaskedFileBinds (click to open the compare view)credential-mask-files.tssrc/sandbox/credential-sentinel.ts ±104 lines · covered fns: SentinelEntry, SentinelRegistry (click to open the compare view)credential-sentinel.tssrc/sandbox/credential-mask-env.ts ±83 lines · covered fns: MaskedEnvBuildResult, buildMaskedEnvVars (click to open the compare view)credential-mask-env.tssrc/sandbox/sandbox-utils.ts ±45 lines · evidence fns: generateProxyEnvVars (click to open the compare view)sandbox-utils.tstest/sandbox/proxy-env-vars.test.ts ±43 lines · evidence fns: describe (click to open the compare view)proxy-env-vars.tsrc/sandbox/http-proxy.ts ±41 lines · covered fns: HttpProxyServerOptions, createHttpProxyServer (click to open the compare view)http-proxy.tstest/sandbox/credential-mask-env.test.ts ±39 lines · covered fns: describe.if (click to open the compare view)credential-massrc/sandbox/tls-terminate-proxy.ts ±35 lines · covered fns: terminateAndForward, forwardUpstream (click to open the compare view)tls-terminasrc/sandbox/sandbox-manager.ts ±22 lines · evidence fns: buildCredentialInjector, startMuxProxyServer, checkDependencies (click to open the compare view)test/sandbox/wrap-with-sandbox.test.ts ±19 lines · evidence fns: describe (click to open the compare view)src/sandbox/linux-sandbox-utils.ts ±11 lines · evidence fns: wrapCommandWithSandboxLinux (click to open the compare view)src/sandbox/credential-extract.ts ±9 lines · covered fns: ReplacementSpan, extractAndSubstitute (click to open the compare view)package-lock.json ±4 lines · evidence · sensitive: dependencies (click to open the compare view)package.json ±2 lines · evidence · sensitive: dependencies (click to open the compare view)src/sandbox/request-filter.ts ±2 lines · covered fns: MutateForwardedHeaders (click to open the compare view)
cited as evidence in documented commit undocumented unknown sensitive path (border)

Claims in detail

What's Changed

verified Add maskClaims for claim-level masking inside decoded JWTs by @elhajjj in #373 0.95
The diff adds a `maskClaims` configuration field to CredentialFileConfigSchema in sandbox-config.ts with full documentation; implements claim-level masking in credential-mask-files.ts via a new conditional block that calls `maskJwtClaims()` and registers per-claim sentinels; and includes comprehensive unit and end-to-end tests in credential-mask-files.test.ts demonstrating the feature masks named claims inside JWT payloads while preserving other claims real.
src/sandbox/credential-mask-files.ts, src/sandbox/sandbox-config.ts, test/config-validation.test.ts, test/sandbox/credential-mask-files.test.ts
fns: mintFakeJwt, MaskedFileBuildResult, buildMaskedFileBinds, z.string, z.object, describe, describe.if
commits: 2acd4d8c
verified Add decode:"jwt" for env vars holding JWTs by @elhajjj in #374 0.95
The diff adds `decode: z.enum(['jwt']).optional()` to CredentialEnvVarConfigSchema in sandbox-config.ts. Implementation in sandbox-manager.ts (line 729+) checks `if (v.decode === 'jwt')`, verifies the value with `verifyJwt()`, and replaces it with a fake JWT via `mintFakeJwt()`. Comprehensive test coverage in credential-mask.test.ts validates the feature end-to-end, including verification, fake-JWT generation, proxy token substitution, and fail-open behavior for non-JWT values.
fns: z.object, checkDependencies, getCredentialRestrictions, describe, describe.if
commits: a989994b
verified Add maskClaims for env vars holding JWTs by @elhajjj in #376 0.95
The diff shows two new test suites ('env maskClaims masking on Linux (bwrap)' and 'end-to-end env maskClaims via SandboxManager') with comprehensive tests for maskClaims on JWT environment variables, including sentinel replacement, registry mappings, and proxy substitution. Configuration validation code in sandbox-config.ts enforces maskClaims constraints for envVars (requires decode, rejects empty list). The tests explicitly verify that named claims are masked with sentinels while other claims
src/sandbox/credential-mask-files.ts, src/sandbox/sandbox-config.ts, src/sandbox/sandbox-manager.ts, test/config-validation.test.ts, test/sandbox/credential-mask-files.test.ts, test/sandbox/credential-mask.test.ts
fns: mintFakeJwt, MaskedFileBuildResult, buildMaskedFileBinds, z.string, z.object, checkDependencies, getCredentialRestrictions, describe
commits: e9d60942
verified Add decode option for encoded credential formats, starting with JWT by @elhajjj in #362 0.98
The diff adds a new `decode` configuration option for credentials: src/sandbox/credential-decode.ts introduces JWT verification and masking functions (verifyJwt, maskJwtClaims, mintFakeJwt), and src/sandbox/credential-mask-env.ts implements the logic checking `if (v.decode === 'jwt')` to apply JWT-specific masking. Comprehensive tests in credential-decode.test.ts verify the JWT implementation. This directly implements the claimed feature.
fns: ReplacementSpan, extractAndSubstitute, MaskedEnvBuildResult, buildMaskedEnvVars, MaskedFileBuildResult, buildMaskedFileBinds, SentinelEntry, SentinelRegistry
commits: 6def5683
verified fix(linux): force --unshare-user + --cap-drop ALL in secure bwrap branch (H1 #3845682) by @seanyeoh-ant in #390 0.95
The diff shows `bwrapArgs.push('--unshare-user', '--cap-drop', 'ALL', '--proc', '/proc')` added to the secure branch (`if (!enableWeakerNestedSandbox)`), replacing the previous `--proc /proc` only. A test has been added that explicitly asserts both `--unshare-user` and `--cap-drop ALL` are present in secure-mode output.
src/sandbox/linux-sandbox-utils.ts, test/sandbox/wrap-with-sandbox.test.ts
fns: wrapCommandWithSandboxLinux, describe
commits: cf24a43e
verified Substitute masked credentials in request bodies at the TLS-terminating proxy by @elhajjj in #399 0.95
The diff shows a complete implementation of masked-credential substitution in request bodies: new `body-substitution.ts` module handles streaming sentinel→real substitution; `tls-terminate-proxy.ts` integrates it via `prepareBodySubstitution()` call; `http-proxy.ts` adds `getBodySubstitutions` option for the TLS-terminated path; comprehensive test file (`credential-mask-body.test.ts`) validates substitution across JSON, form-urlencoded, and multipart body formats.
fns: SentinelRegistry, HttpProxyServerOptions, createHttpProxyServer, MutateForwardedHeaders, buildCredentialInjector, startMuxProxyServer, terminateAndForward, forwardUpstream
commits: e5b3778e
verified Advertise the HTTP CONNECT proxy in GRPC_PROXY instead of socks5h by @shawnm-anthropic in #409 0.98
The diff shows GRPC_PROXY/grpc_proxy variables changed from `socks5h://${auth}localhost:${socksProxyPort}` (removed code) to `${connectProxyUrl}` where connectProxyUrl resolves to `http://${auth}localhost:${httpProxyPort}` when an HTTP proxy port exists. Tests confirm the new behavior advertises http:// URLs with fallback to socks5h only when no HTTP proxy is configured. Comments explain gRPC C-core compatibility requirements for HTTP CONNECT proxies.
src/sandbox/sandbox-utils.ts, test/sandbox/proxy-env-vars.test.ts
fns: generateProxyEnvVars, describe
commits: 48b9f1d9
verified Release v0.0.66 by @shawnm-anthropic in #410 0.95
The diff shows package.json version bumped from 0.0.65 to 0.0.66, and the linked commit explicitly states 'Merge pull request #410 from anthropic-experimental/release/v0.0.66 (by shawnm-anthropic)', directly confirming all three elements of the claim: the v0.0.66 release, authorship by shawnm-anthropic, and PR #410.
package.json, package-lock.json
commits: 03bcd3da

New Contributors

skipped @seanyeoh-ant made their first contribution in #390
skipped **Full Changelog**:

Undocumented commits

commitsubjectchurnfiles
3248f1f6Merge main (through #389) into decode stack+7881/−997556
0924646bMerge main (#333 onExtractNoMatch) into decode: jwt+1548/−221616
fb8e15dfMerge main (#361 maskDuplicates) into decode: jwt+1440/−157527
b0e65655Integration tests: body substitution through the terminating proxy (JSON, form, multipart, gzip, framing)+472/−01
1938728aUnit tests: boundary-offset sweep, backpressure, framing gates for body substitution+200/−01
515ebe64Wire body sentinel substitution into the TLS-terminated and plaintext proxy paths+118/−44
e134ba2bAdd streaming sentinel substitution transform for request bodies+109/−01
d6ef651ffeat(credentials): maskJwtClaims helper — rebuild token with per-claim sentinels+76/−01
bb928bd5Registry: length-matched sentinel minting and per-host sentinel pairs accessor+57/−21
c0a7836aAdd JWT verification helper and default extraction pattern+48/−01
af0299bdSupport caller-minted sentinels in SentinelRegistry+38/−41
2e10cbb5Add mintFakeJwt helper for JWT-shaped sentinels+40/−21
2e7f0bdce2e: sandboxed POST body reaches injectHost with the real secret via SandboxManager+32/−21
be94f5b1Substitute in bodyless-method requests that declare a body (GET-with-body)+22/−12
916504c6Document the no-nested-sentinels caller contract and the scan's earliest-match discipline+9/−12