Skip to content

ironsh/hosted-actions-example

Repository files navigation

Hosted Actions Example: Using iron-proxy in GitHub Actions

iron-proxy is a transparent forward proxy that intercepts all HTTP and HTTPS traffic from your CI job and enforces a domain allowlist. The ironsh/iron-proxy-action GitHub Action handles all the setup for you.

Quick Start

Add the action to your workflow before your build steps, and the summary step after:

steps:
  - uses: actions/checkout@v4

  - uses: ironsh/iron-proxy-action@v0.1.0
    with:
      egress-rules: egress-rules.yaml
      warn: true # log denied requests without blocking

  # Your build steps
  - run: npm ci
  - run: npm test

  - uses: ironsh/iron-proxy-action/summary@v0.1.0
    if: always()

Create an egress-rules.yaml with the domains your build needs. You can use this repo's egress-rules.yaml as a starting point:

domains:
  - "nodejs.org"
  - "*.nodejs.org"
  - "*.npmjs.org"

Push with warn: true and check the job summary to see every domain your build contacted. Add those domains to egress-rules.yaml, remove warn: true, and push again. The proxy will now enforce the allowlist.

See this repository for a complete working example. Everything below explains what is happening under the hood.

Security note: GitHub Actions gives build jobs sudo by default. The action revokes sudo for subsequent steps (controlled by the disable-sudo input) so that build scripts cannot bypass the proxy. For stronger isolation, we recommend using self-hosted runners in VMs and performing egress enforcement at the hypervisor level.

Workflow

The workflow uses the ironsh/iron-proxy-action action, which handles downloading iron-proxy, generating and trusting a TLS interception CA, configuring DNS, starting the proxy, and locking down outbound traffic with iptables — all in a single step:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ironsh/iron-proxy-action@v0.1.0
        with:
          egress-rules: egress-rules.yaml

      # Your build steps (all traffic goes through iron-proxy)
      - run: npm ci
      - run: npm test

      - uses: ironsh/iron-proxy-action/summary@v0.1.0
        if: always()

The summary step runs at the end (even on failure) and produces a job summary showing all allowed and denied requests.

Action Inputs

Input Default Description
egress-rules egress-rules.yaml Path to your egress rules file
version latest Iron proxy version to install
warn false Log denied requests without blocking them
disable-sudo true Revoke sudo so subsequent steps can't bypass the proxy
disable-docker true Revoke Docker access so subsequent steps can't bypass the proxy
upstream-resolver 8.8.8.8:53 Upstream DNS resolver

Configuring the Allowlist

The egress rules live in egress-rules.yaml:

domains:
  - "nodejs.org"
  - "*.nodejs.org"
  - "*.npmjs.org"

domains lists hostnames (with optional wildcards) that are allowed through the proxy. Everything else is blocked.

How It Works

iron-proxy sits between your CI job and the internet. It has four responsibilities:

  1. DNS interception. iron-proxy runs a DNS server on 127.0.0.1:53. When any process resolves a hostname, iron-proxy returns 127.0.0.1, directing the connection back through itself. It forwards the real lookup to an upstream resolver (8.8.8.8 by default) to connect to the actual destination.
  2. TLS interception. For HTTPS, iron-proxy generates certificates on the fly for each destination host, signed by a short-lived CA that the action creates and trusts. Tools like curl, npm, and apt accept these certificates because the CA is in the system trust store.
  3. Allowlist enforcement. Each request is checked against the domain list in egress-rules.yaml. Requests to unlisted hosts are blocked and logged.
  4. Network lockdown. iptables rules prevent any process from bypassing the proxy by connecting to an external IP directly. Only the proxy and already-established connections are allowed to make outbound connections. All other processes must go through loopback, where the proxy is listening.

Known Limitations

  • GitHub Actions gives build jobs sudo by default. The action revokes sudo for subsequent steps, but if you set disable-sudo: false, attackers who detect the proxy could circumvent it.
  • Some runtimes ship their own certificate bundles and may need extra configuration to trust the interception CA. The action handles Node.js (NODE_EXTRA_CA_CERTS) automatically; others like Python's requests (REQUESTS_CA_BUNDLE) or Java (keytool) may need manual setup.

License

This example is provided under the MIT License.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages