Skip to main content

Switch a job to block mode

Move a job from audit mode, where Bullfrog records connections, to block mode, where it drops connections to destinations you haven't allowlisted.

Before you begin

Step 1: Collect the destinations the job reached

Open a recent run of the job and read the Bullfrog results in the job summary. Write down every destination that isn't part of the GitHub Actions infrastructure, which Bullfrog allows by default.

Run the job a few times before you rely on the list. A workflow that caches dependencies reaches different hosts on a cold cache than on a warm one, and a scheduled job may behave differently from a pull request one.

Step 2: Turn the list into an allowlist

Add the destinations to allowed-domains, one per line:

- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: audit
allowed-domains: |
registry.npmjs.org
objects.githubusercontent.com

Keep egress-policy: audit for now. Bullfrog marks connections that match the allowlist as authorized and the rest as unauthorized, so the next run tells you whether the list is complete without failing anything.

Step 3: Confirm the allowlist is complete

Run the job again and check the summary. Every remaining unauthorized connection is one that block mode will drop. Decide for each one:

  • The job needs it: add it to allowed-domains or allowed-ips.
  • The job doesn't need it: leave it out. It will be blocked, which is the point.

Repeat until nothing unexpected is left.

Step 4: Set block mode

Change egress-policy to block:

- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
allowed-domains: |
registry.npmjs.org
objects.githubusercontent.com

Step 5: Disable sudo

In block mode, a step that can run sudo can undo Bullfrog's filtering. Set enable-sudo: false unless a step in the job genuinely needs root:

- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
enable-sudo: false
allowed-domains: |
registry.npmjs.org
objects.githubusercontent.com

This also restricts Docker, because the runner's Docker socket is equivalent to root. Ordinary container use keeps working. See Bypass risks and limits for what gets refused.

Verify

Push the change and check that the job still passes. In the summary, connections now carry a Blocked or Authorized decision instead of Unauthorized.

If a step fails with a connection error, see Fix a blocked connection.

See also