feat(agent): extract pushed-artifact add-on tarballs (delivery-models 1.2) (#3425) #3468

Merged
mfreeman451 merged 1 commit from feat/addon-pushed-tarball into staging 2026-05-31 16:16:35 +00:00
Owner

What

delivery-models task 1.2 (agent-side tarball delivery). A pushed-artifact add-on can now be a gzip tarball bundling the binary + its addon.yaml/config.schema.json + any .service/.timer units — not just a bare executable.

stageAddonArtifact auto-detects gzip (a bare binary still works unchanged for single-binary agent-sidecar add-ons), verifies the sha256/signature over the raw artifact bytes, and extracts the tarball into the versioned staging dir so the binary and its units land side-by-side under current/ — exactly where the agent discovers units and the root-owned updater applies setcap / installs systemd units.

This is the missing delivery link: it's what gets the .service/.timer files to the agent so the systemd supervision dispatch (the supervision slice) can install them.

Security

Extraction is hardened against hostile/malformed artifacts:

  • every entry must be a regular file named as a single safe path segment — rejects ../ traversal, subdirectories, symlinks, and hardlinks (ErrAddonTarballUnsafe);
  • bounded entry count (64) and per-file (512 MiB) / total (1 GiB) sizes, with a hard read cap independent of the declared header size — decompression-bomb guard (ErrAddonTarballTooLarge);
  • the declared binary must be present (ErrAddonTarballBinaryMissing);
  • binary written 0755, all other files 0644.

Verification

Unit tests: tarball extraction (binary executable + manifest/units 0644 under current/), missing-binary, unsafe entries (traversal / subdir / symlink), too-many-entries; bare-binary delivery regression intact. go build/vet/golangci-lint clean. (Extraction is platform-agnostic; the downstream setcap/systemctl were host-verified in the prior slices.)

Scope / follow-ups

  • Off staging, independent of the supervision-dispatch PR (different files); they compose when both land.
  • Build-side production of the per-arch tarball (the assembler/inventory + the signed-publish pipeline) is the complementary build-signing follow-up; this PR makes the agent ready to receive them.

🤖 Generated with Claude Code

## What delivery-models **task 1.2** (agent-side tarball delivery). A pushed-artifact add-on can now be a **gzip tarball** bundling the binary + its `addon.yaml`/`config.schema.json` + any `.service`/`.timer` units — not just a bare executable. `stageAddonArtifact` auto-detects gzip (a bare binary still works unchanged for single-binary `agent-sidecar` add-ons), verifies the sha256/signature over the raw artifact bytes, and extracts the tarball into the versioned staging dir so the binary and its units land **side-by-side under `current/`** — exactly where the agent discovers units and the root-owned updater applies `setcap` / installs systemd units. This is the missing delivery link: it's what gets the `.service`/`.timer` files to the agent so the systemd supervision dispatch (the supervision slice) can install them. ## Security Extraction is hardened against hostile/malformed artifacts: - every entry must be a **regular file** named as a **single safe path segment** — rejects `../` traversal, subdirectories, symlinks, and hardlinks (`ErrAddonTarballUnsafe`); - **bounded** entry count (64) and per-file (512 MiB) / total (1 GiB) sizes, with a hard read cap independent of the declared header size — decompression-bomb guard (`ErrAddonTarballTooLarge`); - the declared binary must be present (`ErrAddonTarballBinaryMissing`); - binary written `0755`, all other files `0644`. ## Verification Unit tests: tarball extraction (binary executable + manifest/units `0644` under `current/`), missing-binary, unsafe entries (traversal / subdir / symlink), too-many-entries; **bare-binary delivery regression intact**. `go build`/`vet`/`golangci-lint` clean. (Extraction is platform-agnostic; the downstream `setcap`/`systemctl` were host-verified in the prior slices.) ## Scope / follow-ups - Off `staging`, independent of the supervision-dispatch PR (different files); they compose when both land. - Build-side **production** of the per-arch tarball (the assembler/inventory + the signed-publish pipeline) is the complementary build-signing follow-up; this PR makes the agent **ready to receive** them. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(agent): extract pushed-artifact add-on tarballs (delivery-models 1.2) (#3425)
Some checks failed
Secret Scan / gitleaks (pull_request) Successful in 22s
lint / lint (push) Successful in 1m20s
lint / lint (pull_request) Successful in 1m47s
Golang Tests / test-go (push) Successful in 3m3s
CI / build (pull_request) Failing after 2m44s
396f67bf5f
A pushed artifact can now be a gzip tarball bundling the add-on binary plus its
manifest/config and systemd unit files, not just a bare executable. stageAddonArtifact
auto-detects gzip (vs a bare binary, which still works unchanged), verifies the
sha256/signature over the raw artifact bytes, and extracts the tarball into the
versioned staging dir so the binary and its units land side-by-side under `current/` --
which is exactly where the agent discovers units and the root-owned updater applies
setcap / installs systemd units.

This is the delivery mechanism that gets .service/.timer units to the agent (the
discovery + systemd dispatch from the supervision slice consumes them).

Extraction is hardened against hostile/malformed artifacts: every entry must be a
regular file named as a single safe path segment (rejects traversal, subdirs, symlinks,
hardlinks); entry count and per-file/total sizes are bounded (decompression-bomb guard);
the declared binary must be present. The binary is written 0755, all other files 0644.

Tested: tarball extraction (binary executable + units/manifest 0644 under current/),
missing-binary, unsafe-entry (traversal/subdir/symlink), too-many-entries; bare-binary
delivery regression intact. Build/vet/golangci-lint clean. Build-side production of the
per-arch tarball is the complementary build-signing/bundle follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mfreeman451 left a comment

lgtm

lgtm
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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
carverauto/serviceradar!3468
No description provided.