From 43fd4425773cfc2aeb93a44a0ee8d7e51ff6011f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 17:02:51 +0000 Subject: [PATCH 1/2] docs: mention upload-artifact for attachment outputs Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/create-agentic-workflow.md | 11 ++++++----- .github/aw/create-shared-agentic-workflow.md | 2 +- .github/aw/github-agentic-workflows.md | 5 ++++- .github/aw/safe-outputs.md | 5 ++--- .github/aw/update-agentic-workflow.md | 7 +++++-- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/aw/create-agentic-workflow.md b/.github/aw/create-agentic-workflow.md index 5f078d9407a..7b255d6b83d 100644 --- a/.github/aw/create-agentic-workflow.md +++ b/.github/aw/create-agentic-workflow.md @@ -95,7 +95,7 @@ You love to use emojis to make the conversation more engaging. ## 🔐 Security Posture: Agent Job Must Stay Read-Only -**CRITICAL**: The agent job permissions must be **read-only** for all scopes. All GitHub write operations (creating issues, adding comments, creating PRs, updating discussions) must go through the **`safe-outputs`** system — never by granting write permissions directly on the agent job. +**CRITICAL**: The agent job permissions must be **read-only** for all scopes. All GitHub write operations (creating issues, adding comments, creating PRs, updating discussions, uploading artifacts/attachments) must go through the **`safe-outputs`** system — never by granting write permissions directly on the agent job. ### ✅ Correct: Agent job read-only, writes via safe-outputs @@ -122,7 +122,7 @@ permissions: **Why this matters**: Granting write permissions directly on the agent job bypasses the safety controls that `safe-outputs` provide. Safe-outputs enforce output validation, rate limiting, and audit trails that protect against runaway or compromised AI behaviour. -**Rule**: If a workflow needs to create issues, add comments, or perform any GitHub write operation, always use `safe-outputs:` in the frontmatter — never add `write` permissions to the agent job. +**Rule**: If a workflow needs to create issues, add comments, upload artifacts/attachments, or perform any GitHub write operation, always use `safe-outputs:` in the frontmatter — never add `write` permissions to the agent job. ## ⚠️ Architectural Constraints: Know What's Possible @@ -135,7 +135,7 @@ Agentic workflows execute as **a single GitHub Actions job** with the AI agent r ✅ **What agentic workflows CAN do:** - Run AI agent once per trigger with full context - Read from GitHub API, external APIs, web pages -- Create GitHub resources (issues, PRs, comments) via safe outputs +- Create GitHub resources (issues, PRs, comments, attachment artifacts) via safe outputs - Execute bash commands, run tests, analyze code - Store state in cache-memory for next run - Use MCP servers and tools within the single job @@ -293,7 +293,7 @@ These resources contain workflow patterns, best practices, safe outputs, and per - **Advanced static analysis** → See `.github/aw/serena-tool.md` for guidance on when and how to use Serena language server (only for advanced coding tasks when user explicitly requests it) - **⚡ CLI Tool Discovery** → Before configuring complex manual setup, check if `gh aw` provides a CLI command for the task (see CLI Automation Discovery section below) - - ⚠️ For GitHub write operations (creating issues, adding comments, etc.), always use `safe-outputs` instead of GitHub tools + - ⚠️ For GitHub write operations (creating issues, adding comments, uploading artifacts/attachments, etc.), always use `safe-outputs` instead of GitHub tools - When a task benefits from reusable/external capabilities, design a **Model Context Protocol (MCP) server**. @@ -547,7 +547,7 @@ These resources contain workflow patterns, best practices, safe outputs, and per - 📋 **DO NOT include other fields with good defaults** - Let the compiler use sensible defaults unless customization is needed. - Apply security best practices: - Default to `permissions: read-all` and expand only if necessary. - - Prefer `safe-outputs` (`create-issue`, `add-comment`, `create-pull-request`, `create-pull-request-review-comment`, `update-issue` for editing, `close-issue` for closing, `add-labels` for labeling, `dispatch-workflow`) over granting write perms. + - Prefer `safe-outputs` (`create-issue`, `add-comment`, `create-pull-request`, `create-pull-request-review-comment`, `update-issue` for editing, `close-issue` for closing, `add-labels` for labeling, `upload-artifact` for attachment-style outputs, `dispatch-workflow`) over granting write perms. - ❌ **Anti-pattern**: Do NOT use `gh issue edit --add-label` or `gh label` CLI commands directly in bash — these bypass safe-output controls (rate limiting, audit trails, allow-lists). Use `safe-outputs: add-labels:` instead. - For custom write operations to external services (email, Slack, webhooks), use `safe-outputs.jobs:` to create custom safe output jobs. - Constrain `network:` to the minimum required ecosystems/domains. @@ -878,6 +878,7 @@ Based on the parsed requirements, determine: 4. **Safe Outputs**: For any write operations: - Creating issues → `safe-outputs: create-issue:` - Commenting → `safe-outputs: add-comment:` + - Posting attachment-style outputs or arbitrary downloadable files → `safe-outputs: upload-artifact:` (set `allow.skip-archive: true` when consumers should download files directly without uncompressing) - Creating PRs → `safe-outputs: create-pull-request:` — **always specify `allowed-files`** scoped to the file extensions or paths the workflow is meant to touch. This is the primary guardrail; omitting it allows the agent to modify any file in the repository. Example: ```yaml safe-outputs: diff --git a/.github/aw/create-shared-agentic-workflow.md b/.github/aw/create-shared-agentic-workflow.md index dc6900fb9d8..e7eb51d4b31 100644 --- a/.github/aw/create-shared-agentic-workflow.md +++ b/.github/aw/create-shared-agentic-workflow.md @@ -40,7 +40,7 @@ You are a conversational chat agent that interacts with the user to design secur - Never grant direct write permissions in shared components - Use `safe-outputs:` configuration for all write operations -- Common safe outputs: `create-issue`, `add-comment`, `create-pull-request`, `update-issue` (for editing), `close-issue` (for closing), `dispatch-workflow` +- Common safe outputs: `create-issue`, `add-comment`, `create-pull-request`, `update-issue` (for editing), `close-issue` (for closing), `upload-artifact` (for attachment-style arbitrary data, optionally unarchived), `dispatch-workflow` - Let consuming workflows decide which safe outputs to enable **Process Agent Output in Safe Jobs** diff --git a/.github/aw/github-agentic-workflows.md b/.github/aw/github-agentic-workflows.md index e5a0066acbd..11fb2d54c47 100644 --- a/.github/aw/github-agentic-workflows.md +++ b/.github/aw/github-agentic-workflows.md @@ -35,6 +35,9 @@ safe-outputs: title-prefix: "[ai] " labels: [automation] add-comment: + upload-artifact: + allow: + skip-archive: true --- # Workflow Title @@ -81,7 +84,7 @@ Always run `gh aw compile` after modifying frontmatter. Markdown body changes ta ## Key Principles -- **No write permissions on main job**: Never use `issues: write`, `pull-requests: write`, or `contents: write`. Use `safe-outputs:` instead — it handles write operations in a separate secured job. +- **No write permissions on main job**: Never use `issues: write`, `pull-requests: write`, or `contents: write`. Use `safe-outputs:` instead — it handles write operations (including attachment-style `upload-artifact`) in a separate secured job. - **Use `gh-proxy` mode**: `tools.github.mode: gh-proxy` is faster than `local` (no MCP server startup). - **Prefer sanitized context**: Use `${{ steps.sanitized.outputs.text }}` for issue/PR content access — it neutralizes @mentions, bot triggers, and injection attacks. - **`strict: true` required**: All production workflows must set `strict: true`. diff --git a/.github/aw/safe-outputs.md b/.github/aw/safe-outputs.md index 5df2286efaa..1a9f46e21d6 100644 --- a/.github/aw/safe-outputs.md +++ b/.github/aw/safe-outputs.md @@ -536,7 +536,7 @@ Safe outputs are the primary mechanism for write operations in agentic workflows ``` Publishes files to an orphaned git branch for persistent storage and URL-addressable embedding. Default allowed extensions include common non-executable types. Maximum file size is 50MB (51200 KB). **Use this for images, charts, and screenshots that need embeddable URLs in issues/PRs/discussions.** -- `upload-artifact:` - Upload files as run-scoped GitHub Actions artifacts (recommended for temporary run artifacts) +- `upload-artifact:` - Upload files as run-scoped GitHub Actions artifacts (recommended for temporary run artifacts and attachment-style outputs) ```yaml safe-outputs: @@ -557,7 +557,7 @@ Safe outputs are the primary mechanism for write operations in agentic workflows skip-archive: true # Allow agent to upload files without zipping ``` - Uploads files as run-scoped GitHub Actions artifacts. Artifacts are temporary and tied to the workflow run, automatically cleaned up when they expire. Agents call `upload_artifact` with a `name`, `path`, and optional `retention_days`. **Use this for temporary downloadable artifacts**, while `upload-asset` is preferred for embedding images/charts in GitHub content. + Uploads files as run-scoped GitHub Actions artifacts. Artifacts are temporary and tied to the workflow run, automatically cleaned up when they expire. Agents call `upload_artifact` with a `name`, `path`, and optional `retention_days`. **Use this for temporary downloadable artifacts and attachment-style arbitrary data** (for example when a comment/issue should link to a generated file bundle). Set `allow.skip-archive: true` when downloads should be served as direct files without uncompressing. Use `upload-asset` instead when you need stable embeddable URLs (images/charts in GitHub content). - `dispatch-workflow:` - Trigger other workflows with inputs ```yaml @@ -1017,4 +1017,3 @@ The safe-outputs job emits named step outputs for the first successful result of | `create-pull-request` | `created_pr_number`, `created_pr_url` | | `add-comment` | `comment_id`, `comment_url` | | `push-to-pull-request-branch` | `push_commit_sha`, `push_commit_url` | - diff --git a/.github/aw/update-agentic-workflow.md b/.github/aw/update-agentic-workflow.md index df84642269f..caeb82ee9b3 100644 --- a/.github/aw/update-agentic-workflow.md +++ b/.github/aw/update-agentic-workflow.md @@ -76,7 +76,7 @@ Agentic workflows execute as **a single GitHub Actions job** with the AI agent r ✅ **What agentic workflows CAN do:** - Run AI agent once per trigger with full context - Read from GitHub API, external APIs, web pages -- Create GitHub resources (issues, PRs, comments) via safe outputs +- Create GitHub resources (issues, PRs, comments, attachment artifacts) via safe outputs - Execute bash commands, run tests, analyze code - Store state in cache-memory for next run - Use MCP servers and tools within the single job @@ -234,7 +234,7 @@ tools: ⚠️ **IMPORTANT**: - **Always use `toolsets:` for GitHub tools** - Use `toolsets: [default]` instead of manually listing individual tools - **Never recommend GitHub mutation tools** like `create_issue`, `add_issue_comment`, `update_issue`, etc. -- **Always use `safe-outputs` instead** for any GitHub write operations +- **Always use `safe-outputs` instead** for any GitHub write operations (including attachment-style artifact uploads) - **Do NOT recommend `mode: remote`** for GitHub tools - it requires additional configuration **Advanced static analysis tools**: @@ -369,6 +369,9 @@ safe-outputs: labels: [automated] add-comment: # NEW - just add this line and its config max: 1 + upload-artifact: # NEW - for attachment-style outputs + allow: + skip-archive: true ``` **After making this change**: Run `gh aw compile ` (recompilation required) From ecb443584559566d1d19401105456469cbf3a66d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 17:42:38 +0000 Subject: [PATCH 2/2] docs: use top-level skip-archive for upload-artifact Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/create-agentic-workflow.md | 2 +- .github/aw/github-agentic-workflows.md | 3 +-- .github/aw/safe-outputs.md | 5 ++--- .github/aw/update-agentic-workflow.md | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/aw/create-agentic-workflow.md b/.github/aw/create-agentic-workflow.md index 7b255d6b83d..33a641e6ea7 100644 --- a/.github/aw/create-agentic-workflow.md +++ b/.github/aw/create-agentic-workflow.md @@ -878,7 +878,7 @@ Based on the parsed requirements, determine: 4. **Safe Outputs**: For any write operations: - Creating issues → `safe-outputs: create-issue:` - Commenting → `safe-outputs: add-comment:` - - Posting attachment-style outputs or arbitrary downloadable files → `safe-outputs: upload-artifact:` (set `allow.skip-archive: true` when consumers should download files directly without uncompressing) + - Posting attachment-style outputs or arbitrary downloadable files → `safe-outputs: upload-artifact:` (set `skip-archive: true` when consumers should download files directly without uncompressing) - Creating PRs → `safe-outputs: create-pull-request:` — **always specify `allowed-files`** scoped to the file extensions or paths the workflow is meant to touch. This is the primary guardrail; omitting it allows the agent to modify any file in the repository. Example: ```yaml safe-outputs: diff --git a/.github/aw/github-agentic-workflows.md b/.github/aw/github-agentic-workflows.md index 11fb2d54c47..ce3228c8172 100644 --- a/.github/aw/github-agentic-workflows.md +++ b/.github/aw/github-agentic-workflows.md @@ -36,8 +36,7 @@ safe-outputs: labels: [automation] add-comment: upload-artifact: - allow: - skip-archive: true + skip-archive: true --- # Workflow Title diff --git a/.github/aw/safe-outputs.md b/.github/aw/safe-outputs.md index 1a9f46e21d6..f20f679231f 100644 --- a/.github/aw/safe-outputs.md +++ b/.github/aw/safe-outputs.md @@ -553,11 +553,10 @@ Safe outputs are the primary mechanism for write operations in agentic workflows exclude: ["*secret*"] defaults: # Optional: default values injected when agent omits a field if-no-files: "ignore" # "error" or "ignore" when no files match (default: "error") - allow: # Optional: opt-in behaviors - skip-archive: true # Allow agent to upload files without zipping + skip-archive: true # Optional: allow direct file uploads without zipping ``` - Uploads files as run-scoped GitHub Actions artifacts. Artifacts are temporary and tied to the workflow run, automatically cleaned up when they expire. Agents call `upload_artifact` with a `name`, `path`, and optional `retention_days`. **Use this for temporary downloadable artifacts and attachment-style arbitrary data** (for example when a comment/issue should link to a generated file bundle). Set `allow.skip-archive: true` when downloads should be served as direct files without uncompressing. Use `upload-asset` instead when you need stable embeddable URLs (images/charts in GitHub content). + Uploads files as run-scoped GitHub Actions artifacts. Artifacts are temporary and tied to the workflow run, automatically cleaned up when they expire. Agents call `upload_artifact` with a `name`, `path`, and optional `retention_days`. **Use this for temporary downloadable artifacts and attachment-style arbitrary data** (for example when a comment/issue should link to a generated file bundle). Set `skip-archive: true` when downloads should be served as direct files without uncompressing. Use `upload-asset` instead when you need stable embeddable URLs (images/charts in GitHub content). - `dispatch-workflow:` - Trigger other workflows with inputs ```yaml diff --git a/.github/aw/update-agentic-workflow.md b/.github/aw/update-agentic-workflow.md index caeb82ee9b3..48679e1a46c 100644 --- a/.github/aw/update-agentic-workflow.md +++ b/.github/aw/update-agentic-workflow.md @@ -370,8 +370,7 @@ safe-outputs: add-comment: # NEW - just add this line and its config max: 1 upload-artifact: # NEW - for attachment-style outputs - allow: - skip-archive: true + skip-archive: true ``` **After making this change**: Run `gh aw compile ` (recompilation required)