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
- githubNOTE: Even with the firewall disabled, the
network.allowedlist 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 wantdefaultsandgithubin 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:
- Refuses write permissions - you have to use safe-outputs instead of raw
contents: write - Requires explicit network configuration - no leaving the
network:field empty and hoping for the best - Refuses wildcard
*innetwork.alloweddomains - nice try - Requires ecosystem identifiers instead of individual domains (e.g.
pythoninstead ofpypi.org) - Enforces SHA-pinned GitHub Actions - no
@mainreferences 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 failedSo 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: falseI 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 descriptionsThe key pieces:
strict: false- turns off the strict mode bouncer so we can disable the sandboxsandbox.agent: false- disables the AWF container entirelynetwork.firewall: false- lets the agent make unrestricted network requeststhreat-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:
- Keep it on private repos only (strict: false enforces this anyway)
- Use read-only permissions wherever possible
- Limit your safe-outputs to low-risk operations like creating issues
- Understand the threat detection trade-off before disabling it
- Set a reasonable
timeout-minutesso 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.
Useful Links
- gh-aw Overview - What agentic workflows are and how they work
- Network Permissions Reference - Full docs on firewall and domain configuration
- Sandbox Configuration - AWF sandbox settings
- Strict Mode - What strict mode enforces
- Threat Detection - How the threat detection layer works
- Disabling the Firewall - The specific docs on this topic