@@ -84,11 +84,16 @@ source. Runners (`runner/` crate) hold one outbound WS (`/runner/ws`, Bearer tok
8484SHA-256-hashed registration token shown once; heartbeat cadence comes from ` hello_ack ` ),
8585connect to Docker via ` connect_with_defaults ` (local socket/pipe OR remote daemon via
8686` DOCKER_HOST ` + ` DOCKER_TLS_VERIFY ` + ` DOCKER_CERT_PATH ` , rustls), execute each job in a
87- hardened container via bollard (temp workspace bind-mounted at /workspace, tarball checkout
88- with traversal-safe extraction that also drops symlink/hardlink entries, one keep-alive
87+ hardened container via bollard (daemon-managed anonymous volume at /workspace — NOT a host
88+ bind mount, so a runner that itself runs in a container sharing the host docker.sock still
89+ gets a populated /workspace; source is streamed IN via the Docker archive API/` docker cp `
90+ after the container starts, tarball repackaged into a traversal-safe tar that strips
91+ GitHub's top-level dir and drops symlink/hardlink entries; artifacts are streamed back OUT
92+ of ` .overup/artifacts/ ` via the same archive API, one keep-alive
8993container with ` no-new-privileges ` always plus cap-drop ALL by default, memory/CPU/pids
9094limits, bridge|none|isolated per-job network, optional non-root user + read-only rootfs,
91- steps as ` exec ` with ` <shell> -c ` , SIGKILL on cancel/timeout, 5 s Docker stats sampling for
95+ steps as ` exec ` with ` <shell> -c ` , SIGKILL on cancel/timeout, container removed with its
96+ anonymous volume, 5 s Docker stats sampling for
9297CPU/memory/net/blkio metrics reported with ` job_result ` ), and stream seq-numbered log
9398chunks. ` services/log_hub.rs ` is the single log write path: mask FIRST (checkout tokens +
9499confidential-looking env values; a per-job carry buffer catches secrets split across chunk
@@ -403,7 +408,8 @@ upgrades), `dashmap` (RunnerHub connection registry + LogHub broadcast/mask maps
403408endpoint, region ` auto ` , presigned URLs; isolated in ` services/r2.rs ` ), and the local
404409` protocol ` crate (shared WS message types + HMAC helpers). The ` runner/ ` crate adds
405410` bollard ` 0.21 (Docker Engine API: image pull, container lifecycle, exec streams),
406- ` tokio-tungstenite ` (rustls), ` tar ` + ` flate2 ` (traversal-safe tarball extraction),
411+ ` tokio-tungstenite ` (rustls), ` tar ` + ` flate2 ` + ` bytes ` (repackaging the source tarball
412+ into a traversal-safe tar streamed into the container via the Docker archive API),
407413` tempfile ` (per-job workspaces). Deliberately NOT used: ` octocrab ` (the reqwest helper in
408414` services/github_app.rs ` suffices), ` git2 ` (tarball checkout via the API instead of cloning
409415— heavy native dep on Windows).
@@ -500,9 +506,13 @@ endpoint, region `auto`, presigned URLs; isolated in `services/r2.rs`), and the
500506- List filters are validated before SQL: status/conclusion/trigger allow-lists, length caps
501507 on branch/search/timestamps, and free-text search runs through a server-built ILIKE
502508 pattern with ` \ ` , ` % ` , ` _ ` escaped — user text only ever matches literally
503- - Execution isolation (reference runner): per-job temp workspaces (deleted after), tarball
504- extraction drops non-` Normal ` path components AND symlink/hardlink entries (traversal
505- defense — a link target can't be validated by path checks), 1 GiB tarball cap, jobs run
509+ - Execution isolation (reference runner): /workspace is a daemon-managed anonymous volume
510+ (removed with the container), NOT a host bind — source is repackaged into a
511+ traversal-safe tar (top-level dir stripped, non-` Normal ` path components AND
512+ symlink/hardlink entries dropped — a link target can't be validated by path checks) and
513+ streamed IN over the Docker archive API after the container starts (so a containerized
514+ runner sharing the host docker.sock still sees a populated /workspace); artifacts are
515+ streamed back OUT of ` .overup/artifacts/ ` the same way, 1 GiB tarball cap, jobs run
506516 in Docker containers with ` no-new-privileges ` always set, ** capabilities dropped by
507517 default** (` RUNNER_CAP_DROP=false ` to opt out), memory/CPU/pids limits
508518 (` RUNNER_JOB_MEMORY_BYTES ` /` RUNNER_JOB_NANO_CPUS ` /` RUNNER_JOB_PIDS_LIMIT ` , 0 disables),
0 commit comments