From 9470d54204ce5251bff22e3af9ad07e978d44f61 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:53:56 +0000 Subject: [PATCH 1/2] Initial plan From 7ff2ff5b3e57a6454f16aec7c8f0e3e20d8e311a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 22:10:41 +0000 Subject: [PATCH 2/2] Extend auto-triage-issues to triage gh-aw-security-finding issues with severity labels and assignees Agent-Logs-Url: https://github.com/github/gh-aw/sessions/4af6e02e-400d-4671-90bd-14d111258967 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/auto-triage-issues.lock.yml | 70 +++++++++++++++---- .github/workflows/auto-triage-issues.md | 48 ++++++++++--- 2 files changed, 94 insertions(+), 24 deletions(-) diff --git a/.github/workflows/auto-triage-issues.lock.yml b/.github/workflows/auto-triage-issues.lock.yml index 773d1a2e50a..33e77d39621 100644 --- a/.github/workflows/auto-triage-issues.lock.yml +++ b/.github/workflows/auto-triage-issues.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"395091b3248ae0bfdd9169fe4e375b45de1a524b5a1c7ac4189864a829171a9e","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b5af165e0faa0dcdf6e28bf7a0a98f36d5549df650bd406020e5b4535d0cefdb","strict":true,"agent_id":"copilot"} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"ed597411d8f924073f98dfc5c65a23a2325f34cd","version":"v8"},{"repo":"actions/upload-artifact","sha":"bbbca2ddaa5d8feaa63e36b76fdaad77386f024f","version":"v7"}]} # ___ _ _ # / _ \ | | (_) @@ -167,16 +167,16 @@ jobs: run: | bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh { - cat << 'GH_AW_PROMPT_348e9f22fc6fd7c7_EOF' + cat << 'GH_AW_PROMPT_418b8ca92c9f06c2_EOF' - GH_AW_PROMPT_348e9f22fc6fd7c7_EOF + GH_AW_PROMPT_418b8ca92c9f06c2_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_348e9f22fc6fd7c7_EOF' + cat << 'GH_AW_PROMPT_418b8ca92c9f06c2_EOF' - Tools: create_discussion, add_labels(max:10), missing_tool, missing_data, noop + Tools: create_discussion, add_labels(max:10), remove_labels, assign_to_user, missing_tool, missing_data, noop The following GitHub context information is available for this workflow: @@ -206,14 +206,14 @@ jobs: {{/if}} - GH_AW_PROMPT_348e9f22fc6fd7c7_EOF + GH_AW_PROMPT_418b8ca92c9f06c2_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_348e9f22fc6fd7c7_EOF' + cat << 'GH_AW_PROMPT_418b8ca92c9f06c2_EOF' {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/auto-triage-issues.md}} - GH_AW_PROMPT_348e9f22fc6fd7c7_EOF + GH_AW_PROMPT_418b8ca92c9f06c2_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 @@ -384,9 +384,9 @@ jobs: mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_d225981bc842f158_EOF' - {"add_labels":{"max":10},"create_discussion":{"category":"audits","close_older_discussions":true,"expires":24,"fallback_to_issue":true,"max":1,"title_prefix":"[Auto-Triage] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_d225981bc842f158_EOF + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_3c4c6a8c57832638_EOF' + {"add_labels":{"max":10},"assign_to_user":{"max":1},"create_discussion":{"category":"audits","close_older_discussions":true,"expires":24,"fallback_to_issue":true,"max":1,"title_prefix":"[Auto-Triage] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"remove_labels":{},"report_incomplete":{}} + GH_AW_SAFE_OUTPUTS_CONFIG_3c4c6a8c57832638_EOF - name: Write Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -419,6 +419,28 @@ jobs: } } }, + "assign_to_user": { + "defaultMax": 1, + "fields": { + "assignee": { + "type": "string", + "sanitize": true, + "maxLength": 39 + }, + "assignees": { + "type": "[]string", + "sanitize": true, + "maxLength": 39 + }, + "issue_number": { + "issueOrPRNumber": true + }, + "repo": { + "type": "string", + "maxLength": 256 + } + } + }, "create_discussion": { "defaultMax": 1, "fields": { @@ -502,6 +524,25 @@ jobs: } } }, + "remove_labels": { + "defaultMax": 5, + "fields": { + "item_number": { + "issueNumberOrTemporaryId": true + }, + "labels": { + "required": true, + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 128 + }, + "repo": { + "type": "string", + "maxLength": 256 + } + } + }, "report_incomplete": { "defaultMax": 5, "fields": { @@ -592,7 +633,7 @@ jobs: export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.16' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_17800b88a17b863b_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_0802512325be0bcb_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh { "mcpServers": { "github": { @@ -636,7 +677,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_17800b88a17b863b_EOF + GH_AW_MCP_CONFIG_0802512325be0bcb_EOF - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -1204,6 +1245,7 @@ jobs: GH_AW_WORKFLOW_ID: "auto-triage-issues" GH_AW_WORKFLOW_NAME: "Auto-Triage Issues" outputs: + assign_to_user_assigned: ${{ steps.process_safe_outputs.outputs.assigned }} code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }} code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }} create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} @@ -1256,7 +1298,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"max\":10},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Auto-Triage] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_labels\":{\"max\":10},\"assign_to_user\":{\"max\":1},\"create_discussion\":{\"category\":\"audits\",\"close_older_discussions\":true,\"expires\":24,\"fallback_to_issue\":true,\"max\":1,\"title_prefix\":\"[Auto-Triage] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"remove_labels\":{},\"report_incomplete\":{}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/auto-triage-issues.md b/.github/workflows/auto-triage-issues.md index abaabb7bb0c..31233d31502 100644 --- a/.github/workflows/auto-triage-issues.md +++ b/.github/workflows/auto-triage-issues.md @@ -31,6 +31,8 @@ tools: safe-outputs: add-labels: max: 10 + remove-labels: {} + assign-to-user: {} create-discussion: expires: 1d title-prefix: "[Auto-Triage] " @@ -59,33 +61,59 @@ When triggered by an issue event (opened/edited), scheduled run, or manual dispa When an issue is opened or edited: 1. **Analyze the issue** that triggered this workflow (available in `github.event.issue`) -2. **Check if the author is a community member** — if `author_association` is `NONE`, `FIRST_TIME_CONTRIBUTOR`, `FIRST_TIMER`, or `CONTRIBUTOR`, and the author is **not** a bot (`user.type != "Bot"` and login does not end with `[bot]`), include `community` in the labels to apply -3. **Classify the issue** based on its title and body content -4. **Apply all labels** (including `community` if applicable) in a single `add_labels` call -5. If uncertain about classification, add the `needs-triage` label for human review +2. **Check if the issue has the `gh-aw-security-finding` label** — if so, follow the Security Finding Triage rules below in addition to normal classification +3. **Check if the author is a community member** — if `author_association` is `NONE`, `FIRST_TIME_CONTRIBUTOR`, `FIRST_TIMER`, or `CONTRIBUTOR`, and the author is **not** a bot (`user.type != "Bot"` and login does not end with `[bot]`), include `community` in the labels to apply +4. **Classify the issue** based on its title and body content +5. **Apply all labels** (including `community` if applicable) in a single `add_labels` call +6. If uncertain about classification, add the `needs-triage` label for human review ### On Scheduled Runs (Every 6 Hours) When running on schedule: 1. **Fetch unlabeled issues** using GitHub tools -2. **Process up to 10 unlabeled issues** (respecting safe-output limits) -3. **Apply labels** to each issue based on classification -4. **Create a summary report** as a discussion with statistics on processed issues +2. **Fetch `gh-aw-security-finding` issues** that lack severity labels (`security:critical`, `security:high-severity`, `security:medium-severity`, `security:low-severity`) and lack assignees +3. **Process up to 10 unlabeled or un-triaged security issues** (respecting safe-output limits) +4. **Apply labels** to each issue based on classification; for security findings, apply severity labels and assign to an appropriate team member +5. **Create a summary report** as a discussion with statistics on processed issues ### On Manual/On-Demand Runs (workflow_dispatch) When triggered manually as a backfill pass: 1. **Fetch ALL open issues without any labels** using GitHub tools — do not limit to a fixed count -2. **Process up to 10 unlabeled issues** in this run (respecting safe-output limits); if more exist, note the remainder in the report -3. **Apply labels** to each issue based on classification rules below, using title/body heuristics and existing triage rules -4. **Create a summary report** as a discussion listing every issue processed, the labels applied, and how many unlabeled issues (if any) still remain for the next pass +2. **Fetch ALL open `gh-aw-security-finding` issues** that lack severity labels or assignees — these get priority processing regardless of other labels +3. **Process up to 10 unlabeled or un-triaged security issues** in this run (respecting safe-output limits); if more exist, note the remainder in the report +4. **Apply labels** to each issue based on classification rules below, using title/body heuristics and existing triage rules; for security findings apply severity labels and assign to an appropriate reviewer +5. **Create a summary report** as a discussion listing every issue processed, the labels applied, and how many unlabeled issues (if any) still remain for the next pass ## Classification Rules Apply labels based on the following rules. You can apply multiple labels when appropriate. +### Security Finding Triage (`gh-aw-security-finding` label) + +When an issue already has the `gh-aw-security-finding` label, perform a dedicated security triage pass **in addition to** the normal classification below: + +1. **Check for existing severity label** — if the issue already has one of `security:critical`, `security:high-severity`, `security:medium-severity`, or `security:low-severity`, skip severity labeling (already triaged). + +2. **Determine severity** by analyzing the issue title and body: + - `security:critical` — Remote code execution, authentication bypass, full data exfiltration, or supply-chain compromise (e.g., SHA-less container images from untrusted registries, token leakage to external parties) + - `security:high-severity` — Privilege escalation, bearer-token bypass, sandbox escape, improper input sanitization that enables injection, or pinned-version violations that expose the supply chain (e.g., Claude engine unpinned `claude-code` version, MCP containers without SHA-256 digest, percent-encoding bypass of URL sanitization) + - `security:medium-severity` — Sensitive data in logs with insufficiently restrictive file permissions, weak credential masking, limited-scope information disclosure, or defense-in-depth gaps (e.g., `agent-stdio.log` mode 0600 + token masking) + - `security:low-severity` — Minor hardening improvements, low-impact information exposure, or configuration suggestions with no direct exploitability path + +3. **Apply the severity label** determined above. + +4. **Also apply** the `security` component label if not already present. + +5. **Assign to an appropriate reviewer** using `assign_to_user`. Use the following heuristic: + - If the issue mentions a specific maintainer or the body includes a GitHub handle with `@`, assign to that user. + - Otherwise, look up recent contributors to security-related files in the repository (e.g., recent commit authors on files under `pkg/workflow/`, `actions/`) and assign to the most recent contributor who appears to have security domain knowledge. + - If no clear match is found, skip the assignment and note in the scheduled-run report that the issue needs manual assignment. + +6. **Remove `needs-triage`** if it is the only remaining label after applying the severity label (use `remove_labels`). Do not remove other labels. + ### Issue Type Classification **Bug Reports** - Apply `bug` label when: