diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index 39499b44174..3147f34ed38 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -778,6 +778,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index b31cc3594f3..cdb48e0b571 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -881,6 +881,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index f5d9c6e7723..ec82d7f05f1 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -815,6 +815,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 71053a78916..ca85638d3fd 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -847,6 +847,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 0d663c8058b..456848ea156 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -808,6 +808,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 80f9e5fb243..3a4b29f10ff 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -1127,6 +1127,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml index b0ff3e98a62..1c536a92e30 100644 --- a/.github/workflows/issue-triage-agent.lock.yml +++ b/.github/workflows/issue-triage-agent.lock.yml @@ -727,6 +727,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/org-health-report.lock.yml b/.github/workflows/org-health-report.lock.yml index 3cd34a5f5ab..ef1da2fd790 100644 --- a/.github/workflows/org-health-report.lock.yml +++ b/.github/workflows/org-health-report.lock.yml @@ -817,6 +817,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index dc9e24ae9cc..bdb5a18a97a 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -819,6 +819,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index e63ccc14b35..09770a545dc 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -805,6 +805,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index e4f42a55ef9..008cc0edd42 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -986,6 +986,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/refiner.lock.yml b/.github/workflows/refiner.lock.yml index 0d2a5ad0d8b..53257537d42 100644 --- a/.github/workflows/refiner.lock.yml +++ b/.github/workflows/refiner.lock.yml @@ -788,6 +788,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 432471cffe1..49e20732f56 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -1053,6 +1053,7 @@ jobs: /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 5d804edadf2..b52601edffe 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -756,6 +756,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index b6a4bbfd3c7..0520a2c453b 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -756,6 +756,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 39b07e76b8d..43b4f3ed76b 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -782,6 +782,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 95ad608b214..bf5ea2d9108 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -756,6 +756,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index b5bb023a529..191cb949935 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -760,6 +760,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index 882a8bd9ddb..e86db2f98e6 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -883,6 +883,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/weekly-blog-post-writer.lock.yml b/.github/workflows/weekly-blog-post-writer.lock.yml index c72690b2a4b..5cad7a53b11 100644 --- a/.github/workflows/weekly-blog-post-writer.lock.yml +++ b/.github/workflows/weekly-blog-post-writer.lock.yml @@ -918,6 +918,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml index b2513f76177..bb20a7e4d05 100644 --- a/.github/workflows/weekly-issue-summary.lock.yml +++ b/.github/workflows/weekly-issue-summary.lock.yml @@ -797,6 +797,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/weekly-safe-outputs-spec-review.lock.yml b/.github/workflows/weekly-safe-outputs-spec-review.lock.yml index 2813d479876..f2eca75fee3 100644 --- a/.github/workflows/weekly-safe-outputs-spec-review.lock.yml +++ b/.github/workflows/weekly-safe-outputs-spec-review.lock.yml @@ -737,6 +737,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index 2e11528e1bd..9790125d430 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -814,6 +814,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/proxy-logs/ + !/tmp/gh-aw/proxy-logs/proxy-tls/ /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/agent/ /tmp/gh-aw/safeoutputs.jsonl diff --git a/pkg/workflow/compiler_difc_proxy.go b/pkg/workflow/compiler_difc_proxy.go index c7a2846b231..23bb0d23039 100644 --- a/pkg/workflow/compiler_difc_proxy.go +++ b/pkg/workflow/compiler_difc_proxy.go @@ -276,5 +276,11 @@ func difcProxyLogPaths(data *WorkflowData) []string { } // proxy-logs/ contains TLS certs and container stderr from the proxy // (mcp-logs/ is already collected as part of standard MCP logging) - return []string{"/tmp/gh-aw/proxy-logs/"} + // Exclude proxy-tls/ because it contains the TLS private key (server.key) which is + // created by the Docker container with root-only permissions, causing artifact upload + // to fail with EACCES. The private key is ephemeral and should not be uploaded. + return []string{ + "/tmp/gh-aw/proxy-logs/", + "!/tmp/gh-aw/proxy-logs/proxy-tls/", + } } diff --git a/pkg/workflow/compiler_difc_proxy_test.go b/pkg/workflow/compiler_difc_proxy_test.go index 98823ec0ccc..03954809e1f 100644 --- a/pkg/workflow/compiler_difc_proxy_test.go +++ b/pkg/workflow/compiler_difc_proxy_test.go @@ -362,8 +362,9 @@ func TestDIFCProxyLogPaths(t *testing.T) { CustomSteps: "steps:\n - name: Fetch\n env:\n GH_TOKEN: ${{ github.token }}\n run: gh issue list", } paths := difcProxyLogPaths(data) - require.Len(t, paths, 1, "should return exactly one path") - assert.Contains(t, paths[0], "proxy-logs", "path should include proxy-logs directory") + require.Len(t, paths, 2, "should return inclusion path and proxy-tls exclusion path") + assert.Contains(t, paths[0], "proxy-logs", "first path should include proxy-logs directory") + assert.Equal(t, "!/tmp/gh-aw/proxy-logs/proxy-tls/", paths[1], "second path should exclude proxy-tls directory") }) } diff --git a/pkg/workflow/step_order_validation.go b/pkg/workflow/step_order_validation.go index d1f2d9d7764..b2e9b202a29 100644 --- a/pkg/workflow/step_order_validation.go +++ b/pkg/workflow/step_order_validation.go @@ -178,6 +178,12 @@ func (t *StepOrderTracker) findUnscannablePaths(artifactUploads []StepRecord) [] // isPathScannedBySecretRedaction checks if a path would be scanned by the secret redaction step // or is otherwise safe to upload (known engine-controlled diagnostic paths). func isPathScannedBySecretRedaction(path string) bool { + // Exclusion patterns (paths starting with !) are not uploaded - they tell the artifact + // action to skip matching files. They do not need to be scanned by secret redaction. + if strings.HasPrefix(path, "!") { + return true + } + // Paths must be under /tmp/gh-aw/ or ${RUNNER_TEMP}/gh-aw/ to be scanned. // Accept both literal paths and environment variable references. // Engines that produce output outside /tmp/gh-aw/ must move their files into /tmp/gh-aw/ diff --git a/pkg/workflow/step_order_validation_test.go b/pkg/workflow/step_order_validation_test.go index cbf977bca34..b42d1ed06de 100644 --- a/pkg/workflow/step_order_validation_test.go +++ b/pkg/workflow/step_order_validation_test.go @@ -128,6 +128,16 @@ func TestIsPathScannedBySecretRedaction_ScannableFiles(t *testing.T) { path: "${{ env.GH_AW_SAFE_OUTPUTS }}", expected: true, }, + { + name: "Exclusion pattern (proxy-tls directory)", + path: "!/tmp/gh-aw/proxy-logs/proxy-tls/", + expected: true, + }, + { + name: "Exclusion pattern (file outside /tmp/gh-aw/)", + path: "!/some/other/path/file.key", + expected: true, + }, } for _, tt := range tests {