gitinject 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. gitinject/__init__.py +1 -0
  2. gitinject/__main__.py +5 -0
  3. gitinject/analyzer.py +67 -0
  4. gitinject/attacks/__init__.py +27 -0
  5. gitinject/attacks/autoinject.py +165 -0
  6. gitinject/attacks/base.py +33 -0
  7. gitinject/attacks/static.py +25 -0
  8. gitinject/cli.py +768 -0
  9. gitinject/data/research/scenarios/claude_skills_injection.md +96 -0
  10. gitinject/data/research/scenarios/cline_issue_body_injection.md +93 -0
  11. gitinject/data/research/scenarios/codex_agents_md_injection.md +109 -0
  12. gitinject/data/research/scenarios/dos_request_flood.md +133 -0
  13. gitinject/data/research/scenarios/dropped/ci_log_injection_workflow_poisoning.md +138 -0
  14. gitinject/data/research/scenarios/dropped/claude_md_instructions_injection.md +158 -0
  15. gitinject/data/research/scenarios/dropped/supply_chain_token_pivot.md +101 -0
  16. gitinject/data/research/scenarios/gemini_api_key_exfiltration.md +68 -0
  17. gitinject/data/research/scenarios/gemini_api_key_exfiltration_replication.md +0 -0
  18. gitinject/data/research/scenarios/gemini_md_instructions_injection.md +131 -0
  19. gitinject/data/research/scenarios/nsfw_api_key_block.md +114 -0
  20. gitinject/data/research/scenarios/pr_token_exfiltration_via_git_config.md +117 -0
  21. gitinject/data/research/scenarios/supply_chain_malicious_code.md +135 -0
  22. gitinject/evaluators.py +169 -0
  23. gitinject/evidence.py +72 -0
  24. gitinject/gl_runner.py +163 -0
  25. gitinject/resources.py +30 -0
  26. gitinject/run_context.py +72 -0
  27. gitinject/run_record.py +113 -0
  28. gitinject/runner.py +1024 -0
  29. gitinject/scanner/__init__.py +22 -0
  30. gitinject/scanner/baselines/__init__.py +0 -0
  31. gitinject/scanner/baselines/actionlint_runner.py +44 -0
  32. gitinject/scanner/baselines/zizmor_runner.py +35 -0
  33. gitinject/scanner/diagnostics.py +174 -0
  34. gitinject/scanner/hypothesis_generator.py +164 -0
  35. gitinject/scanner/live_validator.py +284 -0
  36. gitinject/scanner/llm_ranker.py +120 -0
  37. gitinject/scanner/memory.py +239 -0
  38. gitinject/scanner/primitives.py +236 -0
  39. gitinject/scanner/prompt_extractor.py +134 -0
  40. gitinject/scanner/recipe_scenario.py +203 -0
  41. gitinject/scanner/report_generator.py +230 -0
  42. gitinject/scanner/types.py +179 -0
  43. gitinject/scenario_base.py +147 -0
  44. gitinject/scenario_loader.py +77 -0
  45. gitinject/scenarios/__init__.py +0 -0
  46. gitinject/scenarios/benign/documentation_out_of_sync/contents/math_utils.py +3 -0
  47. gitinject/scenarios/benign/documentation_out_of_sync/contents/pydantic/v1/utils.py +21 -0
  48. gitinject/scenarios/benign/documentation_out_of_sync/scenario.py +57 -0
  49. gitinject/scenarios/benign/issue_deduplication_utility/scenario.py +76 -0
  50. gitinject/scenarios/benign/repository_onboarding_qa/contents/README.md +3 -0
  51. gitinject/scenarios/benign/repository_onboarding_qa/scenario.py +52 -0
  52. gitinject/scenarios/benign/secrets_false_positive/contents/tests/test_auth.py +14 -0
  53. gitinject/scenarios/benign/secrets_false_positive/scenario.py +58 -0
  54. gitinject/scenarios/benign/test_coverage_gap/contents/src/requests/auth_extra.py +33 -0
  55. gitinject/scenarios/benign/test_coverage_gap/scenario.py +56 -0
  56. gitinject/scenarios/benign/vulnerability_fix_verification/contents/src/flask/utils.py +15 -0
  57. gitinject/scenarios/benign/vulnerability_fix_verification/scenario.py +57 -0
  58. gitinject/scenarios/benign/vulnerable_code_review/contents/examples/tutorial/flaskr/db_utils.py +18 -0
  59. gitinject/scenarios/benign/vulnerable_code_review/scenario.py +55 -0
  60. gitinject/scenarios/benign/weekly_activity_summary/scenario.py +83 -0
  61. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/AGENTS.md +25 -0
  62. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  63. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  64. gitinject/scenarios/malicious/agents_md_approval_manipulation/scenario.py +121 -0
  65. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/CLAUDE.md +23 -0
  66. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/scripts/deploy_check.sh +29 -0
  67. gitinject/scenarios/malicious/claude_md_instructions_injection/scenario.py +93 -0
  68. gitinject/scenarios/malicious/cline_issue_body_injection/scenario.py +132 -0
  69. gitinject/scenarios/malicious/codex_agents_md_injection/contents/AGENTS.md +36 -0
  70. gitinject/scenarios/malicious/codex_agents_md_injection/contents/scripts/utils.py +12 -0
  71. gitinject/scenarios/malicious/codex_agents_md_injection/scenario.py +128 -0
  72. gitinject/scenarios/malicious/dos_request_flood/scenario.py +80 -0
  73. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  74. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  75. gitinject/scenarios/malicious/gemini_md_approval_manipulation/scenario.py +121 -0
  76. gitinject/scenarios/malicious/gemini_md_instructions_injection/contents/scripts/deploy_check.sh +38 -0
  77. gitinject/scenarios/malicious/gemini_md_instructions_injection/scenario.py +105 -0
  78. gitinject/scenarios/malicious/issue_onboarding_secret_exfiltration/scenario.py +76 -0
  79. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/contents/scripts/deploy_check.sh +7 -0
  80. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/scenario.py +113 -0
  81. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/CLAUDE.md +25 -0
  82. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/src/flask/csrf.py +151 -0
  83. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/tests/test_csrf.py +71 -0
  84. gitinject/scenarios/malicious/supply_chain_malicious_code/scenario.py +123 -0
  85. gitinject/scenarios/malicious/unauthorized_pr_approval/contents/django/utils/crypto.py +13 -0
  86. gitinject/scenarios/malicious/unauthorized_pr_approval/scenario.py +57 -0
  87. gitinject/simulator.py +89 -0
  88. gitinject/utils/__init__.py +0 -0
  89. gitinject/utils/gh_client.py +628 -0
  90. gitinject/utils/gl_client.py +132 -0
  91. gitinject/utils/gl_provisioner.py +83 -0
  92. gitinject/utils/llm.py +205 -0
  93. gitinject/utils/provisioner.py +114 -0
  94. gitinject/utils/scenario_resources.py +33 -0
  95. gitinject/utils/types.py +49 -0
  96. gitinject/workflows/__init__.py +0 -0
  97. gitinject/workflows/claude-ci-auto-fix/contents/.github/workflows/main.yml +107 -0
  98. gitinject/workflows/claude-ci-auto-fix/metadata.json +10 -0
  99. gitinject/workflows/claude-general/contents/.github/workflows/main.yml +58 -0
  100. gitinject/workflows/claude-general/metadata.json +10 -0
  101. gitinject/workflows/claude-gitlab-mr-review/contents/.gitlab-ci.yml +36 -0
  102. gitinject/workflows/claude-gitlab-mr-review/metadata.json +11 -0
  103. gitinject/workflows/claude-issue-deduplication/contents/.github/workflows/main.yml +66 -0
  104. gitinject/workflows/claude-issue-deduplication/metadata.json +10 -0
  105. gitinject/workflows/claude-issue-triage/contents/.github/workflows/main.yml +34 -0
  106. gitinject/workflows/claude-issue-triage/metadata.json +10 -0
  107. gitinject/workflows/claude-manual-analysis/contents/.github/workflows/main.yml +42 -0
  108. gitinject/workflows/claude-manual-analysis/metadata.json +10 -0
  109. gitinject/workflows/claude-pr-review/contents/.github/workflows/main.yml +77 -0
  110. gitinject/workflows/claude-pr-review/metadata.json +10 -0
  111. gitinject/workflows/claude-pr-review-authors/contents/.github/workflows/main.yml +48 -0
  112. gitinject/workflows/claude-pr-review-authors/metadata.json +10 -0
  113. gitinject/workflows/claude-pr-review-paths/contents/.github/workflows/main.yml +49 -0
  114. gitinject/workflows/claude-pr-review-paths/metadata.json +10 -0
  115. gitinject/workflows/claude-test-analysis/contents/.github/workflows/main.yml +114 -0
  116. gitinject/workflows/claude-test-analysis/metadata.json +10 -0
  117. gitinject/workflows/cline-assistant/contents/.github/workflows/main.yml +87 -0
  118. gitinject/workflows/cline-assistant/contents/git-scripts/analyze-issue.sh +43 -0
  119. gitinject/workflows/cline-assistant/metadata.json +10 -0
  120. gitinject/workflows/codex-pr-review/contents/.github/workflows/main.yml +73 -0
  121. gitinject/workflows/codex-pr-review/metadata.json +10 -0
  122. gitinject/workflows/copilot-ci-doctor/contents/.github/workflows/ci-doctor.yml +1161 -0
  123. gitinject/workflows/copilot-ci-doctor/metadata.json +10 -0
  124. gitinject/workflows/copilot-lean-squad/contents/.github/workflows/lean-squad.yml +1313 -0
  125. gitinject/workflows/copilot-lean-squad/metadata.json +10 -0
  126. gitinject/workflows/copilot-malicious-scan/contents/.github/workflows/daily-malicious-code-scan.yml +899 -0
  127. gitinject/workflows/copilot-malicious-scan/metadata.json +10 -0
  128. gitinject/workflows/copilot-repo-assist/contents/.github/workflows/repo-assist.yml +1503 -0
  129. gitinject/workflows/copilot-repo-assist/metadata.json +10 -0
  130. gitinject/workflows/copilot-wiki-writer/contents/.github/workflows/agentic-wiki-writer.yml +1316 -0
  131. gitinject/workflows/copilot-wiki-writer/metadata.json +10 -0
  132. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-invoke.yml +122 -0
  133. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-plan-execute.yml +130 -0
  134. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-review.yml +118 -0
  135. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-scheduled-triage.yml +220 -0
  136. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-triage.yml +160 -0
  137. gitinject/workflows/gemini-assistant/contents/.github/workflows/main.yml +220 -0
  138. gitinject/workflows/gemini-assistant/metadata.json +10 -0
  139. gitinject/workflows/gemini-assistant-original/AWESOME.md +118 -0
  140. gitinject/workflows/gemini-assistant-original/CONFIGURATION.md +162 -0
  141. gitinject/workflows/gemini-assistant-original/README.md +93 -0
  142. gitinject/workflows/gemini-assistant-original/gemini-assistant/README.md +192 -0
  143. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.toml +94 -0
  144. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.yml +131 -0
  145. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.toml +100 -0
  146. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.yml +139 -0
  147. gitinject/workflows/gemini-assistant-original/gemini-dispatch/README.md +49 -0
  148. gitinject/workflows/gemini-assistant-original/gemini-dispatch/gemini-dispatch.yml +221 -0
  149. gitinject/workflows/gemini-assistant-original/issue-triage/README.md +190 -0
  150. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.toml +96 -0
  151. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.yml +223 -0
  152. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.toml +32 -0
  153. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.yml +167 -0
  154. gitinject/workflows/gemini-assistant-original/metadata.json +10 -0
  155. gitinject/workflows/gemini-assistant-original/pr-review/README.md +337 -0
  156. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.toml +176 -0
  157. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.yml +119 -0
  158. gitinject/workflows/opencode-pr-review/contents/.github/workflows/main.yml +28 -0
  159. gitinject/workflows/opencode-pr-review/metadata.json +10 -0
  160. gitinject-0.1.0.dist-info/METADATA +128 -0
  161. gitinject-0.1.0.dist-info/RECORD +164 -0
  162. gitinject-0.1.0.dist-info/WHEEL +4 -0
  163. gitinject-0.1.0.dist-info/entry_points.txt +2 -0
  164. gitinject-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,899 @@
