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
572 changes: 572 additions & 0 deletions .github/workflows/example-engine-network-permissions.lock.yml

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions .github/workflows/example-engine-network-permissions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
on:
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: read

engine:
id: claude
permissions:
network:
allowed:
- "docs.github.com"

tools:
claude:
allowed:
WebFetch:
WebSearch:
---

# Secure Web Research Task

Please research the GitHub API documentation or Stack Overflow and find information about repository topics. Summarize them in a brief report.
108 changes: 108 additions & 0 deletions .github/workflows/test-claude.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .github/workflows/test-claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ on:
engine:
id: claude
model: claude-3-5-sonnet-20241022
permissions:
network:
allowed: []
timeout_minutes: 10
permissions:
pull-requests: write
Expand Down
92 changes: 91 additions & 1 deletion docs/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The YAML frontmatter supports standard GitHub Actions properties plus additional
- `steps`: Custom steps for the job

**Properties specific to GitHub Agentic Workflows:**
- `engine`: AI engine configuration (claude/codex) with optional max-turns setting
- `engine`: AI engine configuration (claude/codex) with optional max-turns setting and network permissions
- `tools`: Available tools and MCP servers for the AI engine
- `cache`: Cache configuration for workflow dependencies
- `output`: [Safe Output Processing](safe-outputs.md) for automatic issue creation and comment posting.
Expand Down Expand Up @@ -161,13 +161,21 @@ engine:
version: beta # Optional: version of the action
model: claude-3-5-sonnet-20241022 # Optional: specific LLM model
max-turns: 5 # Optional: maximum chat iterations per run
permissions: # Optional: engine-level permissions (only Claude is supported)
network: # Network access control
allowed: # List of allowed domains
- "api.example.com"
- "*.trusted.com"
```

**Fields:**
- **`id`** (required): Engine identifier (`claude`, `codex`)
- **`version`** (optional): Action version (`beta`, `stable`)
- **`model`** (optional): Specific LLM model to use
- **`max-turns`** (optional): Maximum number of chat iterations per run (cost-control option)
- **`permissions`** (optional): Engine-level permissions
- **`network`** (optional): Network access control
- **`allowed`** (optional): List of allowed domains for WebFetch and WebSearch

**Model Defaults:**
- **Claude**: Uses the default model from the claude-code-base-action (typically latest Claude model)
Expand All @@ -191,6 +199,88 @@ engine:
3. Helps prevent runaway chat loops and control costs
4. Only applies to engines that support turn limiting (currently Claude)

## Engine Network Permissions

> This is only supported by the claude engine today.

Control network access for AI engines using the `permissions` field in the `engine` block:

```yaml
engine:
id: claude
permissions:
network:
allowed:
- "api.example.com" # Exact domain match
- "*.trusted.com" # Wildcard matches any subdomain (including nested subdomains)
```

### Security Model

- **Deny by Default**: When network permissions are specified, only listed domains are accessible
- **Engine vs Tools**: Engine permissions control the AI engine itself, separate from MCP tool permissions
- **Hook Enforcement**: Uses Claude Code's hook system for runtime network access control
- **Domain Validation**: Supports exact matches and wildcard patterns (`*` matches any characters including dots, allowing nested subdomains)

### Examples

```yaml
# Allow specific APIs only
engine:
id: claude
permissions:
network:
allowed:
- "api.github.com"
- "httpbin.org"

# Allow all subdomains of a trusted domain
# Note: "*.github.com" matches api.github.com, subdomain.github.com, and even nested.api.github.com
engine:
id: claude
permissions:
network:
allowed:
- "*.company-internal.com"
- "public-api.service.com"

