Guide

How to Harden GitHub Actions for Free

Your pipeline runs third-party code next to your secrets. Here is how to contain it, for free.

Updated July 18, 2026 · 6 min read

Your CI pipeline is a machine that downloads other people's code and runs it, with access to your secrets. That is the whole point of CI, and it is also why it is a favorite target. A single poisoned dependency or a compromised action can read your tokens and cloud credentials and quietly send them somewhere. Most teams never see it happen.

You can shut most of that down for free. The idea is simple: watch what the job talks to, tie every connection to the process that made it, and block anything you did not allow.

What actually goes wrong

A build step runs an install. One of the hundreds of packages it pulls has a postinstall script. That script reads GITHUB_TOKEN or your cloud keys from the environment and makes an outbound request to an address you have never heard of. The build still passes. Nothing looks wrong. The secret is gone.

The defense is to control egress. If the job can only reach the registries and endpoints it genuinely needs, that exfiltration request has nowhere to go.

The free fix: Legion Runner

Legion Runner is an open-source GitHub Action that hardens the runner it executes on. It monitors and can block outbound traffic, uses an eBPF agent to attribute each connection to the exact process that opened it, and detects tampering of sensitive files. It works on GitHub-hosted and self-hosted Linux runners, and it costs nothing.

Step by step

  1. Add it as the first step. Put it ahead of checkout so the controls are live for the rest of the job.
  2. Start in audit mode. Run it in audit first to learn what your job actually talks to, without breaking anything.
    steps:
      - uses: Wraith-security/legion_runner@v1
        with:
          egress-policy: audit
  3. Read the audit, then switch to block. Once you know your real egress, flip to block and allow only what you need. Presets cover the common ecosystems in one line, and ebpf: auto ties every connection to the process that made it.
    steps:
      - uses: Wraith-security/legion_runner@v1
        with:
          egress-policy: block
          allowed-presets: npm
          ebpf: auto
    
      - uses: actions/checkout@v6
      - run: npm ci && npm run build
  4. Keep file integrity on. Leave file-integrity watching the sensitive paths, so tampering with things like ~/.npmrc or your source shows up in the run.
  5. Pin everything and drop token scope. Pin third-party actions to a commit SHA, not a floating tag, and set the workflow token to the least permission the job needs. Hardening the runner and reducing the blast radius work together.

Why this is worth ten minutes

Supply-chain attacks through CI are cheap for an attacker and expensive for you. The controls above turn a runner that trusts everything into one that trusts only what you named, and they do it without a vendor, a contract, or a per-minute fee. For a growing team, that is one of the highest-value free changes you can make.

The pipeline is where borrowed code meets your secrets. Contain it there, and a poisoned dependency has nowhere to send what it steals.

All guidesExplore the tools