Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1,085 changes: 1,085 additions & 0 deletions .github/workflows/smoke-protocol-domains.lock.yml

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions .github/workflows/smoke-protocol-domains.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@copilot instead of adding a new smoke workflow, modify existing ones to add test coverage for protocol domains.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in commit bb38ea9:

  • Removed standalone smoke-protocol-domains.md workflow
  • Integrated protocol testing into smoke-copilot.md (added HTTPS-only and HTTP-only domain tests)
  • Integrated protocol testing into smoke-codex-firewall.md (added HTTPS-only domain test)
  • Both workflows now verify protocol prefixes are preserved in AWF --allow-domains flag
  • Reduced code duplication while maintaining test coverage

description: Smoke test for protocol-specific domain filtering
on:
schedule: every 24h
workflow_dispatch:
pull_request:
types: [labeled]
names: ["smoke-protocol-domains"]
reaction: "eyes"
permissions:
contents: read
pull-requests: read
issues: read
name: Smoke Protocol Domains
engine: copilot
network:
allowed:
- defaults
- node
- github
- "https://api.github.com" # HTTPS-only (should work since api.github.com is in defaults)
- "http://httpbin.org" # HTTP-only test endpoint
sandbox:
agent: awf # Firewall enabled
tools:
bash:
- "*"
github:
web-fetch:
safe-outputs:
add-comment:
hide-older-comments: true
add-labels:
allowed: [smoke-protocol-domains]
messages:
footer: "> 🔒 *Protocol Security Test: Report by [{workflow_name}]({run_url})*"
run-started: "🔒 Protocol filtering test [{workflow_name}]({run_url}) started..."
run-success: "✅ Protocol filtering test [{workflow_name}]({run_url}) passed. All protocol restrictions working correctly."
run-failure: "❌ Protocol filtering test [{workflow_name}]({run_url}) failed with {status}."
timeout-minutes: 5
strict: true
---

# Smoke Test: Protocol-Specific Domain Filtering

**IMPORTANT: Keep outputs short and concise.**

## Test Requirements

Test protocol-specific domain filtering with the AWF firewall:

1. **HTTPS-only Domain Test**: Verify that `https://api.github.com` is accessible (included in defaults with protocol prefix)
2. **HTTP-only Domain Test**: Verify that `http://httpbin.org` would be accessible if tested (network allows HTTP-only)
3. **Mixed Protocol Test**: Verify that domains without protocol prefixes (from defaults/ecosystems) work with both HTTP and HTTPS
4. **Firewall Configuration Verification**: Confirm the AWF `--allow-domains` flag includes protocol prefixes in the workflow logs

## Test Actions

1. Use web_fetch to access `https://api.github.com/repos/githubnext/gh-aw` (should succeed)
2. Check `/tmp/gh-aw/agent-stdio.log` for the AWF command line to verify protocol prefixes are passed correctly
3. Look for patterns like `https://api.github.com` and `http://httpbin.org` in the --allow-domains flag

## Output

Add a **brief** comment to the current pull request with:
- ✅ HTTPS-only domain access test result
- ✅ Protocol prefix verification in AWF command
- ✅ Overall protocol filtering status
- Overall status: PASS or FAIL

If all tests pass, add the label `smoke-protocol-domains` to the pull request.

**Expected AWF command should include:** `--allow-domains ...,http://httpbin.org,https://api.github.com,...`
25 changes: 25 additions & 0 deletions docs/src/content/docs/guides/network-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ network:
- "*.cdn.example.com" # Wildcard for subdomains
```

## Protocol-Specific Filtering

Restrict domains to specific protocols for enhanced security (Copilot engine with AWF firewall):

```yaml
engine: copilot
network:
allowed:
- defaults
- "https://secure.api.example.com" # HTTPS-only
- "http://legacy.internal.com" # HTTP-only (legacy systems)
- "example.org" # Both protocols (default)
sandbox:
agent: awf # Firewall enabled
```

**Use Cases:**
- **HTTPS-only**: External APIs, production services
- **HTTP-only**: Legacy internal systems, development endpoints
- **Mixed**: Gradual HTTP → HTTPS migration

**Validation:** Invalid protocols (e.g., `ftp://`) are rejected at compile time.

