feat(web): add public agent-binary download endpoint that proxy-streams from Forgejo (VS-56) #74

Merged
nrupard merged 2 commits from feat/VS-56-public-agent-binary-download into main 2026-06-26 16:42:41 +02:00
Member

Add GET /api/v1/agent/binary/:id on the API server, which opens a live read of the configured upstream source (settings.agentbinaryfetcher, normally a Forgejo Generic Package registry) and streams the vervainagent- blob straight through to the client. This lets agents fetch their binary directly from the API instead of via the session-gated frontend proxy (parent VS-54), while keeping the read-only service-account token server-side: it is only sent in the outbound Authorization header to the registry, never echoed in a response header, body, or redirect.

Bytes are streamed chunk by chunk rather than buffered: a new BinarySource::stream_binary returns a StreamedBinary (boxed byte stream plus optional upstream Content-Length). The default impl buffers via fetch_binary so non-streaming sources and test doubles need no extra code; HttpSource and ForgejoSource override it to forward reqwest's bytes_stream without reading the body into memory. The handler reuses the hot-swappable refresher's source, so a live settingsupdate that swaps the source is picked up automatically.

Unknown ids surface as SourceError::BadStatus{404} and map to a clean 404; any other upstream error logs server-side and returns 502 without leaking the registry URL. The path is published as wire_paths::AGENT_BINARY_DOWNLOAD_PATH for the frontend repoint (VAPP-35) to mirror. Client-facing authorization is tracked in VS-57 and is required before public exposure.

#VS-56

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

Add GET /api/v1/agent/binary/:id on the API server, which opens a live read of the configured upstream source (settings.agentbinaryfetcher, normally a Forgejo Generic Package registry) and streams the vervainagent-<id> blob straight through to the client. This lets agents fetch their binary directly from the API instead of via the session-gated frontend proxy (parent VS-54), while keeping the read-only service-account token server-side: it is only sent in the outbound Authorization header to the registry, never echoed in a response header, body, or redirect. Bytes are streamed chunk by chunk rather than buffered: a new BinarySource::stream_binary returns a StreamedBinary (boxed byte stream plus optional upstream Content-Length). The default impl buffers via fetch_binary so non-streaming sources and test doubles need no extra code; HttpSource and ForgejoSource override it to forward reqwest's bytes_stream without reading the body into memory. The handler reuses the hot-swappable refresher's source, so a live settingsupdate that swaps the source is picked up automatically. Unknown ids surface as SourceError::BadStatus{404} and map to a clean 404; any other upstream error logs server-side and returns 502 without leaking the registry URL. The path is published as wire_paths::AGENT_BINARY_DOWNLOAD_PATH for the frontend repoint (VAPP-35) to mirror. Client-facing authorization is tracked in VS-57 and is required before public exposure. #VS-56 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(web): add public agent-binary download endpoint that proxy-streams from Forgejo (VS-56)
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 3m11s
e713628ee0
Add GET /api/v1/agent/binary/:id on the API server, which opens a live read of the configured upstream source (settings.agentbinaryfetcher, normally a Forgejo Generic Package registry) and streams the vervainagent-<id> blob straight through to the client. This lets agents fetch their binary directly from the API instead of via the session-gated frontend proxy (parent VS-54), while keeping the read-only service-account token server-side: it is only sent in the outbound Authorization header to the registry, never echoed in a response header, body, or redirect.

Bytes are streamed chunk by chunk rather than buffered: a new BinarySource::stream_binary returns a StreamedBinary (boxed byte stream plus optional upstream Content-Length). The default impl buffers via fetch_binary so non-streaming sources and test doubles need no extra code; HttpSource and ForgejoSource override it to forward reqwest's bytes_stream without reading the body into memory. The handler reuses the hot-swappable refresher's source, so a live settingsupdate that swaps the source is picked up automatically.

Unknown ids surface as SourceError::BadStatus{404} and map to a clean 404; any other upstream error logs server-side and returns 502 without leaking the registry URL. The path is published as wire_paths::AGENT_BINARY_DOWNLOAD_PATH for the frontend repoint (VAPP-35) to mirror. Client-facing authorization is tracked in VS-57 and is required before public exposure.

#VS-56

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ci: compile-check with cargo check, not the disk-bombing build --all-targets
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 1m33s
Create release / Create release from merged PR (pull_request) Has been skipped
02e2e8d86e
The Check workflow ran cargo build --all-targets, which links every integration-test binary (tls_smoke, mcp_gateway, device_file, control_token, login, setup, relay_listing, admin), each statically linking the full wasmtime/leptos/aws-lc/rustls closure. Linking those in parallel exhausted the runner's disk and the link died with ENOSPC / lld SIGBUS, failing the check even though the code is fine.

Those executables are never run: CI only runs cargo test --lib. And clippy --all-targets, which runs first, already typechecks every target. So the build step was pure waste whose only effect was filling the disk. Replace it with cargo check --workspace --all-targets, which verifies all targets compile without producing the binaries, matching the local just check-compile recipe. The just pre-commit hook carried the same wasteful build --all-targets; switch it to cargo check too so local and CI stay in lockstep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch feat/VS-56-public-agent-binary-download 2026-06-26 16:42:41 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-server!74
No description provided.