# Deny all network access (empty list)
engine:
id: claude
permissions:
network:
allowed: []
```

### Permission Modes

1. **No network permissions**: Unrestricted access (backwards compatible)
```yaml
engine:
id: claude
# No permissions block - full network access
```

2. **Empty allowed list**: Complete network access denial
```yaml
engine:
id: claude
permissions:
network:
allowed: [] # Deny all network access
```

3. **Specific domains**: Granular access control to listed domains only
```yaml
engine:
id: claude
permissions:
network:
allowed:
- "trusted-api.com"
- "*.safe-domain.org"
```

## Output Configuration (`output:`)

See [Safe Output Processing](safe-outputs.md) for automatic issue creation and comment posting.
Expand Down
61 changes: 60 additions & 1 deletion docs/security-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ In addition, the compilation step of Agentic Workflows enforces additional secur
- **Expression restrictions** - only a limited set of expressions are allowed in the workflow frontmatter, preventing arbitrary code execution
- **Highly restricted commands** - by default, no commands are allowed to be executed, and any commands that are allowed must be explicitly specified in the workflow
- **Explicit tool allowlisting** - only tools explicitly allowed in the workflow can be used
- **Engine network restrictions** - control network access for AI engines using domain allowlists
- **Limit workflow longevity** - workflows can be configured to stop triggering after a certain time period
- **Limit chat iterations** - workflows can be configured to limit the number of chat iterations per run, preventing runaway loops and excessive resource consumption

Expand Down Expand Up @@ -211,6 +212,63 @@ Protect against model manipulation through layered defenses:
- **Input sanitization**: Minimize untrusted content exposure; strip embedded commands when not required for functionality
- **Action validation**: Implement a plan-validate-execute flow where policy layers check each tool call against risk thresholds

## Engine Network Permissions

### Overview

Engine network permissions provide fine-grained control over network access for AI engines themselves, separate from MCP tool network permissions. This feature uses Claude Code's hook system to enforce domain-based access controls.

### Security Benefits

1. **Defense in Depth**: Additional layer beyond MCP tool restrictions
2. **Compliance**: Meet organizational security requirements for AI network access
3. **Audit Trail**: Network access attempts are logged through Claude Code hooks
4. **Principle of Least Privilege**: Only grant network access to required domains

### Implementation Details

- **Hook-Based Enforcement**: Uses Claude Code's PreToolUse hooks to intercept network requests
- **Runtime Validation**: Domain checking happens at request time, not compilation time
- **Error Handling**: Blocked requests receive clear error messages with allowed domains
- **Performance Impact**: Minimal overhead (~10ms per network request)

### Best Practices

1. **Always Specify Permissions**: When using network features, explicitly list allowed domains
2. **Use Wildcards Carefully**: `*.example.com` matches any subdomain including nested ones (e.g., `api.example.com`, `nested.api.example.com`) - ensure this broad access is intended
3. **Test Thoroughly**: Verify that all required domains are included in allowlist
4. **Monitor Usage**: Review workflow logs to identify any blocked legitimate requests
5. **Document Reasoning**: Comment why specific domains are required for maintenance

### Permission Modes

1. **No network permissions**: Unrestricted access (backwards compatible)
```yaml
engine:
id: claude
# No permissions block - full network access
```

2. **Empty allowed list**: Complete network access denial
```yaml
engine:
id: claude
permissions:
network:
allowed: [] # Deny all network access
```

3. **Specific domains**: Granular access control to listed domains only
```yaml
engine:
id: claude
permissions:
network:
allowed:
- "api.github.com"
- "*.company-internal.com"
```

## Engine Security Notes

Different agentic engines have distinct defaults and operational surfaces.
Expand All @@ -219,10 +277,11 @@ Different agentic engines have distinct defaults and operational surfaces.

- Restrict `claude.allowed` to only the needed capabilities (Edit/Write/WebFetch/Bash with a short list)
- Keep `allowed_tools` minimal in the compiled step; review `.lock.yml` outputs
- Use engine network permissions to restrict WebFetch and WebSearch to required domains only

#### Security posture differences with Codex

Claude exposes richer default tools and optional Bash; codex relies more on CLI behaviors. In both cases, tool allow-lists and pinned dependencies are your primary controls.
Claude exposes richer default tools and optional Bash; codex relies more on CLI behaviors. In both cases, tool allow-lists, network restrictions, and pinned dependencies are your primary controls.

## See also

Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
github.com/sourcegraph/conc v0.3.0
github.com/spf13/cobra v1.9.1
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -27,7 +26,6 @@ require (
github.com/fatih/color v1.7.0 // indirect
github.com/henvic/httpretty v0.1.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
Expand Down
Loading