The client side of Vega, a reproducible-build Nix binary cache. This repository holds the agent that builds a flake and attests its outputs, and the reproducer that rebuilds someone else's derivation to corroborate it.
Vega signs a build into its shared cache only after independent builders rebuild the same derivation and produce the same output, and it records every attestation in a public, append-only transparency log. The control plane that enforces that is separate; it is documented at https://docs.vega-cache.dev. This repository is public on purpose: the code that builds and attests should be auditable by anyone who relies on the result.
vega is the command line for the cache: enroll a machine, push your local
builds to your own namespace, and manage who your machines trust. Run it with
Nix, no clone needed:
nix run github:Ad-Astra-Computing/vega-agent#vega -- login
nix profile install github:Ad-Astra-Computing/vega-agent#vega # or install it
Or add it to your flake, pinned to a release tag for repeatable builds:
inputs.vega.url = "github:Ad-Astra-Computing/vega-agent/v0.4.2";
# optional, to share this flake's nixpkgs:
# inputs.vega.inputs.nixpkgs.follows = "nixpkgs";Then put it on PATH via vega.packages.${system}.default (devShells,
environment.systemPackages, home.packages, ...) or run it with
nix run vega#vega -- verify ....
Quickstart:
vega login # enroll this machine (GitHub device flow)
vega push .#my-package # build locally, upload novel paths to your namespace
vega verify /nix/store/<h> # independently verify a build: signature + transparency log + NAR bytes
vega mcp # read-only MCP server for AI agents (vega_verify, vega_risk)
vega view # print the nix.conf substituter + keys for your view
vega trust add github:alice # trust another builder (scoped, revocable)
vega status # auth + connectivity
vega doctor # diagnose nix / zstd / auth, and check for a newer release
vega verify checks the cache's signature against a key you already trust, the
signed tree head, the build's RFC 9162 inclusion proof, and re-derives the NAR
hash — proof, not trust. vega mcp exposes that to coding agents over the Model
Context Protocol so an agent can gate a dependency on allow/warn/deny
before installing it.
Full command set: login, logout, whoami, status, doctor, push,
verify, mcp, trust (add/remove/list), view; run vega <command> --help for details.
The GitHub token from login is used once and never stored; only a short-lived
Vega credential is kept (~/.config/vega/credential, mode 0600), and the control
plane is required to be https.
agent/holds the Node CLIs and a composite GitHub Action.main.tsbuilds an installable and attests its outputs.reproduce.tsrebuilds a derivation from its provenance and attests the result.nix.tsis the boundary that shells out to thenixCLI.verify.tsre-derives a NAR hash to audit a published cache entry.
src/agent/is the protocol and payload logic, with no I/O, covered by tests.src/nix/holds Nix wire-format helpers: narinfo, store paths, hashing..github/workflows/reproduce.ymlis the reusable reproduction workflow.
Call the composite action from a workflow that grants OIDC. Pin actions to a commit SHA rather than a tag.
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@<sha>
- uses: Ad-Astra-Computing/vega-agent/agent@<sha>
with:
installable: .#packages.x86_64-linux.default
control-plane: https://vega-cache.devUseful action inputs:
skip-upstream: "true"— upload only paths the upstream cache does not already serve (recommended for system closures).reuse-cache: "true"— substitute this repo's own prior Vega pushes before building, so heavy paths are not rebuilt every run. Keep it off for any job whose attestation feeds the shared tier (that build must stay independent of Vega).build-timeout-minutes— explicit per-build cap. Default0(disabled): the job'stimeout-minutesis the only limit, so a long-but-progressing build is never killed.extra-substituters/extra-trusted-public-keys— pull heavy dependencies from a trusted upstream cache (e.g. a project's Cachix) instead of from source.
Run the reproduce workflow against a build's provenance: the flake reference, the attribute, and the locked revision. It rebuilds on a fresh runner under this repository's identity and attests the result. Agreement on the output is what promotes it to the shared cache; a mismatch is recorded as a divergence.
Reproduction is meant to be distributed. Running every build in one repository both queues the jobs behind a single concurrency pool and defeats the point: independence comes from distinct builders. Run the reproducer in your own repository, where it counts as a separate, independent corroboration.
The reproducer builds code it did not write. Before invoking nix, the agent removes the GitHub OIDC request token from the environment, so the untrusted build cannot mint a runner-identity token. Flakes evaluate in pure mode and builds run in the nix sandbox, so the build cannot read the attestation credential either. The control-plane URL is fixed in the workflow, not an input, so a caller cannot redirect the token. A self-hosted reproducer must still use ephemeral, per-job-isolated runners, never a long-lived host.
nix run github:Ad-Astra-Computing/vega-agent # the vega CLI (default)
nix run github:Ad-Astra-Computing/vega-agent#vega -- login
nix run github:Ad-Astra-Computing/vega-agent#attest # build and attest (CI)
nix run github:Ad-Astra-Computing/vega-agent#reproduce # reproduce and attest (CI)
nix develop # a shell with node and zstd
The attest and reproduce apps read their inputs from the environment, the
same variables the GitHub Action and the reproduce workflow set.
npm install
npm run typecheck
npm test
BSD 3-Clause; see LICENSE. This repository began from the open-sourced garnix CI codebase (Copyright garnix, Co.). New code is Copyright Ad Astra Computing Inc.