Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 2, 2025

Adds support for specifying a custom AWF binary path in the firewall configuration, bypassing the default GitHub release download.

Usage

network:
  allowed:
    - defaults
  firewall:
    path: /custom/path/to/awf  # Absolute path
    # or
    path: bin/awf              # Relative to GITHUB_WORKSPACE
    log-level: info

Changes

  • FirewallConfig struct (pkg/workflow/firewall.go): Added Path field
  • JSON schema (pkg/parser/schemas/main_workflow_schema.json): Added path property to firewall object
  • Frontmatter extraction (pkg/workflow/frontmatter_extraction.go): Extract path from firewall config
  • Copilot engine (pkg/workflow/copilot_engine.go):
    • resolveAWFPath() - resolves absolute paths as-is, relative paths against ${GITHUB_WORKSPACE}
    • getAWFBinaryPath() - returns custom path or default awf
    • generateAWFPathValidationStep() - creates step to verify binary exists and is executable
    • Modified GetInstallationSteps() to emit validation step instead of install step when path is set
    • Modified GetExecutionSteps() to use dynamic binary path

Behavior

Config Installation Step Execution
No path Downloads AWF from GitHub releases Uses awf from PATH
path: /abs/path Validates binary exists Uses /abs/path
path: rel/path Validates binary exists Uses ${GITHUB_WORKSPACE}/rel/path

When path is specified, the version field is ignored.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

you are tasked to support custom awf installation path in agentic workflow frontmatter configurations, allowing users to bypass the default GitHub release download mechanism and use their own AWF binaries.

Recommended Approach

User-Facing Syntax

network:
  allowed:
    - defaults
    - node
  firewall:
    path: /custom/path/to/awf  # Absolute or relative path
    log-level: info

Path resolution rules:

  • Paths starting with / are treated as absolute paths
  • Other paths are treated as relative to ${GITHUB_WORKSPACE} (repository root)
  • When path is specified, AWF download is skipped
  • The version field is ignored when path is provided

Implementation Steps

1. Data Structure Changes

File: pkg/workflow/firewall.go (line ~16)

Add Path field to FirewallConfig struct:

type FirewallConfig struct {
    Enabled       bool     `yaml:"enabled,omitempty"`
    Version       string   `yaml:"version,omitempty"`
    Args          []string `yaml:"args,omitempty"`
    LogLevel      string   `yaml:"log_level,omitempty"`
    CleanupScript string   `yaml:"cleanup_script,omitempty"`
    Path          string   `yaml:"path,omitempty"`  // NEW: Custom AWF binary path
}

2. Schema Updates

File: pkg/parser/schemas/main_workflow_schema.json (line ~1670)

Add path property to firewall object schema:

"path": {
  "type": "string",
  "description": "Custom path to AWF binary. When specified, skips downloading AWF from GitHub releases. Supports absolute paths or paths relative to GITHUB_WORKSPACE."
}

3. Frontmatter Extraction

File: pkg/workflow/frontmatter_extraction.go (after line 686)

Add path extraction in extractFirewallConfig:

// Extract path if present
if path, hasPath := firewallObj["path"]; hasPath {
    if pathStr, ok := path.(string); ok {
        config.Path = pathStr
    }
}

4. Core Logic Changes

File: pkg/workflow/copilot_engine.go

4.1 Modify GetInstallationSteps (lines 64-76)

Change from unconditional AWF installation to conditional:

// Add AWF installation or validation steps
if isFirewallEnabled(workflowData) {
    firewallConfig := getFirewallConfig(workflowData)

    if firewallConfig == nil || firewallConfig.Path == "" {
        // Default: Download and install AWF from GitHub releases
        var awfVersion string
        if firewallConfig != nil {
            awfVersion = firewallConfig.Version
        }
        awfInstall := generateAWFInstallationStep(awfVersion)
        steps = append(steps, awfInstall)
    } else {
        // Custom path: Validate the binary exists and is executable
        validationStep := generateAWFPathValidationStep(firewallConfig.Path)
        steps = append(steps, validationStep)
    }
}

4.2 Add New Helper Functions (after line 867)

Function: generateAWFPathValidationStep

Creates a validation step to verify custom AWF binary:

func generateAWFPathValidationStep(customPath string) GitHubActionStep {
    resolvedPath := resolveAWFPath(customPath)

    stepLines := []string{
        "      - name: Validate custom AWF binary",
        "        run: |",
        fmt.Sprintf("          echo \"Validating custom AWF binary at: %s\"", resolvedPath),
        fmt.Sprintf("          if [ ! -f %s ]; then", shellEscapeArg(resolvedPath)),
        fmt.Sprintf("            echo \"Error: AWF binary not found at %s\"", resolvedPath),
        "            exit 1",
        "          fi",
        fmt.Sprintf("          if [ ! -x %s ]; then", shellEscapeArg(resolvedPath)),
        fmt.Sprintf("            echo \"Error: AWF binary at %s is not executable\"", resolvedPath),
        "            exit 1",
        "          fi",
        fmt.Sprintf("          %s --version", shellEscapeArg(resolvedPath)),
    }

    return GitHubActionStep(stepLines)
}

Function: resolveAWFPath

Handles path resolution for absolute and relative paths:

