Skip to content

feat(website): record a website env's traffic as PCAP, served through traffic/v1 (FD-4683) - #469

Open
williamloo-scale wants to merge 8 commits into
wloo/website-computer-routingfrom
wloo/website-traffic-capture
Open

williamloo-scale wants to merge 8 commits into
wloo/website-computer-routingfrom
wloo/website-traffic-capture

Conversation

@williamloo-scale

@williamloo-scale williamloo-scale commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #448.

A website env can record every packet its websites' server and frontend containers send and receive, as PCAP, and serve the files through its card. This is opt-in.

  • Turning it on: deploy_env takes capture_traffic, and agent-env env deploy takes --capture-traffic. It works for a website env, or a multi env with a website, on a VM. Any other env, and container mode, refuse it.

  • Capture: each website container gets a tcpdump service beside it.

    • tcpdump comes from the gateway image and runs in that container's network namespace (network_mode: "service:<container>").
    • It's the only service holding NET_RAW/NET_ADMIN.
    • It writes rotating classic pcap files, 10 of 20 MB each with the oldest overwritten, to a volume no website container mounts. The gateway mounts it read-only.
    • The deploy is refused if a capture isn't running once the gateway is up.
  • Protocol: the new agentenv_protocol.traffic defines urn:agentenv:traffic/v1 with two ops:

    • list returns a TrafficCaptureListing, oldest file first;
    • get streams one file as application/vnd.tcpdump.pcap.

    Client helpers: list_traffic_captures, fetch_traffic_capture, serves_traffic. The gateway's constants.py mirrors the names, with a test keeping them equal.

  • Access: both ops require the per-deploy control token (DeployedEnv.control_token). The gateway removes Authorization from a proxied request only when it carries that token (compared with hmac.compare_digest), so no site can read the token, and a site's own bearer auth still reaches it.

  • Collection: the new collect_traffic_capture step stores each capture as a pcap FileArtifact in one FileArtifactUniverse, recorded under context.metadata["traffic_captures"][env_id]. It's best effort unless fail_task_on_error is set. Teardown also collects any capturing env the run didn't collect, before the env closes, so a capture isn't lost with its VM.

Before merging

  • Not yet run on a deployed VM. The compose wiring, gateway routes, token stripping, step and teardown are covered by unit tests.

Test

Unit suite on this branch: 13,358 passed, lint clean. One GitHub-clone test from main is deselected because it hangs on the local machine on main too.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The documentation-only update appears safe to merge.

Summary

Adds opt-in website traffic capture, token-protected downloads through traffic/v1, and collection into file artifacts before teardown.

  • Website deployments can record traffic from their server and frontend containers.
  • The gateway lists and streams pcap captures through a token-protected traffic API.
  • Task runs can save website traffic captures and collect missed files during teardown.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Site[Website container] -->|shared network namespace| Capture[tcpdump sidecar]
  Capture --> Volume[Rotating PCAP files]
  Volume -->|read-only mount| Gateway[Gateway traffic/v1]
  Gateway -->|control token required| Collect[Collection step or teardown]
  Collect --> Files[File artifacts and universe]
  Files --> Run[Saved run metadata]
Loading

Reviews (11) · Last reviewed commit: "docs(website): traffic capture records w..." · Reviewed by Greptile

@williamloo-scale
williamloo-scale requested a review from a team as a code owner November 3, 2026 21:53
Comment thread src/agent_env/env/gateway/gateway.py Resolved
Comment thread src/agent_env/env/gateway/gateway.py Resolved
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from a767a25 to d160d31 Compare November 3, 2026 22:52
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 194572e to 3b757da Compare November 3, 2026 22:52
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from d160d31 to 5953d5a Compare November 3, 2026 23:53
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 3b757da to 73241f9 Compare November 4, 2026 00:00
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from 5953d5a to 9f2a5ca Compare November 4, 2026 00:32
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 73241f9 to 0192f08 Compare November 4, 2026 00:33
Comment thread src/agent_env/task/teardown.py Resolved
Comment thread src/agent_env/task/teardown.py Resolved
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from 0cca3db to a1ec8b4 Compare November 4, 2026 03:37
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 965deb7 to 9ac178a Compare November 4, 2026 03:37
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from a1ec8b4 to d044c00 Compare November 4, 2026 03:56
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 9ac178a to 0e9e82d Compare November 4, 2026 03:56
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from d044c00 to f813a59 Compare November 4, 2026 05:07
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from 0e9e82d to dcc3d9f Compare November 4, 2026 05:07
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from f813a59 to faf8e7c Compare November 4, 2026 05:10
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from dcc3d9f to bdec057 Compare November 4, 2026 05:10
williamloo-scale and others added 3 commits November 3, 2026 21:16
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…refix of its own, and capture loopback too (FD-4683)

- The gateway's traffic/v1 get copies a capture before sending any of it, copying again when tcpdump truncates the
  file to reuse it, and answers 503 when every copy was rewritten.
- collect_traffic_capture writes each collection under its own attempt prefix, and the upload owns its temp file
  (finish_on_thread), so a cancelled collection never removes a file an upload still reads.
- tcpdump captures every interface of the container, its loopback among them.
- The read size and error limits are named.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… the env closes (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale and others added 4 commits November 3, 2026 21:16
…collects a retry's rolled-back deployments too (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…time runs out partway (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… stored linked to the run as partial (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…thread, so teardown's time limit holds (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from faf8e7c to 27a865f Compare November 4, 2026 05:16
@williamloo-scale
williamloo-scale force-pushed the wloo/website-traffic-capture branch from bdec057 to 46aa361 Compare November 4, 2026 05:16
…nd from just after each starts, not before (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant