feat: enforce owner allowlisted bwrap HTTPS egress
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
This commit is contained in:
parent
d69827aaa2
commit
d477c3b5d9
11 changed files with 563 additions and 32 deletions
39
docs/bwrap-egress.md
Normal file
39
docs/bwrap-egress.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Bwrap HTTPS egress
|
||||
|
||||
Owner extension config can set `allowed_egress: [api.anthropic.com:443]`.
|
||||
A profile must declare a subset in `network.egress`, with `default: deny`.
|
||||
Defaults remain empty. Only exact lowercase DNS names ending in `:443`
|
||||
are accepted; no wildcards, IP literals, URLs or other ports.
|
||||
|
||||
Each opted-in sandbox gets a separate host-side Unix CONNECT proxy. Only that
|
||||
socket is mounted into the sandbox; an in-namespace loopback bridge provides
|
||||
HTTPS_PROXY/https_proxy to child processes. The namespace retains only lo,
|
||||
without a host interface or direct DNS/network access. The owner proxy resolves
|
||||
the declared hostname, rejects any non-global result, and connects to a checked
|
||||
numeric address without a second lookup. TLS stays between client and provider;
|
||||
system CA certificates are mounted read-only. No TLS interception or body logging.
|
||||
|
||||
This enforces connection destinations, not HTTP paths, provider account identity,
|
||||
or TLS SNI on shared hosting. A client can send arbitrary bytes to an allowed
|
||||
server. It is not an application firewall or a defense against an allowed
|
||||
provider's own forwarding features. A future stronger policy needs separate
|
||||
application enforcement. DNS resolution uses the trusted host resolver.
|
||||
|
||||
Up to 16 concurrent tunnels per sandbox, 8 KiB CONNECT headers, 10-second
|
||||
socket operations, 30-second idle and 900-second tunnel lifetime. Unsupported
|
||||
methods, hosts, ports and request framing close without upstream dialing.
|
||||
Teardown kills the dedicated proxy process and removes its socket directory.
|
||||
The current host owner must remain trusted; no caller-selected proxy config.
|
||||
|
||||
Validation: `scripts/smoke-bwrap-egress.py` made a credential-free TLS GET to
|
||||
api.anthropic.com from sandbox e290e788 and received HTTP 404. Undeclared
|
||||
example.com and direct 1.1.1.1:443 were denied, only lo existed, and proxy plus
|
||||
workspace teardown passed. This is transport evidence, not model authentication.
|
||||
Unit tests cover invalid destinations, private and mapped-loopback DNS,
|
||||
checked-address dialing, CONNECT framing and owner/profile allowlist separation.
|
||||
|
||||
Claude documents HTTPS_PROXY at https://code.claude.com/docs/en/network-config.
|
||||
The pinned Claude executable must still pass its own proxy/startup compatibility
|
||||
proof. The existing production profiles are unchanged. CCR-2026-0016 custody is
|
||||
complete at version 2, but owner machine authentication and protected credential
|
||||
delivery remain outstanding under SAND-WP-0015-T04 and GLAS-WP-0012-T02.
|
||||
|
|
@ -82,9 +82,10 @@ continues to carry exact consumer identity and value-free route references.
|
|||
|
||||
## Network and credentials remain separate gates
|
||||
|
||||
Bwrap now refuses a profile with `network.default: allow`, nonempty egress, or
|
||||
setup secret references. The implementation currently provides only a
|
||||
loopback-only network and no credential-delivery mechanism. Returning a
|
||||
Bwrap refuses `network.default: allow` and setup secret references. Network
|
||||
egress is opt-in through the owner allowlist described in bwrap-egress.md;
|
||||
empty-egress profiles retain loopback-only networking. There is still no
|
||||
credential-delivery mechanism. Returning a
|
||||
declared egress list as evidence would not make that list enforced or usable.
|
||||
Exec credential route references continue to be labels, not credential values
|
||||
or delivery grants.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue