Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions docs-site/src/content/docs/guides/domain-filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,40 @@ sudo awf \
--prompt "Search for papers"
```

## Protocol-specific filtering

Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protocol:

```bash
# HTTPS only - blocks HTTP traffic to this domain
sudo awf --allow-domains 'https://secure.example.com' -- curl https://secure.example.com

# HTTP only - blocks HTTPS traffic to this domain
sudo awf --allow-domains 'http://legacy-api.example.com' -- curl http://legacy-api.example.com

# Both protocols (default, no prefix)
sudo awf --allow-domains 'example.com' -- curl https://example.com
```

| Format | HTTP | HTTPS |
|--------|------|-------|
| `domain.com` | ✓ | ✓ |
| `https://domain.com` | ✗ | ✓ |
| `http://domain.com` | ✓ | ✗ |

Protocol prefixes work with wildcard patterns: `https://*.secure.example.com` matches only HTTPS traffic to any subdomain of `secure.example.com`.

## Normalization

Domains are normalized before matching:

- **Case-insensitive**: `GitHub.COM` = `github.com`
- **Whitespace trimmed**: `" github.com "` = `github.com`
- **Whitespace trimmed**: `" github.com "` = `github.com`
- **Trailing dots removed**: `github.com.` = `github.com`
- **Protocols stripped**: `https://github.com` = `github.com`

