Disabling the Firewall Entirely in gh-aw (Agentic Workflows)
  March 20, 2026     8 min read

Disabling the Firewall Entirely in gh-aw (Agentic Workflows)

Disabling the Firewall Entirely in gh-aw (Agentic Workflows)

If you've been playing with GitHub Agentic Workflows (gh-aw) for any amount of time, you've probably hit the moment where your carefully crafted AI agent just... can't do the thing. It tries to fetch a webpage. Blocked. It tries to hit some obscure API. Blocked. It tries to download a package from a registry you've never heard of. You guessed it - blocked.

Welcome to the AWF (Agent Workflow Firewall), and today we're going to talk about the nuclear option: turning it off entirely.

A Bit of Context

By default, gh-aw wraps your coding agent in a sandbox powered by the AWF (Agent Workflow Firewall). This is genuinely great - it enforces domain-based access controls so your AI agent can't just wander off into the dark corners of the internet unsupervised. You configure which domains are allowed via the network field in your workflow's frontmatter, and the firewall makes sure the agent stays within those boundaries.

For most workflows, this is exactly what you want. Your agent only needs GitHub, maybe PyPI, maybe a specific API - easy. You list your ecosystem identifiers and custom domains, and you're done:

network:
  allowed:
    - defaults
    - python
    - github
    - "api.my-cool-service.com"

But then there are the other workflows.

When You Need Your Agent to Touch Everything

I recently built an agentic workflow that I can only describe as a "web content health checker on steroids". The idea was simple: given a repository full of markdown documentation, have an AI agent crawl every external link, check if it's still alive, verify the content hasn't drifted from what the docs describe, and open issues for anything that looks stale or broken.

Sounds reasonable, right? Until you realise your documentation links to approximately seven hundred different domains. AWS docs, Stack Overflow, random blog posts, npm packages, YouTube videos, some guy's personal site from 2014 that somehow still has the best explanation of a niche Linux kernel parameter.

I am not listing seven hundred domains in my network.allowed field. I refuse.

This is where disabling the firewall comes in.

The Nuclear Option

Disabling the firewall is a two-part operation. You need to set sandbox.agent: false to disable the AWF container sandbox, and set network.firewall: false so the agent can make unrestricted network requests. Here's what that looks like in your frontmatter:

strict: false

sandbox:
  agent: false

network:
  firewall: false
  allowed:
    - defaults
    - github

NOTE: Even with the firewall disabled, the network.allowed list still matters! It's used for content sanitization - any URLs from domains not in your allowed list get replaced with (redacted) in workflow outputs. So you probably still want defaults and github in there at minimum to stop your output from turning into a wall of (redacted) text.

You'll notice that strict: false sitting at the top. That's not optional - it's the chain of dominoes you have to knock over.

Strict Mode: The Bouncer at the Door

Strict mode is enabled by default in gh-aw, and it's basically the security-conscious adult in the room. When strict mode is on, it:

  1. Refuses write permissions - you have to use safe-outputs instead of raw contents: write
  2. Requires explicit network configuration - no leaving the network: field empty and hoping for the best
  3. Refuses wildcard * in network.allowed domains - nice try
  4. Requires ecosystem identifiers instead of individual domains (e.g. python instead of pypi.org)
  5. Enforces SHA-pinned GitHub Actions - no @main references allowed

To disable the firewall, you must set strict: false first. The compiler won't let you disable the sandbox with strict mode enabled - and honestly, fair enough. If you're going to open the floodgates, the system wants you to be explicit about it.

BIG CAVEAT: Workflows compiled with strict: false cannot run on public repositories. The workflow will fail at runtime with an error telling you to recompile with strict mode. This makes sense - you probably don't want a publicly accessible agent that can make unrestricted network requests. Keep this for private repos only.

Threat Detection: The Other Domino

Here's the thing that tripped me up the first time. If your workflow has safe-outputs configured (which it almost certainly does if you want the agent to actually do anything useful like create issues or PRs), then threat detection is automatically enabled.

Threat detection is the security layer that analyses your agent's output after it runs but before safe outputs are applied. It scans for prompt injection attempts, secret leaks, and malicious code patches. It's a genuinely good feature.

