Safe Outputs
The safe-outputs: (validated GitHub operations) element of your workflow’s frontmatter declares that your agentic workflow should conclude with optional automated actions based on the agentic workflow’s output. This enables your workflow to write content that is then automatically processed to create GitHub issues, comments, pull requests, or add labels - all without giving the agentic portion of the workflow any write permissions.
Safe outputs enforce security through separation: agents run read-only and request actions via structured output, while separate permission-controlled jobs execute those requests. This provides least privilege, defense against prompt injection, auditability, and controlled limits per operation.
Example:
safe-outputs: create-issue:The agent requests issue creation; a separate job with issues: write creates it.
Available Safe Output Types
Section titled “Available Safe Output Types”Issues & Discussions
Section titled “Issues & Discussions”- Create Issue (
create-issue) - Create GitHub issues (max: 1) - Update Issue (
update-issue) - Update issue status, title, or body (max: 1) - Close Issue (
close-issue) - Close issues with comment (max: 1) - Link Sub-Issue (
link-sub-issue) - Link issues as sub-issues (max: 1) - Create Discussion (
create-discussion) - Create GitHub discussions (max: 1) - Update Discussion (
update-discussion) - Update discussion title, body, or labels (max: 1) - Close Discussion (
close-discussion) - Close discussions with comment and resolution (max: 1)
Pull Requests
Section titled “Pull Requests”- Create PR (
create-pull-request) - Create pull requests with code changes (default max: 1, configurable) - Update PR (
update-pull-request) - Update PR title or body (max: 1) - Close PR (
close-pull-request) - Close pull requests without merging (max: 10) - PR Review Comments (
create-pull-request-review-comment) - Create review comments on code lines (max: 10) - Reply to PR Review Comment (
reply-to-pull-request-review-comment) - Reply to existing review comments (max: 10) - Resolve PR Review Thread (
resolve-pull-request-review-thread) - Resolve review threads after addressing feedback (max: 10) - Push to PR Branch (
push-to-pull-request-branch) - Push changes to PR branch (default max: 1, configurable, same-repo only)
Labels, Assignments & Reviews
Section titled “Labels, Assignments & Reviews”- Add Comment (
add-comment) - Post comments on issues, PRs, or discussions (max: 1) - Hide Comment (
hide-comment) - Hide comments on issues, PRs, or discussions (max: 5) - Add Labels (
add-labels) - Add labels to issues or PRs (max: 3) - Remove Labels (
remove-labels) - Remove labels from issues or PRs (max: 3) - Add Reviewer (
add-reviewer) - Add reviewers to pull requests (max: 3) - Assign Milestone (
assign-milestone) - Assign issues to milestones (max: 1) - Assign to Agent (
assign-to-agent) - Assign Copilot coding agent to issues or PRs (max: 1) - Assign to User (
assign-to-user) - Assign users to issues (max: 1) - Unassign from User (
unassign-from-user) - Remove user assignments from issues or PRs (max: 1)
Projects, Releases & Assets
Section titled “Projects, Releases & Assets”- Create Project (
create-project) - Create new GitHub Projects boards (max: 1, cross-repo) - Update Project (
update-project) - Manage GitHub Projects boards (max: 10, same-repo only) - Create Project Status Update (
create-project-status-update) - Create project status updates - Update Release (
update-release) - Update GitHub release descriptions (max: 1) - Upload Assets (
upload-asset) - Upload files to orphaned git branch (max: 10, same-repo only)
Security & Agent Tasks
Section titled “Security & Agent Tasks”- Dispatch Workflow (
dispatch-workflow) - Trigger other workflows with inputs (max: 3, same-repo only) - Code Scanning Alerts (
create-code-scanning-alert) - Generate SARIF security advisories (max: unlimited, same-repo only) - Autofix Code Scanning Alerts (
autofix-code-scanning-alert) - Create automated fixes for code scanning alerts (max: 10, same-repo only) - Create Agent Session (
create-agent-session) - Create Copilot coding agent sessions (max: 1)
System Types (Auto-Enabled)
Section titled “System Types (Auto-Enabled)”- No-Op (
noop) - Log completion message for transparency (max: 1, same-repo only) - Missing Tool (
missing-tool) - Report missing tools (max: unlimited, same-repo only) - Missing Data (
missing-data) - Report missing data required to achieve goals (max: unlimited, same-repo only)
Custom Safe Output Jobs (jobs:)
Section titled “Custom Safe Output Jobs (jobs:)”Create custom post-processing jobs registered as Model Context Protocol (MCP) tools. Support standard GitHub Actions properties and auto-access agent output via $GH_AW_AGENT_OUTPUT. See Custom Safe Output Jobs.
Issue Creation (create-issue:)
Section titled “Issue Creation (create-issue:)”Creates GitHub issues based on workflow output.
safe-outputs: create-issue: title-prefix: "[ai] " # prefix for titles labels: [automation, agentic] # labels to attach assignees: [user1, copilot] # assignees (use 'copilot' for bot) max: 5 # max issues (default: 1) expires: 7 # auto-close after 7 days (or false to disable) group: true # group as sub-issues under parent close-older-issues: true # close previous issues from same workflow target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsAuto-Expiration
Section titled “Auto-Expiration”The expires field auto-closes issues after a time period. Supports day-string format (7d, 2w, 1m, 1y, 2h) or false to disable expiration. Integer values (e.g., expires: 7) are also accepted as shorthand for days and can be migrated to string format with gh aw fix --write. Generates agentics-maintenance.yml workflow that runs at the minimum required frequency based on the shortest expiration time across all workflows:
- 1 day or less → every 2 hours
- 2 days → every 6 hours
- 3-4 days → every 12 hours
- 5+ days → daily
Hours less than 24 are treated as 1 day minimum for expiration calculation.
To explicitly disable expiration (useful when create-issue has a default expiration), use expires: false:
Issue Grouping
Section titled “Issue Grouping”The group field (default: false) automatically organizes multiple issues as sub-issues under a parent issue. When enabled:
- Parent issues are automatically created and managed using the workflow ID as the group identifier
- Child issues are linked to the parent using GitHub’s sub-issue relationships
- Maximum of 64 sub-issues per parent issue
- Parent issues include metadata tracking all sub-issues
This is useful for workflows that create multiple related issues, such as planning workflows that break down epics into tasks, or batch processing workflows that create issues for individual items.
Example:
safe-outputs: create-issue: title-prefix: "[plan] " labels: [plan, ai-generated] max: 5 group: trueIn this example, if the workflow creates 5 issues, all will be automatically grouped under a parent issue, making it easy to track related work items together.
Temporary IDs for Issue References
Section titled “Temporary IDs for Issue References”Use temporary IDs (aw_ + 3-8 alphanumeric chars) to reference parent issues before creation. References like #aw_abc123 in bodies are replaced with actual numbers. The parent field creates sub-issue relationships.
Auto-Close Older Issues
Section titled “Auto-Close Older Issues”The close-older-issues field (default: false) automatically closes previous open issues from the same workflow when a new issue is created. This is useful for workflows that generate recurring reports or status updates, ensuring only the latest issue remains open.
safe-outputs: create-issue: title-prefix: "[weekly-report] " labels: [report, automation] close-older-issues: trueWhen enabled:
- Searches for open issues containing the same workflow-id marker in their body
- Closes found issues as “not planned” with a comment linking to the new issue
- Maximum 10 older issues will be closed
- Only runs if the new issue creation succeeds
Searching for Workflow-Created Items
Section titled “Searching for Workflow-Created Items”All items created by workflows (issues, pull requests, discussions, and comments) include a hidden workflow-id marker in their body:
<!-- gh-aw-workflow-id: WORKFLOW_NAME -->You can use this marker to find all items created by a specific workflow on GitHub.com.
Search Examples:
Find all open issues created by the daily-team-status workflow:
repo:owner/repo is:issue is:open "gh-aw-workflow-id: daily-team-status" in:bodyFind all pull requests created by the security-audit workflow:
repo:owner/repo is:pr "gh-aw-workflow-id: security-audit" in:bodyFind all items (issues, PRs, discussions) from any workflow in your organization:
org:your-org "gh-aw-workflow-id:" in:bodyFind comments from a specific workflow:
repo:owner/repo "gh-aw-workflow-id: bot-responder" in:commentsClose Issue (close-issue:)
Section titled “Close Issue (close-issue:)”Closes GitHub issues with an optional comment and state reason. Filters by labels and title prefix control which issues can be closed.
safe-outputs: close-issue: target: "triggering" # "triggering" (default), "*", or number required-labels: [automated] # only close with any of these labels required-title-prefix: "[bot]" # only close matching prefix max: 20 # max closures (default: 1) target-repo: "owner/repo" # cross-repositoryTarget: "triggering" (requires issue event), "*" (any issue), or number (specific issue).
State Reasons: completed, not_planned, reopened (default: completed).
Comment Creation (add-comment:)
Section titled “Comment Creation (add-comment:)”Posts comments on issues, PRs, or discussions. Defaults to triggering item; use target: "*" for any, or number for specific items. When combined with create-issue, create-discussion, or create-pull-request, includes “Related Items” section.
safe-outputs: add-comment: max: 3 # max comments (default: 1) target: "*" # "triggering" (default), "*", or number discussion: true # target discussions target-repo: "owner/repo" # cross-repository hide-older-comments: true # hide previous comments from same workflow allowed-reasons: [outdated] # restrict hiding reasons (optional)The author of the parent issue, PR, or discussion receiving the comment is automatically preserved as an allowed mention. This means @username references to the issue/PR/discussion author are not neutralized when the workflow posts a reply.
Hide Older Comments
Section titled “Hide Older Comments”Set hide-older-comments: true to minimize previous comments from the same workflow (identified by GITHUB_WORKFLOW) before posting new ones. Useful for status updates. Allowed reasons: spam, abuse, off_topic, outdated (default), resolved.
Append-Only Status Comments
Section titled “Append-Only Status Comments”By default, gh-aw posts an activation comment when a workflow starts, then updates that same comment with the final status.
If you prefer an append-only timeline (never editing existing comments), set:
safe-outputs: messages: append-only-comments: trueWhen enabled, the workflow completion notifier creates a new comment instead of editing the activation comment.
Hide Comment (hide-comment:)
Section titled “Hide Comment (hide-comment:)”Collapses comments in GitHub UI with reason. Requires GraphQL node IDs (e.g., IC_kwDOABCD123456), not REST numeric IDs. Reasons: spam, abuse, off_topic, outdated, resolved.
safe-outputs: hide-comment: max: 5 # max comments (default: 5) target-repo: "owner/repo" # cross-repositoryAdd Labels (add-labels:)
Section titled “Add Labels (add-labels:)”Adds labels to issues or PRs. Specify allowed to restrict to specific labels, or blocked to deny specific label patterns regardless of the allow list.
safe-outputs: add-labels: allowed: [bug, enhancement] # restrict to specific labels blocked: ["~*", "*[bot]"] # deny labels matching these glob patterns max: 3 # max labels (default: 3) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repositoryBlocked Label Patterns
Section titled “Blocked Label Patterns”The blocked field accepts glob patterns that are evaluated before the allowed list. Any label matching a blocked pattern is rejected, even if it also appears in the allowed list. This provides infrastructure-level protection against prompt injection attacks in repositories with many labels where maintaining an exhaustive allowlist is impractical.
Common patterns:
| Pattern | Effect |
|---|---|
~* | Denies all labels starting with ~ (often used as workflow triggers) |
*[bot] | Denies all labels ending with [bot] (administrative bot labels) |
stale | Denies the exact stale label |
safe-outputs: add-labels: blocked: ["~*", "*[bot]"] # Blocked patterns evaluated first allowed: [bug, enhancement] # Allowed list applied after blocked check max: 5Remove Labels (remove-labels:)
Section titled “Remove Labels (remove-labels:)”Removes labels from issues or PRs. Specify allowed to restrict which labels can be removed, or blocked to prevent removal of specific label patterns. If a label is not present on the item, it will be silently skipped.
safe-outputs: remove-labels: allowed: [automated, stale] # restrict to specific labels (optional) blocked: ["~*"] # deny removal of labels matching these glob patterns max: 3 # max operations (default: 3) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repositoryTarget: "triggering" (requires issue/PR event), "*" (any issue/PR), or number (specific issue/PR).
When allowed is omitted or set to null, any labels can be removed. Use allowed to restrict removal to specific labels only, providing control over which labels agents can manipulate. The blocked field takes precedence over allowed.
Example use case: Label lifecycle management where agents add temporary labels during triage and remove them once processed.
safe-outputs: add-labels: allowed: [needs-triage, automation] remove-labels: allowed: [needs-triage] # agents can remove triage label after processingAdd Reviewer (add-reviewer:)
Section titled “Add Reviewer (add-reviewer:)”Adds reviewers to pull requests. Specify reviewers to restrict to specific GitHub usernames.
safe-outputs: add-reviewer: reviewers: [user1, copilot] # restrict to specific reviewers max: 3 # max reviewers (default: 3) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsTarget: "triggering" (requires PR event), "*" (any PR), or number (specific PR).
Use reviewers: [copilot] to assign the Copilot PR reviewer bot. This uses the same token resolution as Copilot agent assignment: github-token:, GH_AW_AGENT_TOKEN (or GH_AW_GITHUB_TOKEN, falling back to GITHUB_TOKEN).
Assign Milestone (assign-milestone:)
Section titled “Assign Milestone (assign-milestone:)”Assigns issues to milestones. Specify allowed to restrict to specific milestone titles.
safe-outputs: assign-milestone: allowed: [v1.0, v2.0] # restrict to specific milestone titles max: 1 # max assignments (default: 1) target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsIssue Updates (update-issue:)
Section titled “Issue Updates (update-issue:)”Updates issue status, title, or body. Only explicitly enabled fields can be updated. Status must be “open” or “closed”. The operation field controls how body updates are applied: append (default), prepend, replace, or replace-island. Use title-prefix to restrict updates to issues whose titles start with a specific prefix.
safe-outputs: update-issue: status: # enable status updates title: # enable title updates body: # enable body updates title-prefix: "[bot] " # only update issues with this title prefix max: 3 # max updates (default: 1) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsTarget: "triggering" (requires issue event), "*" (any issue), or number (specific issue).
When using target: "*", the agent must provide issue_number or item_number in the output to identify which issue to update.
Title Prefix: When title-prefix is set, the update is rejected if the target issue’s current title does not start with the specified prefix. This ensures agents can only modify issues that have been explicitly tagged for automated updates.
Operation Types (for body updates):
append(default): Adds content to the end with separator and attributionprepend: Adds content to the start with separator and attributionreplace: Completely replaces existing body with new content and attributionreplace-island: Updates a specific section marked with HTML comments
Agent output format: {"type": "update_issue", "issue_number": 123, "operation": "append", "body": "..."}. The operation field is optional (defaults to append).
Pull Request Updates (update-pull-request:)
Section titled “Pull Request Updates (update-pull-request:)”Updates PR title or body. Both fields are enabled by default. The operation field controls how body updates are applied: append (default), prepend, or replace.
safe-outputs: update-pull-request: title: true # enable title updates (default: true) body: true # enable body updates (default: true) footer: false # omit AI-generated footer from body updates (default: true) max: 1 # max updates (default: 1) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsTarget: "triggering" (requires PR event), "*" (any PR), or number (specific PR).
When using target: "*", the agent must provide pull_request_number in the output to identify which pull request to update.
Operation Types:
append(default): Adds content to the end with separator and attributionprepend: Adds content to the start with separator and attributionreplace: Completely replaces existing body with new content and attribution
Title updates always replace the existing title. Disable fields by setting to false.
Link Sub-Issue (link-sub-issue:)
Section titled “Link Sub-Issue (link-sub-issue:)”Links issues as sub-issues using GitHub’s parent-child issue relationships. Supports filtering by labels and title prefixes for both parent and sub issues.
safe-outputs: link-sub-issue: parent-required-labels: [epic] # parent must have these labels parent-title-prefix: "[Epic]" # parent must match prefix sub-required-labels: [task] # sub must have these labels sub-title-prefix: "[Task]" # sub must match prefix max: 1 # max links (default: 1) target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsAgent output includes parent_issue_number and sub_issue_number. Validation ensures both issues exist and meet label/prefix requirements before linking.
Project Creation (create-project:)
Section titled “Project Creation (create-project:)”Creates new GitHub Projects V2 boards. Requires PAT or GitHub App token (GH_AW_PROJECT_GITHUB_TOKEN)-default GITHUB_TOKEN lacks Projects v2 access. Supports optional view configuration to create custom project views at creation time.
safe-outputs: create-project: max: 1 # max operations (default: 1) github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} target-owner: "myorg" # default target owner (optional) title-prefix: "Project" # default title prefix (optional) views: # optional: auto-create views - name: "Sprint Board" layout: board filter: "is:issue is:open" - name: "Task Tracker" layout: tableWhen views are configured, they are created automatically after project creation. GitHub’s default “View 1” will remain, and configured views are created as additional views.
The target-owner field is an optional default. When configured, the agent can omit the owner field in tool calls, and the default will be used. The agent can still override by providing an explicit owner value.
Without default (agent must provide owner):
create_project({ title: "Project: Security Q1 2025", owner: "myorg", owner_type: "org", // "org" or "user" (default: "org") item_url: "https://github.com/myorg/repo/issues/123" // Optional issue to add});With default configured (agent only needs title):
create_project({ title: "Project: Security Q1 2025" // owner uses configured default // owner_type defaults to "org" // Can still override: owner: "...", owner_type: "user"});Optionally include item_url (GitHub issue URL) to add the issue as the first project item. Exposes outputs: project-id, project-number, project-title, project-url, item-id (if item added).
Project Board Updates (update-project:)
Section titled “Project Board Updates (update-project:)”Manages GitHub Projects boards. Requires PAT or GitHub App token (GH_AW_PROJECT_GITHUB_TOKEN)-default GITHUB_TOKEN lacks Projects v2 access. Update-only by default; set create_if_missing: true to create boards (requires appropriate token permissions).
safe-outputs: update-project: project: "https://github.com/orgs/myorg/projects/42" # required: target project URL max: 20 # max operations (default: 10) github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} views: # optional: auto-create views - name: "Sprint Board" layout: board filter: "is:issue is:open" - name: "Task Tracker" layout: table - name: "Roadmap" layout: roadmapConfiguration options:
project(required in configuration): Default project URL shown in examples. Note: Agent output messages must explicitly include theprojectfield - the configured value is for documentation purposes only.max: Maximum number of operations per run (default: 10).github-token: Custom token with Projects permissions (required for Projects v2 access).views: Optional array of project views to create automatically.- Exposes outputs:
project-id,project-number,project-url,item-id.
Supported Field Types
Section titled “Supported Field Types”GitHub Projects V2 supports various custom field types. The following field types are automatically detected and handled:
TEXT- Text fields (default)DATE- Date fields (format:YYYY-MM-DD)NUMBER- Numeric fields (story points, estimates, etc.)ITERATION- Sprint/iteration fields (matched by iteration title)SINGLE_SELECT- Dropdown/select fields (creates missing options automatically)
Example field usage:
fields: status: "In Progress" # SINGLE_SELECT field start_date: "2026-01-04" # DATE field story_points: 8 # NUMBER field sprint: "Sprint 42" # ITERATION field (by title) priority: "High" # SINGLE_SELECT fieldCreating Project Views
Section titled “Creating Project Views”Project views can be created automatically by declaring them in the views array. Views are created when the workflow runs, after processing update_project items from the agent.
View configuration:
safe-outputs: update-project: github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} views: - name: "Sprint Board" # required: view name layout: board # required: table, board, or roadmap filter: "is:issue is:open" # optional: filter query - name: "Task Tracker" layout: table filter: "is:issue is:pr" - name: "Roadmap" layout: roadmapView properties:
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | View name (e.g., “Sprint Board”, “Task Tracker”) |
layout | string | Yes | View layout: table, board, or roadmap |
filter | string | No | Filter query (e.g., is:issue is:open, label:bug) |
visible-fields | array | No | Field IDs to display (table/board only, not roadmap) |
Layout types:
table- List view with customizable columns for detailed trackingboard- Kanban-style cards grouped by status or custom fieldroadmap- Timeline visualization with date-based swimlanes
Filter syntax examples:
is:issue is:open- Open issues onlyis:pr- Pull requests onlyis:issue is:pr- Both issues and PRslabel:bug- Items with bug labelassignee:@me- Items assigned to viewer
Views are created automatically during workflow execution. The workflow must include at least one update_project operation to provide the target project URL.
Project Status Updates (create-project-status-update:)
Section titled “Project Status Updates (create-project-status-update:)”Creates status updates on GitHub Projects boards to communicate progress, findings, and trends. Status updates appear in the project’s Updates tab and provide a historical record of execution. Requires PAT or GitHub App token (GH_AW_PROJECT_GITHUB_TOKEN)-default GITHUB_TOKEN lacks Projects v2 access.
safe-outputs: create-project-status-update: project: "https://github.com/orgs/myorg/projects/73" # required: target project URL max: 1 # max updates per run (default: 1) github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}Configuration options:
project(required in configuration): Default project URL shown in examples. Note: Agent output messages must explicitly include theprojectfield - the configured value is for documentation purposes only.max: Maximum number of status updates per run (default: 1).github-token: Custom token with Projects permissions (required for Projects v2 access).- Often used by scheduled workflows and orchestrator workflows to post run summaries.
Required Fields
Section titled “Required Fields”| Field | Type | Description |
|---|---|---|
project | URL | Full GitHub project URL (e.g., https://github.com/orgs/myorg/projects/73). Required in every agent output message. |
body | Markdown | Status update content with summary, findings, and next steps |
Optional Fields
Section titled “Optional Fields”| Field | Type | Default | Description |
|---|---|---|---|
status | Enum | ON_TRACK | Status indicator: ON_TRACK, AT_RISK, OFF_TRACK, COMPLETE, INACTIVE |
start_date | Date | Today | Run start date (format: YYYY-MM-DD) |
target_date | Date | Today | Projected completion or milestone date (format: YYYY-MM-DD) |
Example Usage
Section titled “Example Usage”create-project-status-update: project: "https://github.com/orgs/myorg/projects/73" status: "ON_TRACK" start_date: "2026-01-06" target_date: "2026-01-31" body: | ## Run Summary
**Discovered:** 25 items (15 issues, 10 PRs) **Processed:** 10 items added to project, 5 updated **Completion:** 60% (30/50 total tasks)
### Key Findings - Documentation coverage improved to 88% - 3 critical accessibility issues identified - Worker velocity: 1.2 items/day
### Trends - Velocity stable at 8-10 items/week - Blocked items decreased from 5 to 2 - On track for end-of-month completion
### Next Steps - Continue processing remaining 15 items - Address 2 blocked items in next run - Target 95% documentation coverage by end of monthStatus Indicators
Section titled “Status Indicators”ON_TRACK: Progressing as planned, meeting expected targetsAT_RISK: Potential issues identified (blocked items, slower velocity, dependencies)OFF_TRACK: Behind schedule, requires intervention or re-planningCOMPLETE: Objectives met, no further work neededINACTIVE: Paused or not actively running
Exposes outputs: status-update-id, project-id, status.
Pull Request Creation (create-pull-request:)
Section titled “Pull Request Creation (create-pull-request:)”Creates PRs with code changes. By default, falls back to creating an issue if PR creation fails (e.g., org settings block it). Set fallback-as-issue: false to disable this fallback and avoid requiring issues: write permission. expires field (same-repo only) auto-closes after period: integers (days) or 2h, 7d, 2w, 1m, 1y (hours < 24 treated as 1 day).
Multiple PRs per run are supported by setting max higher than 1. Each PR is created from its own branch with an independent patch, so concurrent calls do not conflict.
safe-outputs: create-pull-request: title-prefix: "[ai] " # prefix for titles labels: [automation] # labels to attach reviewers: [user1, copilot] # reviewers (use 'copilot' for bot) draft: true # create as draft (default: true) max: 3 # max PRs per run (default: 1) expires: 14 # auto-close after 14 days (same-repo only) if-no-changes: "warn" # "warn" (default), "error", or "ignore" target-repo: "owner/repo" # cross-repository base-branch: "vnext" # target branch for PR (default: github.base_ref || github.ref_name) fallback-as-issue: false # disable issue fallback (default: true) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions github-token-for-extra-empty-commit: ${{ secrets.CI_TOKEN }} # optional token to push empty commit triggering CIThe base-branch field specifies which branch the pull request should target. This is particularly useful for cross-repository PRs where you need to target non-default branches (e.g., vnext, release/v1.0, staging). When not specified, defaults to github.base_ref (the PR’s target branch) with a fallback to github.ref_name (the workflow’s branch) for push events.
Example use case: A workflow in org/engineering that creates PRs in org/docs targeting the vnext branch for feature documentation:
safe-outputs: create-pull-request: target-repo: "org/docs" base-branch: "vnext" draft: true github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsPR creation may fail if “Allow GitHub Actions to create and approve pull requests” is disabled in Organization Settings. By default (fallback-as-issue: true), fallback creates an issue with branch link and requires issues: write permission. Set fallback-as-issue: false to disable fallback and only require contents: write + pull-requests: write.
When create-pull-request is configured, git commands (checkout, branch, switch, add, rm, commit, merge) are automatically enabled.
By default, PRs created with GitHub Agentic Workflows do not trigger CI. See Triggering CI for how to configure CI triggers.
Close Pull Request (close-pull-request:)
Section titled “Close Pull Request (close-pull-request:)”Closes PRs without merging with optional comment. Filter by labels and title prefix. Target: "triggering" (PR event), "*" (any), or number.
safe-outputs: close-pull-request: target: "triggering" # "triggering" (default), "*", or number required-labels: [automated, stale] # only close with these labels required-title-prefix: "[bot]" # only close matching prefix max: 10 # max closures (default: 1) target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsPR Review Comments (create-pull-request-review-comment:)
Section titled “PR Review Comments (create-pull-request-review-comment:)”Creates review comments on specific code lines in PRs. Supports single-line and multi-line comments. Comments are buffered and submitted as a single PR review (see submit-pull-request-review below).
safe-outputs: create-pull-request-review-comment: max: 3 # max comments (default: 10) side: "RIGHT" # "LEFT" or "RIGHT" (default: "RIGHT") target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository footer: "if-body" # footer control: "always", "none", or "if-body" github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsReply to PR Review Comment (reply-to-pull-request-review-comment:)
Section titled “Reply to PR Review Comment (reply-to-pull-request-review-comment:)”Replies to existing review comments on pull requests. Use this to respond to reviewer feedback, answer questions, or acknowledge comments. The comment_id must be the numeric ID of an existing review comment.
safe-outputs: reply-to-pull-request-review-comment: max: 10 # max replies (default: 10) target: "triggering" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository allowed-repos: ["org/other-repo"] # additional allowed repositories footer: true # add AI-generated footer (default: true) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsThe footer field controls whether AI-generated footers are added to PR review comments:
"always"(default) - Always include footer on review comments"none"- Never include footer on review comments"if-body"- Only include footer when the review has a body text
With footer: "if-body", approval reviews without body text appear clean without the AI-generated footer, while reviews with explanatory text still include the footer for attribution.
Submit PR Review (submit-pull-request-review:)
Section titled “Submit PR Review (submit-pull-request-review:)”Submits a consolidated pull request review with a status decision. All create-pull-request-review-comment outputs are automatically collected and included as inline comments in the review.
If the agent calls submit_pull_request_review, it can specify a review body and event (APPROVE, REQUEST_CHANGES, or COMMENT). Both fields are optional — event defaults to COMMENT when omitted, and body is only required for REQUEST_CHANGES. The agent can also submit a body-only review (e.g., APPROVE) without any inline comments.
If the agent does not call submit_pull_request_review at all, buffered comments are still submitted as a COMMENT review automatically.
When the workflow is not triggered by a pull request (e.g. workflow_dispatch), set target to the PR number (e.g. ${{ github.event.inputs.pr_number }}) so the review can be submitted. Same semantics as add-comment target: "triggering" (default), "*" (use pull_request_number from the message), or an explicit number.
safe-outputs: create-pull-request-review-comment: max: 10 submit-pull-request-review: max: 1 # max reviews to submit (default: 1) target: "triggering" # or "*", or e.g. ${{ github.event.inputs.pr_number }} when not in pull_request trigger footer: false # omit AI-generated footer from review body (default: true)Resolve PR Review Thread (resolve-pull-request-review-thread:)
Section titled “Resolve PR Review Thread (resolve-pull-request-review-thread:)”Resolves review threads on pull requests. Allows AI agents to mark review conversations as resolved after addressing the feedback. Uses the GitHub GraphQL API with the resolveReviewThread mutation.
Resolution is scoped to the triggering PR only — the handler validates that each thread belongs to the triggering pull request before resolving it.
safe-outputs: resolve-pull-request-review-thread: max: 10 # max threads to resolve (default: 10)Agent output format:
{"type": "resolve_pull_request_review_thread", "thread_id": "PRRT_kwDOABCD..."}Code Scanning Alerts (create-code-scanning-alert:)
Section titled “Code Scanning Alerts (create-code-scanning-alert:)”Creates security advisories in SARIF format and submits to GitHub Code Scanning. Supports severity: error, warning, info, note.
safe-outputs: create-code-scanning-alert: max: 50 # max findings (default: unlimited) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsAutofix Code Scanning Alerts (autofix-code-scanning-alert:)
Section titled “Autofix Code Scanning Alerts (autofix-code-scanning-alert:)”Creates automated fixes for code scanning alerts. Agent outputs fix suggestions that are submitted to GitHub Code Scanning.
safe-outputs: autofix-code-scanning-alert: max: 10 # max autofixes (default: 10) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsPush to PR Branch (push-to-pull-request-branch:)
Section titled “Push to PR Branch (push-to-pull-request-branch:)”Pushes changes to a PR’s branch. Validates via title-prefix and labels to ensure only approved PRs receive changes. Multiple pushes per run are supported by setting max higher than 1.
safe-outputs: push-to-pull-request-branch: target: "*" # "triggering" (default), "*", or number title-prefix: "[bot] " # require title prefix labels: [automated] # require all labels max: 3 # max pushes per run (default: 1) if-no-changes: "warn" # "warn" (default), "error", or "ignore" github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions github-token-for-extra-empty-commit: ${{ secrets.CI_TOKEN }} # optional token to push empty commit triggering CIWhen push-to-pull-request-branch is configured, git commands (checkout, branch, switch, add, rm, commit, merge) are automatically enabled.
Like create-pull-request, pushes with GitHub Agentic Workflows do not trigger CI. See Triggering CI for how to enable automatic CI triggers.
Fail-Fast on Code Push Failure
Section titled “Fail-Fast on Code Push Failure”If push-to-pull-request-branch (or create-pull-request) fails, the safe-output pipeline cancels all remaining non-code-push outputs. Each cancelled output is marked with an explicit reason such as “Cancelled: code push operation failed”. The failure details appear in the agent failure issue or comment generated by the conclusion job.
Release Updates (update-release:)
Section titled “Release Updates (update-release:)”Updates GitHub release descriptions: replace (complete replacement), append (add to end), or prepend (add to start).
safe-outputs: update-release: max: 1 # max releases (default: 1, max: 10) target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.CUSTOM_TOKEN }} # custom tokenAgent output format: {"type": "update_release", "tag": "v1.0.0", "operation": "replace", "body": "..."}. The tag field is optional for release events (inferred from context). Workflow needs read access; only the generated job receives write permissions.
Asset Uploads (upload-asset:)
Section titled “Asset Uploads (upload-asset:)”Uploads files (screenshots, charts, reports) to orphaned git branch with predictable URLs: https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{filename}. Agent registers files via upload_asset tool; separate job with contents: write commits them.
safe-outputs: upload-asset: branch: "assets/my-workflow" # default: "assets/${{ github.workflow }}" max-size: 5120 # KB (default: 10240 = 10MB) allowed-exts: [.png, .jpg, .svg] # default: [.png, .jpg, .jpeg] max: 20 # default: 10 github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsBranch Requirements: New branches require assets/ prefix for security. Existing branches allow any name. Create custom branches manually:
git checkout --orphan my-custom-branch && git rm -rf . && git commit --allow-empty -m "Initialize" && git push origin my-custom-branchSecurity: File path validation (workspace//tmp only), extension allowlist, size limits, SHA-256 verification, orphaned branch isolation, minimal permissions.
Outputs: published_count, branch_name. Limits: Same-repo only, max 50MB/file, 100 assets/run.
No-Op Logging (noop:)
Section titled “No-Op Logging (noop:)”Enabled by default. Allows agents to produce completion messages when no actions are needed, preventing silent workflow completion.
safe-outputs: create-issue: # noop enabled automatically noop: false # explicitly disableAgent output: {"type": "noop", "message": "Analysis complete - no issues found"}. Messages appear in the workflow conclusion comment or step summary.
Missing Tool Reporting (missing-tool:)
Section titled “Missing Tool Reporting (missing-tool:)”Enabled by default. Automatically detects and reports tools lacking permissions or unavailable functionality.
safe-outputs: create-issue: # missing-tool enabled automatically missing-tool: false # explicitly disableMissing Data Reporting (missing-data:)
Section titled “Missing Data Reporting (missing-data:)”Enabled by default. Allows AI agents to report missing data required to achieve their goals, encouraging truthfulness over hallucination.
safe-outputs: missing-data: create-issue: true # create GitHub issues for missing data title-prefix: "[data]" # prefix for issue titles (default: "[missing data]") labels: [data, blocked] # labels to attach to issues max: 10 # max reports per run (default: unlimited) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsWhen create-issue: true, the agent creates or updates GitHub issues documenting missing data with:
- Detailed explanation of what data is needed and why
- Context about how the data would be used
- Possible alternatives if the data cannot be provided
- Encouragement message praising the agent’s truthfulness
This rewards honest AI behavior and helps teams improve data accessibility for future agent runs.
Discussion Creation (create-discussion:)
Section titled “Discussion Creation (create-discussion:)”Creates discussions with optional category (slug, name, or ID; defaults to first available). expires field auto-closes after period (integers, 2h, 7d, 2w, 1m, 1y, or false to disable; hours < 24 treated as 1 day) as “OUTDATED” with comment. Generates maintenance workflow with dynamic frequency based on shortest expiration time (see Auto-Expiration section above).
Category Naming Standard: Use lowercase, plural category names (e.g., audits, general, reports) for consistency and better searchability. GitHub Discussion category IDs (starting with DIC_) are also supported.
safe-outputs: create-discussion: title-prefix: "[ai] " # prefix for titles category: "announcements" # category slug, name, or ID (use lowercase, prefer announcement-capable) expires: 3 # auto-close after 3 days (or false to disable) max: 3 # max discussions (default: 1) target-repo: "owner/repo" # cross-repository fallback-to-issue: true # fallback to issue creation on permission errors (default: true) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsFallback to Issue Creation
Section titled “Fallback to Issue Creation”The fallback-to-issue field (default: true) automatically falls back to creating an issue when discussion creation fails due to permissions errors. This is useful in repositories where discussions are not enabled or where the workflow lacks the necessary permissions to create discussions.
When fallback is triggered:
- An issue is created instead of a discussion
- A note is added to the issue body indicating it was intended to be a discussion
- The issue includes all the same content as the intended discussion
To disable fallback behavior and fail if discussions cannot be created:
safe-outputs: create-discussion: fallback-to-issue: falseCommon scenarios where fallback is useful:
- Repositories with discussions disabled
- Insufficient permissions (requires
discussions: write) - Organization policies restricting discussions
- Testing workflows across different repository configurations
Close Discussion (close-discussion:)
Section titled “Close Discussion (close-discussion:)”Closes GitHub discussions with optional comment and resolution reason. Filters by category, labels, and title prefix control which discussions can be closed.
safe-outputs: close-discussion: target: "triggering" # "triggering" (default), "*", or number required-category: "Ideas" # only close in category required-labels: [resolved] # only close with labels required-title-prefix: "[ai]" # only close matching prefix max: 1 # max closures (default: 1) target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsTarget: "triggering" (requires discussion event), "*" (any discussion), or number (specific discussion).
Resolution Reasons: RESOLVED, DUPLICATE, OUTDATED, ANSWERED.
Discussion Updates (update-discussion:)
Section titled “Discussion Updates (update-discussion:)”Updates discussion title, body, or labels. Only explicitly enabled fields can be updated.
safe-outputs: update-discussion: title: # enable title updates body: # enable body updates labels: # enable label updates allowed-labels: [bug, idea] # restrict to specific labels max: 1 # max updates (default: 1) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsField Enablement: Include title:, body:, or labels: keys to enable updates for those fields. Without these keys, the field cannot be updated. Setting allowed-labels implicitly enables label updates.
Target: "triggering" (requires discussion event), "*" (any discussion), or number (specific discussion).
When using target: "*", the agent must provide discussion_number in the output to identify which discussion to update.
Workflow Dispatch (dispatch-workflow:)
Section titled “Workflow Dispatch (dispatch-workflow:)”Triggers other workflows in the same repository using GitHub’s workflow_dispatch event. This enables orchestration patterns, such as orchestrator workflows that coordinate multiple worker workflows.
Shorthand Syntax:
safe-outputs: dispatch-workflow: [worker-workflow, scanner-workflow]Configuration
Section titled “Configuration”workflows(required) - List of workflow names (without.mdextension) that the agent is allowed to dispatch. Each workflow must exist in the same repository and support theworkflow_dispatchtrigger.max(optional) - Maximum number of workflow dispatches allowed (default: 1, maximum: 50). This prevents excessive workflow triggering.
Validation Rules
Section titled “Validation Rules”At compile time, the compiler validates:
-
Workflow existence - Each workflow in the
workflowslist must exist as either:- A markdown workflow file (
.md) - A compiled lock file (
.lock.yml) - A standard GitHub Actions workflow (
.yml)
- A markdown workflow file (
-
workflow_dispatch trigger - Each workflow must include
workflow_dispatchin itson:trigger section:on: [push, workflow_dispatch] # oron:push:workflow_dispatch:inputs:tracker_id:description: "Tracker identifier"required: true -
No self-reference - A workflow cannot dispatch itself to prevent infinite loops.
-
File resolution - The compiler resolves the correct file extension (
.lock.ymlor.yml) at compile time and embeds it in the safe output configuration, ensuring the runtime handler dispatches the correct workflow file.
Defining Workflow Inputs
Section titled “Defining Workflow Inputs”To enable the agent to provide inputs when dispatching workflows, define workflow_dispatch inputs in the target workflow:
Target Workflow Example (deploy-app.md):
---on: workflow_dispatch: inputs: environment: description: "Target deployment environment" required: true type: choice options: [staging, production] version: description: "Version to deploy" required: true type: string dry_run: description: "Perform dry run without actual deployment" required: false type: boolean default: false---
# Deploy Application Workflow
Deploys the application to the specified environment...Rate Limiting
Section titled “Rate Limiting”To respect GitHub API rate limits, the handler automatically enforces a 5-second delay between consecutive workflow dispatches. The first dispatch has no delay.
Security Considerations
- Same-repository only - Cannot dispatch workflows in other repositories. This prevents cross-repository workflow triggering which could be a security risk.
- Allowlist enforcement - Only workflows explicitly listed in the
workflowsconfiguration can be dispatched. Requests for unlisted workflows are rejected. - Compile-time validation - Workflows are validated at compile time to catch configuration errors early.
Agent Session Creation (create-agent-session:)
Section titled “Agent Session Creation (create-agent-session:)”Creates Copilot coding agent sessions. Requires COPILOT_GITHUB_TOKEN or GH_AW_GITHUB_TOKEN PAT-default GITHUB_TOKEN lacks permissions.
Assign to Agent (assign-to-agent:)
Section titled “Assign to Agent (assign-to-agent:)”Programmatically assigns GitHub Copilot coding agent to existing issues or pull requests through workflow automation. This safe output automates the standard GitHub workflow for assigning issues to Copilot. Requires fine-grained PAT with actions, contents, issues, pull requests write access stored as GH_AW_AGENT_TOKEN, or GitHub App token. Supported agents: copilot (copilot-swe-agent).
Auto-resolves target from workflow context (issue/PR events) when issue_number or pull_number not explicitly provided. Restrict with allowed list. Target: "triggering" (default), "*" (any), or number.
safe-outputs: assign-to-agent: name: "copilot" # default agent (default: "copilot") model: "claude-opus-4.6" # default AI model (default: "auto") custom-agent: "agent-id" # default custom agent ID (optional) custom-instructions: "..." # default custom instructions (optional) allowed: [copilot] # restrict to specific agents (optional) max: 1 # max assignments (default: 1) target: "triggering" # "triggering" (default), "*", or number target-repo: "owner/repo" # where the issue lives (cross-repository) pull-request-repo: "owner/repo" # where the PR should be created (may differ from issue repo) allowed-pull-request-repos: [owner/repo1, owner/repo2] # additional allowed PR repositories base-branch: "develop" # target branch for PR (default: target repo's default branch) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsTarget Issue or Pull Request:
target: "triggering"- Auto-resolves fromgithub.event.issue.numberorgithub.event.pull_request.numbertarget: "*"- Requires explicitissue_numberorpull_numberin agent outputtarget: "123"- Always uses issue/PR #123
Cross-Repository PR Creation:
The pull-request-repo parameter allows you to create pull requests in a different repository than where the issue lives. This is useful when:
- Issues are tracked in a central repository but code lives in separate repositories
- You want to separate issue tracking from code repositories
When pull-request-repo is configured, Copilot will create the pull request in the specified repository instead of the issue’s repository. The issue repository is determined by target-repo or defaults to the workflow’s repository.
The repository specified by pull-request-repo is automatically allowed - you don’t need to list it in allowed-pull-request-repos. Use allowed-pull-request-repos to specify additional repositories where PRs can be created.
Use base-branch to specify which branch in the target repository the pull request should target. When omitted, the target repository’s actual default branch is used automatically. Only relevant when pull-request-repo is configured.
Assignee Filtering:
When allowed list is configured, existing agent assignees not in the list are removed while regular user assignees are preserved.
Use assign-to-agent when you need to programmatically assign agents to existing issues or PRs through workflow automation. If you’re creating new issues and want to assign an agent immediately, use assignees: copilot in your create-issue configuration instead.
Assign to User (assign-to-user:)
Section titled “Assign to User (assign-to-user:)”Assigns users to issues. Restrict with allowed list. Target: "triggering" (issue event), "*" (any), or number. Supports single or multiple assignees.
safe-outputs: assign-to-user: allowed: [user1, user2] # restrict to specific users max: 3 # max assignments (default: 1) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository unassign-first: true # unassign all current assignees before assigning (default: false) github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsUnassign from User (unassign-from-user:)
Section titled “Unassign from User (unassign-from-user:)”Removes user assignments from issues or pull requests. Restrict with allowed list to control which users can be unassigned. Target: "triggering" (issue/PR event), "*" (any), or number.
safe-outputs: unassign-from-user: allowed: [user1, user2] # restrict to specific users max: 1 # max unassignments (default: 1) target: "*" # "triggering" (default), "*", or number target-repo: "owner/repo" # cross-repository github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissionsCross-Repository Operations
Section titled “Cross-Repository Operations”Most safe outputs support target-repo. This will generally require an authorization option (github-token or app:)-to take effect.
safe-outputs: create-issue: target-repo: "org/tracking-repo" github-token: ${{ secrets.CROSS_REPO_PAT }}Global Configuration Options
Section titled “Global Configuration Options”Group Reports (group-reports:)
Section titled “Group Reports (group-reports:)”Controls whether failed workflow runs are grouped under a parent “[agentics] Failed runs” issue. This is opt-in and defaults to false.
safe-outputs: create-issue: group-reports: true # Enable parent issue grouping for failed runs (default: false)When enabled, individual failed run reports are linked as sub-issues under a shared parent issue, making it easier to track recurring failures across workflow runs. When disabled (the default), each failure is reported independently.
Custom GitHub Token (github-token:)
Section titled “Custom GitHub Token (github-token:)”Override for all safe outputs, or per safe output:
safe-outputs: github-token: ${{ secrets.CUSTOM_PAT }} # global create-issue: create-pull-request: github-token: ${{ secrets.PR_PAT }} # per-outputGitHub App Token (app:)
Section titled “GitHub App Token (app:)”Use GitHub App tokens for enhanced security: on-demand token minting, automatic revocation, fine-grained permissions, and better attribution.
See GitHub App for Safe Outputs for configuration details and security benefits.
Text Sanitization (allowed-domains:, allowed-github-references:)
Section titled “Text Sanitization (allowed-domains:, allowed-github-references:)”The text output by AI agents is automatically sanitized to prevent injection of malicious content and ensure safe rendering on GitHub. The auto-sanitization applied is: XML escaped, HTTPS only, domain allowlist (GitHub by default), 0.5MB/65k line limits, control char stripping.
You can configure sanitization options:
safe-outputs: allowed-domains: [api.github.com] # GitHub domains always included allowed-github-references: [] # Escape all GitHub referencesDomain Filtering (allowed-domains): Controls which domains are allowed in URLs. URLs from other domains are replaced with (redacted).
Reference Escaping (allowed-github-references): Controls which GitHub repository references (#123, owner/repo#456) are allowed in workflow output. When configured, references to unlisted repositories are escaped with backticks to prevent GitHub from creating timeline items. This is particularly useful for SideRepoOps workflows to prevent automation from cluttering your main repository’s timeline.
[]- Escape all references (prevents all timeline items)["repo"]- Allow only the target repository’s references["repo", "owner/other-repo"]- Allow specific repositories- Not specified (default) - All references allowed
Bot Mention Limit (max-bot-mentions:)
Section titled “Bot Mention Limit (max-bot-mentions:)”Agent output is automatically scanned for bot trigger phrases (e.g., @copilot, @github-actions) to prevent accidental automation triggering. By default, the first 10 occurrences are left unchanged and any excess are escaped with backticks. Entries already wrapped in backticks are skipped.
Use max-bot-mentions to adjust this threshold:
safe-outputs: max-bot-mentions: 3 # Allow 3 unescaped bot mentions per output create-issue:Accepts a literal integer or a GitHub Actions expression string (e.g., ${{ inputs.max-mentions }}). Set to 0 to escape all bot trigger phrases. Default: 10.
Templatable Fields
Section titled “Templatable Fields”max, expires, and max-bot-mentions accept GitHub Actions expression strings in addition to literal integers, allowing workflow inputs or repository variables to control limits at runtime:
safe-outputs: max-bot-mentions: ${{ inputs.max-mentions }} create-issue: max: ${{ inputs.max-issues }} expires: ${{ inputs.expires-days }} create-pull-request: max: ${{ inputs.max-prs }} draft: ${{ inputs.create-draft }}Most boolean configuration fields also accept expression strings. Fields that influence permission computation (such as add-comment.discussion and create-pull-request.fallback-as-issue) remain literal booleans.
Maximum Patch Size (max-patch-size:)
Section titled “Maximum Patch Size (max-patch-size:)”Limits git patch size for PR operations (1-10,240 KB, default: 1024 KB):
safe-outputs: max-patch-size: 512 # max patch size in KB create-pull-request:Custom Runner Image
Section titled “Custom Runner Image”Specify custom runner for safe output jobs (default: ubuntu-slim): runs-on: ubuntu-22.04
Custom Messages (messages:)
Section titled “Custom Messages (messages:)”Customize notifications using template variables and Markdown. Import from shared workflows (local overrides imported).
safe-outputs: messages: footer: "> Generated by [{workflow_name}]({run_url})" append-only-comments: true run-started: " Processing {event_type}..." run-success: "✓ Completed successfully" run-failure: "✗ Encountered {status}" create-issue:Templates: footer, footer-install, staged-title, staged-description, run-started, run-success, run-failure
Options: append-only-comments (default: false)
Variables: {workflow_name}, {run_url}, {triggering_number}, {workflow_source}, {workflow_source_url}, {event_type}, {status}, {operation}
Related Documentation
Section titled “Related Documentation”- Threat Detection Guide - Complete threat detection documentation and examples
- Frontmatter - All configuration options for workflows
- Workflow Structure - Directory layout and organization
- Command Triggers - Special /my-bot triggers and context text
- CLI Commands - CLI commands for workflow management