```bash
# These are all equivalent
--allow-domains github.com
--allow-domains " GitHub.COM. "
--allow-domains "https://github.com"
```
:::note
Protocol prefixes (`http://`, `https://`) are **not** stripped — they enable [protocol-specific filtering](#protocol-specific-filtering). A bare domain (no prefix) allows both HTTP and HTTPS.
:::

## Debugging domain filtering

Expand Down Expand Up @@ -259,5 +278,6 @@ awf logs --format json | jq 'select(.isAllowed == false)'

## See also

- [CLI Reference](/gh-aw-firewall/reference/cli-reference) - Complete option documentation
- [CLI Reference](/gh-aw-firewall/reference/cli-reference) - Complete option documentation including implicit behaviors
- [Playwright Testing](/gh-aw-firewall/guides/playwright-testing) - Using the `localhost` keyword for local development
- [Security Architecture](/gh-aw-firewall/reference/security-architecture) - How filtering works
146 changes: 142 additions & 4 deletions docs-site/src/content/docs/reference/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ awf [options] -- <command>

### `--allow-domains <domains>`

Comma-separated list of allowed domains. Domains automatically match all subdomains. Supports wildcard patterns and protocol-specific filtering.
Comma-separated list of allowed domains. Domains automatically match all subdomains. Supports wildcard patterns, protocol-specific filtering, and special keywords.

**If no domains are specified, all network access is blocked.** This is useful for running commands that should have no network access.

Comment on lines +72 to 75
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statement that “If no domains are specified, all network access is blocked” is not always true once implicit allowlist expansion runs. In enterprise environments, domains may be auto-added from GITHUB_SERVER_URL/GITHUB_API_URL (GHEC) or ENGINE_API_TARGET (GHES) even when the user doesn’t pass --allow-domains. Consider clarifying this sentence (or adding a note) to describe that implicit behaviors can add domains to an otherwise empty allowlist.

See below for a potential fix:

**If no domains are specified, network access is blocked by default.** This is useful for running commands that should have no network access.

**Note:** In some enterprise environments, domains may still be added implicitly to the allowlist from configuration such as `GITHUB_SERVER_URL`, `GITHUB_API_URL`, or `ENGINE_API_TARGET`, even when `--allow-domains` is not provided.

```bash
# Allow specific domains
--allow-domains github.com,npmjs.org
--allow-domains '*.github.com,api-*.example.com'

# No network access by default when omitted

Copilot uses AI. Check for mistakes.
Expand All @@ -82,7 +82,7 @@ Comma-separated list of allowed domains. Domains automatically match all subdoma
awf -- echo "offline command"
```

#### Protocol-Specific Filtering
#### Protocol-specific filtering

Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protocol:

Expand All @@ -93,7 +93,7 @@ Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protoc
# HTTP only - blocks HTTPS traffic to this domain
--allow-domains 'http://legacy-api.example.com'

# Both protocols (default behavior, backward compatible)
# Both protocols (default behavior)
--allow-domains 'example.com'

# Mixed configuration
Expand All @@ -103,6 +103,78 @@ Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protoc
--allow-domains 'https://*.secure.example.com'
```

| Format | HTTP | HTTPS | Example |
|--------|------|-------|---------|
| `domain.com` | ✓ | ✓ | `--allow-domains example.com` |
| `https://domain.com` | ✗ | ✓ | `--allow-domains 'https://api.example.com'` |
| `http://domain.com` | ✓ | ✗ | `--allow-domains 'http://legacy.example.com'` |

:::tip
Bare domains (without protocol prefix) allow both HTTP and HTTPS. Use protocol prefixes to restrict to a single protocol.
:::

#### Wildcard patterns

Use `*` to match multiple domains:

```bash
# Match any subdomain
--allow-domains '*.github.com'

# Match prefix patterns within a subdomain label
--allow-domains 'api-*.example.com'

# Combine plain domains and wildcards
--allow-domains 'github.com,*.googleapis.com,api-*.example.com'
```

:::caution
Use quotes around patterns to prevent shell expansion of `*`.
:::

| Pattern | Matches | Does Not Match |
|---------|---------|----------------|
| `*.github.com` | `api.github.com`, `raw.github.com` | `github.com` |
| `api-*.example.com` | `api-v1.example.com`, `api-test.example.com` | `api.example.com` |
| `github.com` | `github.com`, `api.github.com` | `notgithub.com` |

**Security restrictions:** Overly broad patterns like `*`, `*.*`, or `*.*.*` are rejected.

:::note
Wildcard patterns and protocol prefixes can be combined: `https://*.secure.example.com` matches only HTTPS traffic to any subdomain of `secure.example.com`.
:::

#### `localhost` keyword

Using `localhost` in `--allow-domains` triggers special behavior for local development:

```bash
# Automatically configures everything for local testing
sudo awf --allow-domains localhost -- npx playwright test
```

When `localhost` is detected, awf automatically:

1. **Replaces `localhost` with `host.docker.internal`** — Maps to Docker's host gateway so containers can reach host services
2. **Enables `--enable-host-access`** — Activates host network access (equivalent to passing `--enable-host-access`)
3. **Allows common development ports** — Opens ports 3000, 3001, 4000, 4200, 5000, 5173, 8000, 8080, 8081, 8888, 9000, 9090
Comment on lines +156 to +160
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI only replaces the first occurrence of localhost/http://localhost/https://localhost in the allowlist (additional occurrences are left unchanged). Consider documenting this so users don’t expect multiple localhost entries (e.g., mixed protocol) to all be rewritten automatically.

Copilot uses AI. Check for mistakes.

Protocol prefixes are preserved: `http://localhost` becomes `http://host.docker.internal` and `https://localhost` becomes `https://host.docker.internal`.

```bash
# Override the default ports
sudo awf --allow-domains localhost --allow-host-ports 3000,8080 -- npx playwright test

# Combine with other domains
sudo awf --allow-domains localhost,github.com -- npx playwright test
```

:::caution
The `localhost` keyword enables access to services running on your host machine. Only use it for trusted workloads like local testing and development.
:::

**See also:** [Playwright Testing with Localhost](/gh-aw-firewall/guides/playwright-testing) for detailed examples.

### `--allow-domains-file <path>`

Path to file with allowed domains. Supports comments (`#`) and one domain per line.
Expand Down Expand Up @@ -752,6 +824,71 @@ sudo -E awf --enable-api-proxy --no-rate-limit \
When using a custom `--openai-api-target` or `--anthropic-api-target`, you must add the target domain to `--allow-domains` so the firewall permits outbound traffic. AWF emits a warning if a custom target is set but not in the allowlist.
:::

## Implicit Behaviors

### Enterprise domain auto-detection

AWF automatically detects GitHub Enterprise environments and adds required domains to the allowlist. No manual configuration is needed — the domains are auto-added when the relevant environment variables are present.

#### GitHub Enterprise Cloud (GHEC)

When `GITHUB_SERVER_URL` points to a `*.ghe.com` tenant (set automatically by GitHub Agentic Workflows), AWF auto-adds:

| Auto-added Domain | Purpose |
|-------------------|---------|
| `<tenant>.ghe.com` | Enterprise tenant |
| `api.<tenant>.ghe.com` | API access |
| `copilot-api.<tenant>.ghe.com` | Copilot inference |
| `copilot-telemetry-service.<tenant>.ghe.com` | Copilot telemetry |

Domains from `GITHUB_API_URL` are also detected — if `GITHUB_API_URL` points to a `*.ghe.com` hostname (e.g., `https://api.myorg.ghe.com`), that hostname is added to the allowlist as well. This ensures API access works even if only `GITHUB_API_URL` is set.

```bash
# These environment variables are set automatically by GitHub Agentic Workflows
# GITHUB_SERVER_URL=https://myorg.ghe.com
# GITHUB_API_URL=https://api.myorg.ghe.com

# AWF auto-adds:
# - myorg.ghe.com
# - api.myorg.ghe.com
# - copilot-api.myorg.ghe.com
# - copilot-telemetry-service.myorg.ghe.com
sudo awf --allow-domains github.com -- copilot-agent
```

:::note
Public `github.com` is not auto-added — it must be specified explicitly in `--allow-domains`.
:::

#### GitHub Enterprise Server (GHES)

When `ENGINE_API_TARGET` is set (indicating a GHES environment), AWF auto-adds:

| Auto-added Domain | Purpose |
|-------------------|---------|
| `github.<company>.com` | GHES base domain (extracted from API URL) |
| `api.github.<company>.com` | GHES API access |
| `api.githubcopilot.com` | Copilot API (cloud-hosted) |
| `api.enterprise.githubcopilot.com` | Enterprise Copilot API |
| `telemetry.enterprise.githubcopilot.com` | Enterprise Copilot telemetry |

```bash
# Set by GitHub Agentic Workflows on GHES
# ENGINE_API_TARGET=https://api.github.mycompany.com

# AWF auto-adds:
# - github.mycompany.com
# - api.github.mycompany.com
# - api.githubcopilot.com
# - api.enterprise.githubcopilot.com
# - telemetry.enterprise.githubcopilot.com
sudo awf --allow-domains github.com -- copilot-agent
```

:::tip
Use `--log-level debug` to see which enterprise domains were auto-detected. Look for "Auto-added GHEC domains" or "Auto-added GHES domains" in the output.
:::

## Exit Codes

| Code | Description |
Expand Down Expand Up @@ -1064,7 +1201,8 @@ Denied Requests (3):
## See Also

- [API Proxy Sidecar](/gh-aw-firewall/reference/api-proxy-sidecar) - Secure credential injection architecture and configuration
- [Domain Filtering Guide](/gh-aw-firewall/guides/domain-filtering) - Allowlists, blocklists, and wildcards
- [Domain Filtering Guide](/gh-aw-firewall/guides/domain-filtering) - Allowlists, blocklists, wildcards, and protocol-specific filtering
- [Playwright Testing](/gh-aw-firewall/guides/playwright-testing) - Using the `localhost` keyword for local development
- [SSL Bump Reference](/gh-aw-firewall/reference/ssl-bump/) - HTTPS content inspection and URL filtering
- [Quick Start Guide](/gh-aw-firewall/quickstart) - Getting started with examples
- [Usage Guide](/gh-aw-firewall/usage) - Detailed usage patterns and examples
Expand Down
Loading