diff --git a/.github/aw/github-agentic-workflows.md b/.github/aw/github-agentic-workflows.md index 0bb5325166a..0b3df484a9c 100644 --- a/.github/aw/github-agentic-workflows.md +++ b/.github/aw/github-agentic-workflows.md @@ -233,33 +233,17 @@ The YAML frontmatter supports these fields: allowed: - "example.com" - "*.trusted-domain.com" + firewall: true # Optional: Enable AWF (Agent Workflow Firewall) for Copilot engine ``` - - **⚠️ Deprecated**: `firewall` field moved to `sandbox.agent` configuration - -- **`sandbox:`** - Sandbox environment configuration (object) - - **`agent:`** - Agent sandbox type for runtime isolation - - `awf` - Agent Workflow Firewall (default, network egress control) - - `srt` - Sandbox Runtime (experimental, requires `sandbox-runtime` feature flag) - - `false` - Disable firewall (replaces deprecated `network.firewall: false`) - - Example: - ```yaml - sandbox: - agent: awf # Enable AWF for network control - ``` - - **`mcp:`** - MCP Gateway configuration (experimental, requires `mcp-gateway` feature flag) - - `container:` - Docker container for MCP gateway (string) - - `port:` - Gateway port (integer) - - `api-key:` - API key for gateway authentication (must use `${{ secrets.* }}` syntax) - - Example: - ```yaml - sandbox: - agent: awf - mcp: - container: "ghcr.io/your-org/mcp-gateway" - port: 8080 - api-key: "${{ secrets.MCP_GATEWAY_API_KEY }}" - ``` - + - **Firewall configuration** (Copilot engine only): + ```yaml + network: + firewall: + version: "v1.0.0" # Optional: AWF version (defaults to latest) + log-level: debug # Optional: debug, info (default), warn, error + args: ["--custom-arg", "value"] # Optional: additional AWF arguments + ``` + - **`tools:`** - Tool configuration for coding agent - `github:` - GitHub API tools - `allowed:` - Array of allowed GitHub API functions @@ -269,10 +253,10 @@ The YAML frontmatter supports these fields: - `read-only:` - Restrict to read-only operations (boolean) - `github-token:` - Custom GitHub token - `toolsets:` - Enable specific GitHub toolset groups (array only) - - **Default toolsets** (when unspecified): `context`, `repos`, `issues`, `pull_requests` (excludes `users` - not supported by GitHub Actions tokens) + - **Default toolsets** (when unspecified): `context`, `repos`, `issues`, `pull_requests`, `users` - **All toolsets**: `context`, `repos`, `issues`, `pull_requests`, `actions`, `code_security`, `dependabot`, `discussions`, `experiments`, `gists`, `labels`, `notifications`, `orgs`, `projects`, `secret_protection`, `security_advisories`, `stargazers`, `users`, `search` - - Use `[default]` or `[action-friendly]` for GitHub Actions-compatible toolsets, `[all]` to enable everything - - Examples: `toolsets: [default]`, `toolsets: [action-friendly]`, `toolsets: [default, discussions]`, `toolsets: [repos, issues]` + - Use `[default]` for recommended toolsets, `[all]` to enable everything + - Examples: `toolsets: [default]`, `toolsets: [default, discussions]`, `toolsets: [repos, issues]` - **Recommended**: Prefer `toolsets:` over `allowed:` for better organization and reduced configuration verbosity - `agentic-workflows:` - GitHub Agentic Workflows MCP server for workflow introspection - Provides tools for: @@ -289,35 +273,6 @@ The YAML frontmatter supports these fields: - `playwright:` - Browser automation tools - Custom tool names for MCP servers -- **`safe-inputs:`** - Custom inline MCP tool definitions (experimental) - - Define custom tools inline using JavaScript, shell, or Python scripts - - Each tool has: `description` (required), `inputs` (parameters), implementation (`script`, `run`, or `py`), `env` (environment variables), `timeout` (seconds) - - Tools are automatically mounted as an MCP server at runtime - - Example: - ```yaml - safe-inputs: - greet-user: - description: "Greet a user by name" - inputs: - name: - type: string - required: true - script: | - return { message: `Hello, ${name}!` }; - fetch-data: - description: "Fetch data from API" - run: | - curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com/data - env: - API_TOKEN: "${{ secrets.API_TOKEN }}" - timeout: 120 - ``` - - **Implementation options:** - - `script:` - JavaScript (CommonJS) code, automatically wrapped in async function - - `run:` - Shell script (bash) - - `py:` - Python script (Python 3.1x) - - **Note**: Use only one implementation method per tool - - **`safe-outputs:`** - Safe output processing configuration (preferred way to handle GitHub API write operations) - `create-issue:` - Safe GitHub issue creation (bugs, features) ```yaml @@ -918,6 +873,7 @@ network: - node # Node.js/NPM ecosystem - containers # Container registries - "api.custom.com" # Custom domain + firewall: true # Enable AWF (Copilot engine only) # Or allow specific domains only network: @@ -928,10 +884,6 @@ network: # Or deny all network access network: {} - -# Enable AWF (Agent Workflow Firewall) - use sandbox.agent instead -sandbox: - agent: awf # Default firewall for network control ``` **Important Notes:** @@ -941,7 +893,7 @@ sandbox: - Use ecosystem identifiers (`python`, `node`, `java`, etc.) for language-specific tools - When custom permissions are specified with `allowed:` list, deny-by-default policy is enforced - Supports exact domain matches and wildcard patterns (where `*` matches any characters, including nested subdomains) -- **Firewall configuration**: Use `sandbox.agent: awf` to enable AWF (Agent Workflow Firewall) for domain-based access control (replaces deprecated `network.firewall: true`) +- **Firewall support**: Copilot engine supports AWF (Agent Workflow Firewall) for domain-based access control - Claude engine uses hooks for enforcement; Codex support planned **Permission Modes:** diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 326a7745951..ff08e762e0e 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6276,13 +6276,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 with: artifact-name: sbom.cdx.json format: cyclonedx-json diff --git a/pkg/workflow/repository_features_validation.go b/pkg/workflow/repository_features_validation.go index f0634e1798c..d2765cf3343 100644 --- a/pkg/workflow/repository_features_validation.go +++ b/pkg/workflow/repository_features_validation.go @@ -43,6 +43,7 @@ import ( "sync" "github.com/cli/go-gh/v2" + "github.com/cli/go-gh/v2/pkg/repository" "github.com/githubnext/gh-aw/pkg/console" "github.com/githubnext/gh-aw/pkg/logger" ) @@ -175,22 +176,23 @@ func getCurrentRepository() (string, error) { // getCurrentRepositoryUncached fetches the current repository from gh CLI (no caching) func getCurrentRepositoryUncached() (string, error) { - repositoryFeaturesLog.Print("Fetching current repository from gh CLI") + repositoryFeaturesLog.Print("Fetching current repository using repository.Current()") - // Use gh CLI to get the current repository - // This works when in a git repository with GitHub remote - stdOut, _, err := gh.Exec("repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner") + // Use native repository.Current() to get the current repository + // This works when in a git repository with GitHub remote and respects GH_REPO + repo, err := repository.Current() if err != nil { return "", fmt.Errorf("failed to get current repository: %w", err) } - repo := strings.TrimSpace(stdOut.String()) - if repo == "" { - return "", fmt.Errorf("repository name is empty") + // Validate that owner and name are not empty + if repo.Owner == "" || repo.Name == "" { + return "", fmt.Errorf("repository owner or name is empty (owner: %q, name: %q)", repo.Owner, repo.Name) } - repositoryFeaturesLog.Printf("Cached current repository: %s", repo) - return repo, nil + repoName := fmt.Sprintf("%s/%s", repo.Owner, repo.Name) + repositoryFeaturesLog.Printf("Cached current repository: %s", repoName) + return repoName, nil } // getRepositoryFeatures gets repository features with caching to amortize API calls