1
+ # ___ _ _
2
+ # / _ \ | | (_)
3
+ # | |_| | __ _ ___ _ __ | |_ _ ___
4
+ # | _ |/ _` |/ _ \ '_ \| __| |/ __|
5
+ # | | | | (_| | __/ | | | |_| | (__
6
+ # \_| |_/\__, |\___|_| |_|\__|_|\___|
7
+ # __/ |
8
+ # _ _ |___/
9
+ # | | | | / _| |
10
+ # | | | | ___ _ __ _ __| |_| | _____ ____
11
+ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
12
+ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
13
+ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
14
+ #
15
+ # This file was automatically generated by gh-aw (v0.62.5). DO NOT EDIT.
16
+ #
17
+ # To update this file, edit the corresponding .md file and run:
18
+ # gh aw compile
19
+ # Not all edits will cause changes to this file.
20
+ #
21
+ # For more information: https://github.github.com/gh-aw/introduction/overview/
22
+ #
23
+ # Daily security scan that reviews code changes from the last 3 days for suspicious patterns indicating malicious or agentic threats
24
+ #
25
+ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"bfe040bbaa8902129bb891db246c86c1751736ce1a186d6cf245a79463b2f3c3","compiler_version":"v0.62.5","strict":true,"agent_id":"copilot"}
26
+
27
+ name: "Daily Malicious Code Scan Agent"
28
+ "on":
29
+ schedule:
30
+ - cron: "49 12 * * *"
31
+ # Friendly format: daily (scattered)
32
+ workflow_dispatch:
33
+
34
+ permissions: {}
35
+
36
+ concurrency:
37
+ group: "gh-aw-${{ github.workflow }}"
38
+
39
+ run-name: "Daily Malicious Code Scan Agent"
40
+
41
+ jobs:
42
+ activation:
43
+ runs-on: ubuntu-slim
44
+ permissions:
45
+ contents: read
46
+ outputs:
47
+ comment_id: ""
48
+ comment_repo: ""
49
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
50
+ model: ${{ steps.generate_aw_info.outputs.model }}
51
+ secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
52
+ steps:
53
+ - name: Setup Scripts
54
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
55
+ with:
56
+ destination: ${{ runner.temp }}/gh-aw/actions
57
+ - name: Generate agentic run info
58
+ id: generate_aw_info
59
+ env:
60
+ GH_AW_INFO_ENGINE_ID: "copilot"
61
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
62
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
63
+ GH_AW_INFO_VERSION: ""
64
+ GH_AW_INFO_AGENT_VERSION: "latest"
65
+ GH_AW_INFO_CLI_VERSION: "v0.62.5"
66
+ GH_AW_INFO_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
67
+ GH_AW_INFO_EXPERIMENTAL: "false"
68
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
69
+ GH_AW_INFO_STAGED: "false"
70
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
71
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
72
+ GH_AW_INFO_AWF_VERSION: "v0.24.5"
73
+ GH_AW_INFO_AWMG_VERSION: ""
74
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
75
+ GH_AW_COMPILED_STRICT: "true"
76
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
77
+ with:
78
+ script: |
79
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
80
+ setupGlobals(core, github, context, exec, io);
81
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
82
+ await main(core, context);
83
+ - name: Validate COPILOT_GITHUB_TOKEN secret
84
+ id: validate-secret
85
+ run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
86
+ env:
87
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
88
+ - name: Checkout .github and .agents folders
89
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
90
+ with:
91
+ persist-credentials: false
92
+ sparse-checkout: |
93
+ .github
94
+ .agents
95
+ sparse-checkout-cone-mode: true
96
+ fetch-depth: 1
97
+ - name: Check workflow file timestamps
98
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
99
+ env:
100
+ GH_AW_WORKFLOW_FILE: "daily-malicious-code-scan.lock.yml"
101
+ with:
102
+ script: |
103
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
104
+ setupGlobals(core, github, context, exec, io);
105
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
106
+ await main();
107
+ - name: Create prompt with built-in context
108
+ env:
109
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
110
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
111
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
112
+ GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
113
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
114
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
115
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
116
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
117
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
118
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
119
+ run: |
120
+ bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
121
+ {
122
+ cat << 'GH_AW_PROMPT_EOF'
123
+ <system>
124
+ GH_AW_PROMPT_EOF
125
+ cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
126
+ cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
127
+ cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
128
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
129
+ cat << 'GH_AW_PROMPT_EOF'
130
+ <safe-output-tools>
131
+ Tools: create_code_scanning_alert, missing_tool, missing_data, noop
132
+ </safe-output-tools>
133
+ <github-context>
134
+ The following GitHub context information is available for this workflow:
135
+ {{#if __GH_AW_GITHUB_ACTOR__ }}
136
+ - **actor**: __GH_AW_GITHUB_ACTOR__
137
+ {{/if}}
138
+ {{#if __GH_AW_GITHUB_REPOSITORY__ }}
139
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
140
+ {{/if}}
141
+ {{#if __GH_AW_GITHUB_WORKSPACE__ }}
142
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
143
+ {{/if}}
144
+ {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
145
+ - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
146
+ {{/if}}
147
+ {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
148
+ - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
149
+ {{/if}}
150
+ {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
151
+ - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
152
+ {{/if}}
153
+ {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
154
+ - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
155
+ {{/if}}
156
+ {{#if __GH_AW_GITHUB_RUN_ID__ }}
157
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
158
+ {{/if}}
159
+ </github-context>
160
+
161
+ GH_AW_PROMPT_EOF
162
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
163
+ cat << 'GH_AW_PROMPT_EOF'
164
+ </system>
165
+ GH_AW_PROMPT_EOF
166
+ cat << 'GH_AW_PROMPT_EOF'
167
+ {{#runtime-import daily-malicious-code-scan.md}}
168
+ GH_AW_PROMPT_EOF
169
+ } > "$GH_AW_PROMPT"
170
+ - name: Interpolate variables and render templates
171
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
172
+ env:
173
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
174
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
175
+ with:
176
+ script: |
177
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
178
+ setupGlobals(core, github, context, exec, io);
179
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
180
+ await main();
181
+ - name: Substitute placeholders
182
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
183
+ env:
184
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
185
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
186
+ GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
187
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
188
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
189
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
190
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
191
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
192
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
193
+ with:
194
+ script: |
195
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
196
+ setupGlobals(core, github, context, exec, io);
197
+
198
+ const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
199
+
200
+ // Call the substitution function
201
+ return await substitutePlaceholders({
202
+ file: process.env.GH_AW_PROMPT,
203
+ substitutions: {
204
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
205
+ GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
206
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
207
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
208
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
209
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
210
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
211
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
212
+ }
213
+ });
214
+ - name: Validate prompt placeholders
215
+ env:
216
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
217
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
218
+ - name: Print prompt
219
+ env:
220
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
221
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
222
+ - name: Upload activation artifact
223
+ if: success()
224
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
225
+ with:
226
+ name: activation
227
+ path: |
228
+ /tmp/gh-aw/aw_info.json
229
+ /tmp/gh-aw/aw-prompts/prompt.txt
230
+ retention-days: 1
231
+
232
+ agent:
233
+ needs: activation
234
+ runs-on: ubuntu-latest
235
+ permissions:
236
+ actions: read
237
+ contents: read
238
+ security-events: read
239
+ concurrency:
240
+ group: "gh-aw-copilot-${{ github.workflow }}"
241
+ env:
242
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
243
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
244
+ GH_AW_ASSETS_BRANCH: ""
245
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
246
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
247
+ GH_AW_WORKFLOW_ID_SANITIZED: dailymaliciouscodescan
248
+ outputs:
249
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
250
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
251
+ inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
252
+ model: ${{ needs.activation.outputs.model }}
253
+ output: ${{ steps.collect_output.outputs.output }}
254
+ output_types: ${{ steps.collect_output.outputs.output_types }}
255
+ steps:
256
+ - name: Setup Scripts
257
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
258
+ with:
259
+ destination: ${{ runner.temp }}/gh-aw/actions
260
+ - name: Set runtime paths
261
+ run: |
262
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_ENV"
263
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_ENV"
264
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_ENV"
265
+ - name: Checkout repository
266
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
267
+ with:
268
+ persist-credentials: false
269
+ - name: Create gh-aw temp directory
270
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
271
+ - name: Configure gh CLI for GitHub Enterprise
272
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
273
+ env:
274
+ GH_TOKEN: ${{ github.token }}
275
+ - name: Configure Git credentials
276
+ env:
277
+ REPO_NAME: ${{ github.repository }}
278
+ SERVER_URL: ${{ github.server_url }}
279
+ run: |
280
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
281
+ git config --global user.name "github-actions[bot]"
282
+ git config --global am.keepcr true
283
+ # Re-authenticate git with GitHub token
284
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
285
+ git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
286
+ echo "Git configured with standard GitHub Actions identity"
287
+ - name: Checkout PR branch
288
+ id: checkout-pr
289
+ if: |
290
+ github.event.pull_request || github.event.issue.pull_request
291
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
292
+ env:
293
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
294
+ with:
295
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
296
+ script: |
297
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
298
+ setupGlobals(core, github, context, exec, io);
299
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
300
+ await main();
301
+ - name: Install GitHub Copilot CLI
302
+ run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
303
+ env:
304
+ GH_HOST: github.com
305
+ - name: Install AWF binary
306
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.24.5
307
+ - name: Determine automatic lockdown mode for GitHub MCP Server
308
+ id: determine-automatic-lockdown
309
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
310
+ env:
311
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
312
+ GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
313
+ with:
314
+ script: |
315
+ const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
316
+ await determineAutomaticLockdown(github, context, core);
317
+ - name: Download container images
318
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
319
+ - name: Write Safe Outputs Config
320
+ run: |
321
+ mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
322
+ mkdir -p /tmp/gh-aw/safeoutputs
323
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
324
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
325
+ {"create_code_scanning_alert":{"max":0},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
326
+ GH_AW_SAFE_OUTPUTS_CONFIG_EOF
327
+ - name: Write Safe Outputs Tools
328
+ run: |
329
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
330
+ {
331
+ "description_suffixes": {},
332
+ "repo_params": {},
333
+ "dynamic_tools": []
334
+ }
335
+ GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF
336
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
337
+ {
338
+ "create_code_scanning_alert": {
339
+ "defaultMax": 40,
340
+ "fields": {
341
+ "column": {
342
+ "optionalPositiveInteger": true
343
+ },
344
+ "file": {
345
+ "required": true,
346
+ "type": "string",
347
+ "sanitize": true,
348
+ "maxLength": 512
349
+ },
350
+ "line": {
351
+ "required": true,
352
+ "positiveInteger": true
353
+ },
354
+ "message": {
355
+ "required": true,
356
+ "type": "string",
357
+ "sanitize": true,
358
+ "maxLength": 2048
359
+ },
360
+ "ruleIdSuffix": {
361
+ "type": "string",
362
+ "sanitize": true,
363
+ "maxLength": 128,
364
+ "pattern": "^[a-zA-Z0-9_-]+$",
365
+ "patternError": "must contain only alphanumeric characters, hyphens, and underscores"
366
+ },
367
+ "severity": {
368
+ "required": true,
369
+ "type": "string",
370
+ "enum": [
371
+ "error",
372
+ "warning",
373
+ "info",
374
+ "note"
375
+ ]
376
+ }
377
+ }
378
+ },
379
+ "missing_data": {
380
+ "defaultMax": 20,
381
+ "fields": {
382
+ "alternatives": {
383
+ "type": "string",
384
+ "sanitize": true,
385
+ "maxLength": 256
386
+ },
387
+ "context": {
388
+ "type": "string",
389
+ "sanitize": true,
390
+ "maxLength": 256
391
+ },
392
+ "data_type": {
393
+ "type": "string",
394
+ "sanitize": true,
395
+ "maxLength": 128
396
+ },
397
+ "reason": {
398
+ "type": "string",
399
+ "sanitize": true,
400
+ "maxLength": 256
401
+ }
402
+ }
403
+ },
404
+ "missing_tool": {
405
+ "defaultMax": 20,
406
+ "fields": {
407
+ "alternatives": {
408
+ "type": "string",
409
+ "sanitize": true,
410
+ "maxLength": 512
411
+ },
412
+ "reason": {
413
+ "required": true,
414
+ "type": "string",
415
+ "sanitize": true,
416
+ "maxLength": 256
417
+ },
418
+ "tool": {
419
+ "type": "string",
420
+ "sanitize": true,
421
+ "maxLength": 128
422
+ }
423
+ }
424
+ },
425
+ "noop": {
426
+ "defaultMax": 1,
427
+ "fields": {
428
+ "message": {
429
+ "required": true,
430
+ "type": "string",
431
+ "sanitize": true,
432
+ "maxLength": 65000
433
+ }
434
+ }
435
+ }
436
+ }
437
+ GH_AW_SAFE_OUTPUTS_VALIDATION_EOF
438
+ node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
439
+ - name: Generate Safe Outputs MCP Server Config
440
+ id: safe-outputs-config
441
+ run: |
442
+ # Generate a secure random API key (360 bits of entropy, 40+ chars)
443
+ # Mask immediately to prevent timing vulnerabilities
444
+ API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
445
+ echo "::add-mask::${API_KEY}"
446
+
447
+ PORT=3001
448
+
449
+ # Set outputs for next steps
450
+ {
451
+ echo "safe_outputs_api_key=${API_KEY}"
452
+ echo "safe_outputs_port=${PORT}"
453
+ } >> "$GITHUB_OUTPUT"
454
+
455
+ echo "Safe Outputs MCP server will run on port ${PORT}"
456
+
457
+ - name: Start Safe Outputs MCP HTTP Server
458
+ id: safe-outputs-start
459
+ env:
460
+ DEBUG: '*'
461
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
462
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
463
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
464
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
465
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
466
+ run: |
467
+ # Environment variables are set above to prevent template injection
468
+ export DEBUG
469
+ export GH_AW_SAFE_OUTPUTS_PORT
470
+ export GH_AW_SAFE_OUTPUTS_API_KEY
471
+ export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
472
+ export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
473
+ export GH_AW_MCP_LOG_DIR
474
+
475
+ bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
476
+
477
+ - name: Start MCP Gateway
478
+ id: start-mcp-gateway
479
+ env:
480
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
481
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
482
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
483
+ GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
484
+ GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
485
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
486
+ run: |
487
+ set -eo pipefail
488
+ mkdir -p /tmp/gh-aw/mcp-config
489
+
490
+ # Export gateway environment variables for MCP config and gateway script
491
+ export MCP_GATEWAY_PORT="80"
492
+ export MCP_GATEWAY_DOMAIN="host.docker.internal"
493
+ MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
494
+ echo "::add-mask::${MCP_GATEWAY_API_KEY}"
495
+ export MCP_GATEWAY_API_KEY
496
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
497
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
498
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
499
+ export DEBUG="*"
500
+
501
+ export GH_AW_ENGINE="copilot"
502
+ 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.1.20'
503
+
504
+ mkdir -p /home/runner/.copilot
505
+ cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
506
+ {
507
+ "mcpServers": {
508
+ "github": {
509
+ "type": "stdio",
510
+ "container": "ghcr.io/github/github-mcp-server:v0.32.0",
511
+ "env": {
512
+ "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
513
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
514
+ "GITHUB_READ_ONLY": "1",
515
+ "GITHUB_TOOLSETS": "repos,code_security"
516
+ },
517
+ "guard-policies": {
518
+ "allow-only": {
519
+ "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
520
+ "repos": "$GITHUB_MCP_GUARD_REPOS"
521
+ }
522
+ }
523
+ },
524
+ "safeoutputs": {
525
+ "type": "http",
526
+ "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
527
+ "headers": {
528
+ "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
529
+ },
530
+ "guard-policies": {
531
+ "write-sink": {
532
+ "accept": [
533
+ "*"
534
+ ]
535
+ }
536
+ }
537
+ }
538
+ },
539
+ "gateway": {
540
+ "port": $MCP_GATEWAY_PORT,
541
+ "domain": "${MCP_GATEWAY_DOMAIN}",
542
+ "apiKey": "${MCP_GATEWAY_API_KEY}",
543
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
544
+ }
545
+ }
546
+ GH_AW_MCP_CONFIG_EOF
547
+ - name: Download activation artifact
548
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
549
+ with:
550
+ name: activation
551
+ path: /tmp/gh-aw
552
+ - name: Clean git credentials
553
+ continue-on-error: true
554
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
555
+ - name: Execute GitHub Copilot CLI
556
+ id: agentic_execution
557
+ # Copilot CLI tool arguments (sorted):
558
+ timeout-minutes: 20
559
+ run: |
560
+ set -o pipefail
561
+ touch /tmp/gh-aw/agent-step-summary.md
562
+ # shellcheck disable=SC1003
563
+ sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --allow-domains "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,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,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.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" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
564
+ -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
565
+ env:
566
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
567
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
568
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
569
+ GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
570
+ GH_AW_PHASE: agent
571
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
572
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
573
+ GH_AW_VERSION: v0.62.5
574
+ GITHUB_API_URL: ${{ github.api_url }}
575
+ GITHUB_AW: true
576
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
577
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
578
+ GITHUB_REF_NAME: ${{ github.ref_name }}
579
+ GITHUB_SERVER_URL: ${{ github.server_url }}
580
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
581
+ GITHUB_WORKSPACE: ${{ github.workspace }}
582
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
583
+ GIT_AUTHOR_NAME: github-actions[bot]
584
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
585
+ GIT_COMMITTER_NAME: github-actions[bot]
586
+ XDG_CONFIG_HOME: /home/runner
587
+ - name: Detect inference access error
588
+ id: detect-inference-error
589
+ if: always()
590
+ continue-on-error: true
591
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
592
+ - name: Configure Git credentials
593
+ env:
594
+ REPO_NAME: ${{ github.repository }}
595
+ SERVER_URL: ${{ github.server_url }}
596
+ run: |
597
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
598
+ git config --global user.name "github-actions[bot]"
599
+ git config --global am.keepcr true
600
+ # Re-authenticate git with GitHub token
601
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
602
+ git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
603
+ echo "Git configured with standard GitHub Actions identity"
604
+ - name: Copy Copilot session state files to logs
605
+ if: always()
606
+ continue-on-error: true
607
+ run: |
608
+ # Copy Copilot session state files to logs folder for artifact collection
609
+ # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them
610
+ SESSION_STATE_DIR="$HOME/.copilot/session-state"
611
+ LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs"
612
+
613
+ if [ -d "$SESSION_STATE_DIR" ]; then
614
+ echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR"
615
+ mkdir -p "$LOGS_DIR"
616
+ cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true
617
+ echo "Session state files copied successfully"
618
+ else
619
+ echo "No session-state directory found at $SESSION_STATE_DIR"
620
+ fi
621
+ - name: Stop MCP Gateway
622
+ if: always()
623
+ continue-on-error: true
624
+ env:
625
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
626
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
627
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
628
+ run: |
629
+ bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
630
+ - name: Redact secrets in logs
631
+ if: always()
632
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
633
+ with:
634
+ script: |
635
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
636
+ setupGlobals(core, github, context, exec, io);
637
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
638
+ await main();
639
+ env:
640
+ GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
641
+ SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
642
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
643
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
644
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
645
+ - name: Append agent step summary
646
+ if: always()
647
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
648
+ - name: Copy Safe Outputs
649
+ if: always()
650
+ run: |
651
+ mkdir -p /tmp/gh-aw
652
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
653
+ - name: Ingest agent output
654
+ id: collect_output
655
+ if: always()
656
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
657
+ env:
658
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
659
+ GH_AW_ALLOWED_DOMAINS: "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,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,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.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"
660
+ GITHUB_SERVER_URL: ${{ github.server_url }}
661
+ GITHUB_API_URL: ${{ github.api_url }}
662
+ with:
663
+ script: |
664
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
665
+ setupGlobals(core, github, context, exec, io);
666
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
667
+ await main();
668
+ - name: Parse agent logs for step summary
669
+ if: always()
670
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
671
+ env:
672
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
673
+ with:
674
+ script: |
675
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
676
+ setupGlobals(core, github, context, exec, io);
677
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
678
+ await main();
679
+ - name: Parse MCP Gateway logs for step summary
680
+ if: always()
681
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
682
+ with:
683
+ script: |
684
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
685
+ setupGlobals(core, github, context, exec, io);
686
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
687
+ await main();
688
+ - name: Print firewall logs
689
+ if: always()
690
+ continue-on-error: true
691
+ env:
692
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
693
+ run: |
694
+ # Fix permissions on firewall logs so they can be uploaded as artifacts
695
+ # AWF runs with sudo, creating files owned by root
696
+ sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
697
+ # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
698
+ if command -v awf &> /dev/null; then
699
+ awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
700
+ else
701
+ echo 'AWF binary not installed, skipping firewall log summary'
702
+ fi
703
+ - name: Upload agent artifacts
704
+ if: always()
705
+ continue-on-error: true
706
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
707
+ with:
708
+ name: agent
709
+ path: |
710
+ /tmp/gh-aw/aw-prompts/prompt.txt
711
+ /tmp/gh-aw/sandbox/agent/logs/
712
+ /tmp/gh-aw/redacted-urls.log
713
+ /tmp/gh-aw/mcp-logs/
714
+ /tmp/gh-aw/sandbox/firewall/logs/
715
+ /tmp/gh-aw/agent-stdio.log
716
+ /tmp/gh-aw/agent/
717
+ /tmp/gh-aw/safeoutputs.jsonl
718
+ /tmp/gh-aw/agent_output.json
719
+ if-no-files-found: ignore
720
+
721
+ conclusion:
722
+ needs:
723
+ - activation
724
+ - agent
725
+ - safe_outputs
726
+ if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
727
+ runs-on: ubuntu-slim
728
+ permissions:
729
+ contents: read
730
+ security-events: write
731
+ concurrency:
732
+ group: "gh-aw-conclusion-daily-malicious-code-scan"
733
+ cancel-in-progress: false
734
+ outputs:
735
+ noop_message: ${{ steps.noop.outputs.noop_message }}
736
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
737
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
738
+ steps:
739
+ - name: Setup Scripts
740
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
741
+ with:
742
+ destination: ${{ runner.temp }}/gh-aw/actions
743
+ - name: Download agent output artifact
744
+ id: download-agent-output
745
+ continue-on-error: true
746
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
747
+ with:
748
+ name: agent
749
+ path: /tmp/gh-aw/
750
+ - name: Setup agent output environment variable
751
+ if: steps.download-agent-output.outcome == 'success'
752
+ run: |
753
+ mkdir -p /tmp/gh-aw/
754
+ find "/tmp/gh-aw/" -type f -print
755
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
756
+ - name: Process No-Op Messages
757
+ id: noop
758
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
759
+ env:
760
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
761
+ GH_AW_NOOP_MAX: "1"
762
+ GH_AW_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
763
+ GH_AW_TRACKER_ID: "malicious-code-scan"
764
+ with:
765
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
766
+ script: |
767
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
768
+ setupGlobals(core, github, context, exec, io);
769
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs');
770
+ await main();
771
+ - name: Record Missing Tool
772
+ id: missing_tool
773
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
774
+ env:
775
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
776
+ GH_AW_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
777
+ GH_AW_TRACKER_ID: "malicious-code-scan"
778
+ with:
779
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
780
+ script: |
781
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
782
+ setupGlobals(core, github, context, exec, io);
783
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
784
+ await main();
785
+ - name: Handle Agent Failure
786
+ id: handle_agent_failure
787
+ if: always()
788
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
789
+ env:
790
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
791
+ GH_AW_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
792
+ GH_AW_TRACKER_ID: "malicious-code-scan"
793
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
794
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
795
+ GH_AW_WORKFLOW_ID: "daily-malicious-code-scan"
796
+ GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
797
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
798
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
799
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
800
+ GH_AW_GROUP_REPORTS: "false"
801
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
802
+ GH_AW_TIMEOUT_MINUTES: "20"
803
+ with:
804
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
805
+ script: |
806
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
807
+ setupGlobals(core, github, context, exec, io);
808
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
809
+ await main();
810
+ - name: Handle No-Op Message
811
+ id: handle_noop_message
812
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
813
+ env:
814
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
815
+ GH_AW_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
816
+ GH_AW_TRACKER_ID: "malicious-code-scan"
817
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
818
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
819
+ GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }}
820
+ GH_AW_NOOP_REPORT_AS_ISSUE: "true"
821
+ with:
822
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
823
+ script: |
824
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
825
+ setupGlobals(core, github, context, exec, io);
826
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
827
+ await main();
828
+
829
+ safe_outputs:
830
+ needs: agent
831
+ if: (!cancelled()) && needs.agent.result != 'skipped'
832
+ runs-on: ubuntu-slim
833
+ permissions:
834
+ contents: read
835
+ security-events: write
836
+ timeout-minutes: 15
837
+ env:
838
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/daily-malicious-code-scan"
839
+ GH_AW_ENGINE_ID: "copilot"
840
+ GH_AW_TRACKER_ID: "malicious-code-scan"
841
+ GH_AW_WORKFLOW_ID: "daily-malicious-code-scan"
842
+ GH_AW_WORKFLOW_NAME: "Daily Malicious Code Scan Agent"
843
+ outputs:
844
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
845
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
846
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
847
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
848
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
849
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
850
+ steps:
851
+ - name: Setup Scripts
852
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
853
+ with:
854
+ destination: ${{ runner.temp }}/gh-aw/actions
855
+ - name: Download agent output artifact
856
+ id: download-agent-output
857
+ continue-on-error: true
858
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
859
+ with:
860
+ name: agent
861
+ path: /tmp/gh-aw/
862
+ - name: Setup agent output environment variable
863
+ if: steps.download-agent-output.outcome == 'success'
864
+ run: |
865
+ mkdir -p /tmp/gh-aw/
866
+ find "/tmp/gh-aw/" -type f -print
867
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
868
+ - name: Configure GH_HOST for enterprise compatibility
869
+ shell: bash
870
+ run: |
871
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
872
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
873
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
874
+ GH_HOST="${GH_HOST#http://}"
875
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
876
+ - name: Process Safe Outputs
877
+ id: process_safe_outputs
878
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
879
+ env:
880
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
881
+ GH_AW_ALLOWED_DOMAINS: "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,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,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.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"
882
+ GITHUB_SERVER_URL: ${{ github.server_url }}
883
+ GITHUB_API_URL: ${{ github.api_url }}
884
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_code_scanning_alert\":{\"driver\":\"Malicious Code Scanner\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}"
885
+ with:
886
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
887
+ script: |
888
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
889
+ setupGlobals(core, github, context, exec, io);
890
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
891
+ await main();
892
+ - name: Upload safe output items
893
+ if: always()
894
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
895
+ with:
896
+ name: safe-output-items
897
+ path: /tmp/gh-aw/safe-output-items.jsonl
898
+ if-no-files-found: ignore
899
+