Skip to main content

What you’ll get

One comment on every pull request, one fold per job, connecting each outbound destination to the process that opened it. Adding a single dependency looks like this:
A recorded Garnet comment on a pull request: one job fold, an install step reaching registry.npmjs[.]org, and the runner's own chains in the dns and runner substrate fold

The install reached the registry; the rest is the runner fetching the Action. On the next recorded commit this becomes a comparison.

The job name links to its GitHub Actions run, and View this job’s Execution Profile in Garnet → opens the job’s public run report.

Install the GitHub App

Install Garnet Runtime Review

Pick the repos you want recorded. The App is what posts the comment.

Add the Action to your workflow

Token: app.garnet.aiSettingsAPI Tokens. Save it as the repo secret GARNET_API_TOKEN. It’s the only secret Garnet needs — see What Garnet sees.pull-requests: write is what lets Garnet post the comment. Runner support today: GitHub-hosted ubuntu-latest. Pin to latest SHA

Open a pull request

The comment appears while jobs are still running and fills in as each finishes — one collapsed fold per recorded job.

Read it

A clean npm install reaches registry.npmjs.org and nothing else. Any other destination at install or build time is what you’re looking for.How to read the record in full: The Execution Profile.

See it live

Real recorded comments, with working public report links, on the demo repository:

Registry-only install

Install-time egress reaches the registry and nothing else.

Same diff, poisoned dependency

The record carries egress the diff never mentions.

pnpm under the sensor

A recorded run on a real-world repository.
Next: The Execution Profile · Consume the Runtime Review

Action reference

The action never fails your job — it records the run and posts the record.
The action does not require contents: write, actions: write, or access to any repository secrets beyond the token you pass. Full model: What Garnet sees.
Floating tags like @v2 can move after you adopt them. For supply-chain hygiene, pin to the commit SHA of the latest release.The canonical SHA is always available at garnet.ai/pins (human-readable) and garnet.ai/pins.txt (machine-readable). Both auto-update when a new release ships.
Garnet also writes the Garnet Execution Summary to the GitHub Actions Job Summary automatically — the per-run, full-detail record, under three headings:
  • Workload Summary — profile, workflow, repository, branch, commit, actor, run, and job identity.
  • Network Egress Summary — a Process Tree | Destinations table, one row per distinct lineage keyed on lineage + PID + process; different PIDs never merge. Rows retain the address, every recorded name, ports, protocol, the leaf (pid N), and the recorded workflow step.
  • Telemetry — one sentence: Network telemetry observed N unique domains, M destinations, C connections, and F flows. Unique domains and connections pass through from the sensor; destinations and flows are derived from the record.
  • The View this job’s Execution Profile in Garnet → permalink to the run’s public run report.
The PR comment is the cross-job conversation surface; the Execution Summary is the per-run record, and it is written before the comment.
Agent doesn’t appear in the dashboard — verify GARNET_API_TOKEN is set. Check workflow logs for the Garnet step.Permission denied — Jibril attaches eBPF programs at the kernel level, which requires sudo during install. ubuntu-latest runners include it by default.No Garnet Execution Summary in the Actions run — use the pinned SHA from garnet.ai/pins — the SHA must match the latest release.No PR comment, or the comment stays in the waiting state — grant pull-requests: write in your workflow’s permissions block. The action uses github_token (defaults to ${{ github.token }}) to post comments. If the run already finished, look in the job log for the Garnet step — the sensor must start before the workload runs.Debug mode: