Repository navigation
112 lines (104 loc) · 4.41 KB
/
Copy pathfuzzer-issue-autofix.yml
File metadata and controls
112 lines (104 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
name: Fuzzer Issue Autofix
# Run the Fuzzer Fix Automation when an issue gets the "fuzzer" label. This
# covers issues that people file or label manually. Issues that the fuzz
# pipeline files do not start this workflow, because the pipeline uses
# GITHUB_TOKEN and events from that token do not trigger workflows. The
# attempt-fix-* jobs in fuzz.yml fix those issues instead.
#
# The trigger is "labeled" only. An issue that is opened with labels also sends
# one "labeled" event for each label, so an "opened" trigger only adds a second
# run for each new issue. GitHub cannot filter issue events by label name, so
# each label event on any issue still starts a run that the gate job skips.
#
# A gate job runs first, WITHOUT the claude-automation environment, so untrusted
# triggers are rejected before the write-capable App token is minted. The
# "fuzzer" label alone is not a trust boundary: applying a label only needs
# triage permission, which is below write.
concurrency:
# Keyed on the issue so repeat triggers for the same issue collapse into a
# single in-flight fix attempt.
group: fuzzer-fix-${{ github.event.issue.number }}
cancel-in-progress: true
on:
issues:
types: [labeled]
jobs:
gate:
name: "Gate Fuzzer Autofix Trigger"
# Cheap pre-filter: only fuzzer-labeled issues are in scope. The trust
# decision (who triggered this, is the content trusted) is made in the
# script below, before any environment or write-capable token is attached.
if: github.event.label.name == 'fuzzer'
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
outputs:
should_run: ${{ steps.gate.outputs.should_run }}
reason: ${{ steps.gate.outputs.reason }}
steps:
- name: Decide whether this trigger is trusted
id: gate
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
# Optional extra trusted report-author login (e.g. a dedicated
# fuzz-report App bot). github-actions[bot] is always trusted.
EXTRA_TRUSTED_AUTHOR: ${{ vars.FUZZ_REPORT_BOT_LOGIN }}
with:
github-token: ${{ github.token }}
script: |
const issue = context.payload.issue ?? {};
const sender = context.payload.sender?.login ?? '';
const author = issue.user?.login ?? '';
// Issues authored by the trusted fuzz-report bot carry trusted
// content, so a label event on them is safe regardless of who
// applied the label.
const trustedAuthors = ['github-actions[bot]'];
if (process.env.EXTRA_TRUSTED_AUTHOR) {
trustedAuthors.push(process.env.EXTRA_TRUSTED_AUTHOR);
}
let reason = '';
if (!trustedAuthors.includes(author)) {
// Otherwise the human who opened/labeled the issue must have
// write-or-higher access. Triage can apply labels but is not
// trusted to run write-capable automation on attacker-controlled
// issue content.
let permission = 'none';
try {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: sender,
});
permission = data.permission;
} catch (error) {
if (error.status !== 404) {
throw error;
}
}
if (!['admin', 'maintain', 'write'].includes(permission)) {
reason = 'actor_lacks_write';
}
}
core.setOutput('should_run', reason ? 'false' : 'true');
core.setOutput('reason', reason || 'allowed');
core.notice(
`fuzzer autofix gate: ${reason || 'allowed'} ` +
`(sender=${sender}, author=${author})`
);
autofix:
name: "Autofix Fuzzer Issue"
needs: gate
if: needs.gate.outputs.should_run == 'true'
permissions:
# actions: read is required so the reusable workflow can download the
# crash artifact via `gh run download`.
actions: read
contents: write
issues: write
pull-requests: write
id-token: write
uses: ./.github/workflows/fuzzer-fix-automation.yml
with:
issue_number: ${{ github.event.issue.number }}
secrets: inherit