Here's the catch though: threat detection requires sandbox.agent to be enabled. It runs inside the AWF sandbox with fully blocked network. So if you've disabled the sandbox, the threat detection job literally cannot run. This isn't a "you might want to disable this" situation - the compiler will refuse to compile your workflow if you don't.

Ask me how I know. Here's what gh aw compile spits out if you forget:

⚠ ⚠️  WARNING: Agent sandbox disabled (sandbox.agent: false). This removes
  firewall protection. The AI agent will have direct network access without
  firewall filtering.
✗ .github/workflows/my-workflow.md:1:1: error: threat detection requires
  sandbox.agent to be enabled. Threat detection runs inside the agent sandbox
  (AWF) with fully blocked network. Either enable sandbox.agent or use
  'threat-detection: false' to disable the threat-detection configuration
  in safe-outputs.
✗ compilation failed

So this is another domino in the chain. You disable strict mode, which lets you disable the sandbox, which forces you to disable threat detection. It's dominoes all the way down.

You need threat-detection: false in your safe-outputs config:

safe-outputs:
  create-issue:
    title-prefix: "[link-check] "
    labels: [documentation, link-rot]
  noop:
    report-as-issue: false
  threat-detection: false

I want to be clear: you should understand what you're giving up here. Threat detection exists for a very good reason - it catches prompt injection, secret leaks, and malicious patches before they make it into your repo via safe outputs. In my case, the workflow only has read permissions and creates issues - it can't push code or modify the repository. The risk profile is low enough that I'm comfortable with this trade-off. If your workflow creates PRs with code changes, think very carefully before going down this path.

The Full Hypothetical Workflow

Putting it all together, here is roughly what my link checker workflow looks like:

---
name: Documentation Link Checker
description: >
  Crawls all external links in repository documentation, verifies
  they're still alive, and opens issues for broken or stale links.
on:
  schedule: weekly
  workflow_dispatch:
  skip-if-match: 'is:issue is:open in:title "[link-check]"'

permissions:
  contents: read
  issues: read

strict: false

sandbox:
  agent: false

engine: copilot

network:
  firewall: false
  allowed:
    - defaults
    - github

safe-outputs:
  create-issue:
    title-prefix: "[link-check] "
    labels: [documentation, link-rot]
    max: 10
    expires: 14d
  noop:
    report-as-issue: false
  threat-detection: false

tools:
  github:
    toolsets: [default]
  bash: ["curl", "grep", "find"]
  web-fetch:

timeout-minutes: 30
---

# Documentation Link Health Checker

You are a documentation quality specialist. Your job is to find and
report broken or stale external links across all markdown files in
this repository.

## Process

1. Find all `.md` and `.mdx` files in the repository
2. Extract all external URLs (http/https links)
3. For each URL, check if it returns a successful response
4. For links that fail or return unexpected status codes, create
   an issue with the broken link, the file it was found in, and
   a suggested fix if possible
5. Group related broken links into single issues where appropriate

## Guidelines

- Skip internal/relative links
- Skip known-volatile URLs (CI badges, build status, etc.)
- Include the HTTP status code in your report
- If a link redirects, note the redirect destination
- Be concise in issue descriptions

The key pieces:

  • strict: false - turns off the strict mode bouncer so we can disable the sandbox
  • sandbox.agent: false - disables the AWF container entirely
  • network.firewall: false - lets the agent make unrestricted network requests
  • threat-detection: false - required because threat detection can't run without the sandbox

Should You Actually Do This?

Probably not for most workflows. The firewall and strict mode exist for excellent reasons, and for 90% of use cases you're better off listing specific domains in network.allowed. The ecosystem identifiers (python, node, github, etc.) cover a lot of ground, and you can always add custom domains for specific APIs.

But for that other 10% - workflows that genuinely need to interact with the open internet, like link checkers, content aggregators, web scrapers, or competitive analysis tools - disabling the firewall is the pragmatic choice. Just make sure you:

  1. Keep it on private repos only (strict: false enforces this anyway)
  2. Use read-only permissions wherever possible
  3. Limit your safe-outputs to low-risk operations like creating issues
  4. Understand the threat detection trade-off before disabling it
  5. Set a reasonable timeout-minutes so your agent doesn't run forever

The AWF team has done a great job making the security defaults sensible while still giving you the escape hatches when you need them. Just maybe don't tell your security team about this post.

devopstar

DevOpStar by Nathan Glover | 2025