See [Network Permissions - Protocol-Specific Filtering](/gh-aw/reference/network/#protocol-specific-domain-filtering) for complete details.

## Security Best Practices

1. **Start minimal** - Only add ecosystems you actually use
Expand Down
56 changes: 56 additions & 0 deletions docs/src/content/docs/reference/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ network:
- "api.example.com" # Exact domain
- "trusted.com" # Includes all *.trusted.com subdomains

# Protocol-specific domain filtering (Copilot engine only)
network:
allowed:
- "https://secure.api.example.com" # HTTPS-only access
- "http://legacy.example.com" # HTTP-only access
- "example.org" # Both HTTP and HTTPS (default)

# No network access
network: {}
```
Expand All @@ -54,6 +61,55 @@ Network permissions follow the principle of least privilege with four access lev
AWF does not support wildcard syntax like `*.example.com`. Instead, listing a domain automatically includes all its subdomains. Use `example.com` to allow access to `example.com`, `api.example.com`, `sub.api.example.com`, etc.
:::

## Protocol-Specific Domain Filtering

For fine-grained security control, you can restrict domains to specific protocols (HTTP or HTTPS only). This is particularly useful when:
- Working with legacy systems that only support HTTP
- Ensuring secure connections by restricting to HTTPS-only
- Migrating from HTTP to HTTPS gradually

:::tip[Copilot Engine Support]
Protocol-specific filtering is currently supported by the Copilot engine with AWF firewall enabled. Domains without protocol prefixes allow both HTTP and HTTPS traffic (backward compatible).
:::

### Usage Examples

```yaml wrap
engine: copilot
network:
allowed:
- "https://secure.api.example.com" # HTTPS-only access
- "http://legacy.example.com" # HTTP-only access
- "example.org" # Both protocols (default)
- "https://*.api.example.com" # HTTPS wildcard
```

**Compiled to AWF:**
```bash
--allow-domains ...,example.org,http://legacy.example.com,https://secure.api.example.com,...
```

### Supported Protocols

- `https://` - HTTPS-only access
- `http://` - HTTP-only access
- No prefix - Both HTTP and HTTPS (backward compatible)

:::caution[Protocol Validation]
Invalid protocols (e.g., `ftp://`, `ws://`) are rejected at compile time with a clear error message:
```
error: network.allowed[0]: domain pattern 'ftp://invalid.example.com'
has invalid protocol, only 'http://' and 'https://' are allowed
```
:::

### Best Practices

- **Prefer HTTPS**: Use `https://` prefix for all external APIs and services
- **Legacy Systems**: Only use `http://` for internal or legacy systems that don't support HTTPS
- **Default Behavior**: Omit the protocol prefix for domains that should accept both protocols
- **Gradual Migration**: Use protocol-specific filtering to migrate from HTTP to HTTPS incrementally

## Content Sanitization

The `network:` configuration also controls which domains are allowed in sanitized content. URLs from domains not in the allowed list are replaced with `(redacted)` to prevent potential data exfiltration through untrusted links.
Expand Down
15 changes: 15 additions & 0 deletions pkg/workflow/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,21 @@ func (c *Compiler) CompileWorkflowData(workflowData *WorkflowData, markdownPath
return errors.New(formattedErr)
}

// Validate network allowed domains configuration
log.Printf("Validating network allowed domains")
if err := validateNetworkAllowedDomains(workflowData.NetworkPermissions); err != nil {
formattedErr := console.FormatError(console.CompilerError{
Position: console.ErrorPosition{
File: markdownPath,
Line: 1,
Column: 1,
},
Type: "error",
Message: err.Error(),
})
return errors.New(formattedErr)
}

// Emit experimental warning for sandbox-runtime feature
if isSRTEnabled(workflowData) {
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Using experimental feature: sandbox-runtime firewall"))
Expand Down
Loading
Loading