func resolveAWFPath(customPath string) string {
    if customPath == "" {
        return "/usr/local/bin/awf"
    }

    if strings.HasPrefix(customPath, "/") {
        return customPath  // Absolute path
    }

    // Relative path - resolve against GITHUB_WORKSPACE
    return fmt.Sprintf("${GITHUB_WORKSPACE}/%s", customPath)
}

Function: getAWFBinaryPath

Returns appropriate AWF binary path for execution:

func getAWFBinaryPath(firewallConfig *FirewallConfig) string {
    if firewallConfig != nil && firewallConfig.Path != "" {
        return resolveAWFPath(firewallConfig.Path)
    }
    return "awf"  // Default (in PATH from installation step)
}

4.3 Update GetExecutionSteps (line 256)

Change from hardcoded awf to dynamic path:

// Get AWF binary path (custom or default)
awfBinary := getAWFBinaryPath(firewallConfig)

// Build AWF command
command = fmt.Sprintf(`set -o pipefail
sudo -E %s %s \
  -- %s \
  2>&1 | tee %s`,
  shellEscapeArg(awfBinary),
  shellJoinA...

</details>



<!-- START COPILOT CODING AGENT TIPS -->
---Let Copilot coding agent [set things up for you](https://github.com/githubnext/gh-aw/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.


---

## Changeset

- **Type**: patch
- **Description**: Support custom AWF installation path in firewall configuration; validates and uses user-provided AWF binary when `network.firewall.path` is set, skipping AWF download and ignoring `version` when `path` is specified.

> AI generated by [Changeset Generator](https://github.com/githubnext/gh-aw/actions/runs/19879115553)

---

---

## Smoke Test Summary

**Timestamp**: 2025-12-03T01:25:07Z  
**Status**: PASS  
All Copilot engine tests validated successfully (GitHub MCP, file I/O, bash, playwright)

> AI generated by [Smoke Copilot No Firewall](https://github.com/githubnext/gh-aw/actions/runs/19879115603)

Add support for a custom `path` field in the firewall configuration that allows
users to bypass the default GitHub release download mechanism and use their own
AWF binaries.

Path resolution rules:
- Paths starting with `/` are treated as absolute paths
- Other paths are resolved relative to GITHUB_WORKSPACE
- When `path` is specified, AWF download is skipped
- A validation step verifies the binary exists and is executable

Changes:
- Add Path field to FirewallConfig struct
- Add path property to JSON schema
- Extract path from frontmatter in extractFirewallConfig
- Add helper functions: resolveAWFPath, getAWFBinaryPath, generateAWFPathValidationStep
- Modify GetInstallationSteps to generate validation step when path is specified
- Modify GetExecutionSteps to use dynamic AWF binary path
- Add unit tests and integration tests

Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for custom AWF installation path Support custom AWF installation path in firewall configuration Dec 3, 2025
Copilot AI requested a review from Mossaka December 3, 2025 00:16
@Mossaka Mossaka marked this pull request as ready for review December 3, 2025 01:22
@Mossaka Mossaka added the smoke label Dec 3, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

🤖 SYSTEM_INIT: Smoke Copilot No Firewall ACTIVATED. PROCESSING pull request. ALL SUBSYSTEMS ONLINE.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

📰 BREAKING: Smoke Copilot Playwright is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

🔮 The ancient spirits stir... Smoke Codex awakens to divine this pull request...

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

🎉 Yo ho ho! Changeset Generator found the treasure and completed successfully! ⚓💰

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

💥 WHOOSH! Smoke Claude springs into action on this pull request! [Panel 1 begins...]

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Smoke Test Results

Last 2 Merged PRs:

Test Results:

  • ✅ GitHub MCP Testing
  • ✅ File Writing Testing
  • ✅ Bash Tool Testing

Overall Status: PASS

📰 BREAKING: Report filed by Smoke Copilot fer issue #5339 🗺️

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Smoke Test Results - Copilot Engine (No Firewall)

Test timestamp: 2025-12-03T01:25:07Z

Overall Status: PASS

🤖 DIAGNOSTIC REPORT GENERATED BY Smoke Copilot No Firewall fer issue #5339 🗺️

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Smoke Test Results (Claude)

Last 2 Merged PRs:

Test Results:

  • ✅ GitHub MCP: Retrieved PR titles
  • ✅ File Writing: Created test file successfully
  • ✅ Bash Tool: Verified file contents
  • ✅ Playwright MCP: Navigated to GitHub, title verified

Overall Status: PASS

💥 [THE END] — Illustrated by Smoke Claude fer issue #5339 🗺️

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Recent merged PRs:
Migrate workflow commands (run, status, logs, audit) to RunE
Convert embedded custom agents to prompt file format
✅ GitHub MCP review
✅ File write
✅ File read (cat)
✅ Playwright title contains GitHub
Overall: PASS

🔮 The oracle has spoken through Smoke Codex fer issue #5339 🗺️

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Smoke Test Results

Playwright MCP: Navigate to https://github.com and verify title contains "GitHub"

Overall Status: PASS

📰 BREAKING: Report filed by Smoke Copilot Playwright fer issue #5339 🗺️

@pelikhan pelikhan closed this Dec 3, 2025
@pelikhan pelikhan deleted the copilot/support-custom-awf-installation-path branch December 4, 2025 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants