# How to Configure Network Isolation for gh-aw Workflows: A Complete Guide

> Secure your gh-aw workflows with network isolation. Learn to configure allowed and blocked domains, plus firewall settings, in this complete guide.

- Repository: [GitHub/gh-aw](https://github.com/github/gh-aw)
- Tags: how-to-guide
- Published: 2026-02-16

---

**You configure network isolation in gh-aw by adding a `network` section to your workflow's YAML front matter, specifying `allowed` domains, `blocked` domains, and an optional `firewall` configuration for HTTPS inspection.**

The `github/gh-aw` repository implements a declarative network isolation model that lets you precisely control outbound traffic from your workflows. By defining permissions in the workflow front matter, you can restrict access to specific domains, block malicious endpoints, or enable deep packet inspection through the AWF (Actions Workflow Firewall) runtime.

## Understanding the Network Isolation Model

gh-aw implements network isolation through three core concepts that work together to secure workflow execution.

### NetworkPermissions Data Structure

The `NetworkPermissions` struct in [`pkg/workflow/engine.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/engine.go) (lines 60-65) stores your configuration. It holds the `allowed` list, `blocked` list, and optional `firewall` fields that the compiler reads when building the workflow sandbox.

### Default Allow List

When you omit the `network` block entirely, gh-aw automatically applies `network: defaults`. This grants access to essential infrastructure domains including certificate authorities, Ubuntu package mirrors, and Microsoft update sources. The expansion logic resides in the `GetAllowedDomains()` function within [`engine.go`](https://github.com/github/gh-aw/blob/main/engine.go).

### AWF Firewall Runtime

The **Actions Workflow Firewall (AWF)** is an optional runtime that inspects HTTPS traffic, enforces URL-specific allow-lists, and can terminate TLS for deep inspection. When `network.firewall` is present, the compiler generates an `awf` sandbox with appropriate CLI flags. The configuration structure is defined in [`pkg/workflow/firewall.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/firewall.go) (lines 12-22), while validation logic lives in [`pkg/workflow/network_firewall_validation.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/network_firewall_validation.go) (lines 31-41).

## Configuring Network Permissions in Workflow Front Matter

You define network isolation rules in the YAML front matter at the top of your workflow file.

### Basic Syntax for Allow and Block Lists

Use the `allowed` key to specify permitted domains and the `blocked` key to explicitly deny access:

```yaml
---
on: push
engine:
  id: copilot
network:
  allowed:
    - "github.com"
    - "*.example.com"
  blocked:
    - "bad.example.net"
---

```

The `allowed` list supports glob patterns like `*.example.com`. The compiler expands these patterns when constructing the sandbox network policy.

### Blocking All Network Access

To create a completely offline workflow, provide an empty network configuration:

```yaml
---
on: schedule
engine:
  id: claude
network: {}
---

```

The compiler treats this as "no allowed domains," causing the sandbox to block any outbound network call.

### Using Ecosystem Identifiers

Rather than listing individual domains, you can use ecosystem identifiers that expand to curated domain lists:

| Identifier | Expands To |
|------------|------------|
| `defaults` | Certificate authorities, Ubuntu mirrors, Microsoft updates |
| `github` | `github.com`, `api.github.com`, `objects.githubusercontent.com` |
| `node` | Official npm and Node.js CDN domains |
| `python` | PyPI and Python ecosystem domains |
| `go` | Go module proxy and checksum domains |

The mapping is defined in [`constants/allowed_ecosystems.go`](https://github.com/github/gh-aw/blob/main/constants/allowed_ecosystems.go). Use these identifiers to simplify maintenance:

```yaml
network:
  allowed:
    - "defaults"
    - "github"
    - "node"

```

## Enabling and Configuring the AWF Firewall

The AWF firewall provides deep inspection capabilities beyond simple domain filtering.

### Auto-Enablement for AI Engines

The firewall automatically enables for Copilot, Claude, and Codex engines when:

1. The workflow has network restrictions (`network.allowed` is not `"*"`)
2. No explicit firewall configuration exists
3. The sandbox is not explicitly disabled (`sandbox.agent: false`)

This logic resides in `enableFirewallByDefaultForEngine()` within [`pkg/workflow/firewall.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/firewall.go) (lines 24-70).

### Custom Firewall Configuration

For granular control, explicitly define the `firewall` block:

```yaml
network:
  allowed:
    - "github.com"
  firewall:
    enabled: true           # Optional, defaults to true when present

    version: "v0.7.0"      # Specific AWF Docker image tag

    ssl_bump: true         # Required for HTTPS inspection

    allow_urls:
      - "https://github.com/githubnext/*"
    log_level: "debug"

```

The `ssl_bump: true` setting enables TLS termination for deep packet inspection. Without this flag, the firewall cannot inspect encrypted traffic.

### Validation Rules

The compiler enforces specific constraints on firewall configuration. The `validateNetworkFirewallConfig()` function in [`pkg/workflow/network_firewall_validation.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/network_firewall_validation.go) (lines 31-41) ensures that:

- If `allow_urls` is specified, `ssl_bump` must be `true`
- Version strings conform to semantic versioning patterns

Violations result in compilation errors before the workflow executes.

## Migrating Legacy MCP Network Settings

Earlier versions of gh-aw supported per-server network configuration under `mcp-servers.<server>.network`. This approach is deprecated in favor of the top-level `network` block.

The [`codemod_mcp_network.go`](https://github.com/github/gh-aw/blob/main/codemod_mcp_network.go) file in `pkg/cli/` implements the migration codemod. To update existing workflows automatically:

```bash
gh aw codemod run --codemod mcp-network-to-top-level-migration path/to/workflow.md

```

This command rewrites the front-matter in-place, consolidating legacy MCP network rules into the standard `network` configuration.

## How the Compiler Processes Network Configuration

Understanding the compilation pipeline helps debug network isolation issues. The compiler processes network configuration through four distinct phases:

1. **Front-matter parsing** – `ParseWorkflowFile` extracts the `network` map into a `NetworkPermissions` struct
2. **Validation** – `validateNetworkFirewallConfig` enforces firewall-specific constraints
3. **Sandbox selection** – `isFirewallEnabled` determines whether to instantiate an AWF sandbox (`workflow:firewall`)
4. **Runtime flag generation** – `getAWFImageTag`, `getSSLBumpArgs`, and `getFirewallConfig` generate Docker image tags and CLI arguments for the sandbox

These steps are integrated into the main `Compiler.Compile` pipeline, ensuring network policies are enforced before workflow execution begins.

## Code Examples

### Default Network Isolation

Use the default configuration for standard workflows that need basic infrastructure access:

```yaml
---
on: push
engine:
  id: copilot
network: defaults
---

# Workflow steps execute with access to CA roots and package mirrors

```

### Explicit Allow-List with Firewall

Restrict access to specific domains while enabling deep inspection:

```yaml
---
on: workflow_dispatch
engine:
  id: copilot
network:
  allowed:
    - "github.com"
    - "*.mycorp.com"
  firewall:
    ssl_bump: true
    allow_urls:
      - "https://github.com/githubnext/*"
---
steps:
  - name: Run script
    run: curl https://github.com/githubnext/gh-aw

```

### Complete Network Lockdown

Create an air-gapped workflow that cannot make any outbound connections:

```yaml
---
on: schedule
engine:
  id: claude
network: {}
---

# No network calls are permitted.

```

### Programmatic Inspection in Go

Inspect network configuration programmatically using the gh-aw Go API:

```go
import (
    "fmt"
    "github.com/github/gh-aw/pkg/workflow"
)

func printNetwork(cfg *workflow.WorkflowData) {
    if cfg.NetworkPermissions == nil {
        fmt.Println("No network config – defaults will be applied")
        return
    }
    fmt.Printf("Allowed: %v\n", cfg.NetworkPermissions.Allowed)
    fmt.Printf("Blocked: %v\n", cfg.NetworkPermissions.Blocked)
    if cfg.NetworkPermissions.Firewall != nil {
        fmt.Printf("Firewall enabled: %v\n", cfg.NetworkPermissions.Firewall.Enabled)
    }
}

```

## Summary

- **Front-matter configuration**: Define network isolation in the `network` section of your workflow YAML, using `allowed` for permitted domains and `blocked` for explicit denials.
- **Default behavior**: Omitting the `network` key applies `network: defaults`, granting access to essential infrastructure domains like certificate authorities and package mirrors.
- **Complete isolation**: Set `network: {}` to block all outbound traffic and create air-gapped workflows.
- **Ecosystem identifiers**: Use shortcuts like `github`, `node`, or `python` in the `allowed` list to automatically include official ecosystem domains.
- **AWF firewall**: Enable deep packet inspection by adding a `firewall` block with `ssl_bump: true`, or let it auto-enable for AI engines like Copilot and Claude when network restrictions are present.
- **Validation**: The compiler enforces constraints like requiring `ssl_bump: true` when `allow_urls` is specified, catching configuration errors before runtime.
- **Migration**: Use `gh aw codemod run` to migrate deprecated per-server MCP network settings to the top-level `network` block.

## Frequently Asked Questions

### What happens if I don't specify a network configuration in my gh-aw workflow?

If you omit the `network` block entirely, gh-aw automatically applies `network: defaults` during compilation. This grants your workflow access to essential infrastructure domains including certificate authorities, Ubuntu package mirrors, and Microsoft update sources, while blocking general internet access. The `ParseNetworkPermissions` routine in [`pkg/workflow/engine.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/engine.go) handles this default assignment when `NetworkPermissions` is nil.

### How do I completely block all outbound network access for a workflow?

To create an air-gapped workflow that cannot make any outbound connections, set the network configuration to an empty map: `network: {}`. The compiler interprets this as "no allowed domains," and the resulting sandbox will block every network call. This is useful for workflows that process sensitive data or execute untrusted code without requiring external dependencies.

### Why does my workflow fail when I specify allow_urls without ssl_bump?

The AWF firewall requires `ssl_bump: true` whenever you specify `allow_urls` because the firewall must terminate TLS connections to inspect HTTPS traffic against your URL patterns. The validator in [`pkg/workflow/network_firewall_validation.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/network_firewall_validation.go) (lines 31-41) explicitly checks this relationship and raises a compilation error if `allow_urls` is present without `ssl_bump` enabled. Set `ssl_bump: true` in your `network.firewall` configuration to resolve this.