Skip to content

Commit 42eecda

Browse files
authored
[no-ci] CI: stop trusting public read permission in restricted paths guard (#2105)
* [no-ci] CI: stop trusting public read permission in restricted paths guard Use the live pull request API for author association and treat collaborator read permission as untrusted because public repositories report read access for any GitHub user. * TEMPORARY: Switch to pull_request trigger for testing This commit is for testing the collaborator permission check and must be reverted before merge: 1. Changes trigger from pull_request_target to pull_request so this branch's workflow definition runs instead of main's. 2. Adds a dummy change to cuda_bindings/pyproject.toml to trigger the restricted-paths detection. REVERT THIS COMMIT BEFORE MERGE. Made-with: Cursor * TEMPORARY: Exclude write permission from trusted collaborators This commit is for testing the label-and-comment path and must be reverted before merge. It temporarily treats write access as untrusted so the current PR will exercise Needs-Restricted-Paths-Review assignment again. * Revert "TEMPORARY: Exclude write permission from trusted collaborators" This reverts commit 5226846. * Revert "TEMPORARY: Switch to pull_request trigger for testing" This reverts commit 5ede772.
1 parent 87ee176 commit 42eecda

1 file changed

Lines changed: 77 additions & 23 deletions

File tree

.github/workflows/restricted-paths-guard.yml

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ jobs:
2424
steps:
2525
- name: Inspect PR author signals for restricted paths
2626
env:
27-
# PR metadata inputs (author_association from event payload is
28-
# unreliable for fork PRs, so we query the collaborator API directly)
27+
# PR metadata inputs (the event payload's author_association can be
28+
# stale for fork PRs, so restricted-path PRs query the live PR API).
2929
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
3030
PR_NUMBER: ${{ github.event.pull_request.number }}
3131
PR_URL: ${{ github.event.pull_request.html_url }}
@@ -42,6 +42,8 @@ jobs:
4242
4343
COLLABORATOR_PERMISSION="not checked"
4444
COLLABORATOR_PERMISSION_API_ERROR=""
45+
AUTHOR_ASSOCIATION="not checked"
46+
AUTHOR_ASSOCIATION_API_ERROR=""
4547
4648
if ! MATCHING_RESTRICTED_PATHS=$(
4749
gh api \
@@ -68,6 +70,7 @@ jobs:
6870
echo ""
6971
echo "- **Error**: Failed to inspect the PR file list."
7072
echo "- **Author**: $PR_AUTHOR"
73+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
7174
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
7275
echo ""
7376
echo "Please update the PR at: $PR_URL"
@@ -88,6 +91,7 @@ jobs:
8891
echo ""
8992
echo "- **Error**: Failed to inspect the current PR labels."
9093
echo "- **Author**: $PR_AUTHOR"
94+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
9195
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
9296
echo ""
9397
echo "Please update the PR at: $PR_URL"
@@ -114,6 +118,13 @@ jobs:
114118
echo '```'
115119
}
116120
121+
write_author_association_api_error() {
122+
echo "- **Author association API error**:"
123+
echo '```text'
124+
printf '%s\n' "$AUTHOR_ASSOCIATION_API_ERROR"
125+
echo '```'
126+
}
127+
117128
post_review_label_comment() {
118129
local comment_body
119130
printf -v comment_body '%s\n\n%s\n' \
@@ -135,46 +146,87 @@ jobs:
135146
COMMENT_ACTION="not needed"
136147
137148
if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then
138-
# Distinguish a legitimate 404 "not a collaborator" response from
139-
# actual API failures. The former is an expected untrusted case;
140-
# the latter fails the workflow so it can be rerun later.
141-
if COLLABORATOR_PERMISSION_RESPONSE=$(
142-
gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" \
143-
--jq '.permission' 2>&1
149+
if AUTHOR_ASSOCIATION_RESPONSE=$(
150+
gh api "repos/$REPO/pulls/$PR_NUMBER" \
151+
--jq '.author_association // "NONE"' 2>&1
144152
); then
145-
COLLABORATOR_PERMISSION="$COLLABORATOR_PERMISSION_RESPONSE"
146-
elif [[ "$COLLABORATOR_PERMISSION_RESPONSE" == *"(HTTP 404)"* ]]; then
147-
COLLABORATOR_PERMISSION="none"
153+
AUTHOR_ASSOCIATION="$AUTHOR_ASSOCIATION_RESPONSE"
148154
else
149-
COLLABORATOR_PERMISSION="unknown"
150-
COLLABORATOR_PERMISSION_API_ERROR="$COLLABORATOR_PERMISSION_RESPONSE"
151-
echo "::error::Failed to inspect collaborator permission for $PR_AUTHOR."
155+
AUTHOR_ASSOCIATION="unknown"
156+
AUTHOR_ASSOCIATION_API_ERROR="$AUTHOR_ASSOCIATION_RESPONSE"
157+
echo "::error::Failed to inspect live author association for PR #$PR_NUMBER."
152158
{
153159
echo "## Restricted Paths Guard Failed"
154160
echo ""
155-
echo "- **Error**: Failed to inspect collaborator permission."
161+
echo "- **Error**: Failed to inspect live author association."
156162
echo "- **Author**: $PR_AUTHOR"
157-
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
163+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
158164
echo ""
159165
write_matching_restricted_paths
160166
echo ""
161-
write_collaborator_permission_api_error
167+
write_author_association_api_error
162168
echo ""
163-
echo "Please retry this workflow. If the failure persists, inspect the collaborator permission API error above."
169+
echo "Please retry this workflow. If the failure persists, inspect the author association API error above."
164170
} >> "$GITHUB_STEP_SUMMARY"
165171
exit 1
166172
fi
167173
168-
case "$COLLABORATOR_PERMISSION" in
169-
admin|maintain|write|triage|read)
174+
case "$AUTHOR_ASSOCIATION" in
175+
MEMBER|OWNER)
170176
HAS_TRUSTED_SIGNAL=true
171-
LABEL_ACTION="not needed (collaborator permission is a trusted signal)"
172-
TRUSTED_SIGNALS="collaborator_permission:$COLLABORATOR_PERMISSION"
177+
LABEL_ACTION="not needed (live author association is a trusted signal)"
178+
TRUSTED_SIGNALS="author_association:$AUTHOR_ASSOCIATION"
173179
;;
174180
*)
175-
# none: not a trusted signal
181+
# COLLABORATOR can still be too broad for this policy; use the
182+
# collaborator permission API below for repo-level trust.
176183
;;
177184
esac
185+
186+
# Distinguish a legitimate 404 "not a collaborator" response from
187+
# actual API failures. The former is an expected untrusted case;
188+
# the latter fails the workflow so it can be rerun later.
189+
if [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then
190+
if COLLABORATOR_PERMISSION_RESPONSE=$(
191+
gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" \
192+
--jq '.permission' 2>&1
193+
); then
194+
COLLABORATOR_PERMISSION="$COLLABORATOR_PERMISSION_RESPONSE"
195+
elif [[ "$COLLABORATOR_PERMISSION_RESPONSE" == *"(HTTP 404)"* ]]; then
196+
COLLABORATOR_PERMISSION="none"
197+
else
198+
COLLABORATOR_PERMISSION="unknown"
199+
COLLABORATOR_PERMISSION_API_ERROR="$COLLABORATOR_PERMISSION_RESPONSE"
200+
echo "::error::Failed to inspect collaborator permission for $PR_AUTHOR."
201+
{
202+
echo "## Restricted Paths Guard Failed"
203+
echo ""
204+
echo "- **Error**: Failed to inspect collaborator permission."
205+
echo "- **Author**: $PR_AUTHOR"
206+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
207+
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
208+
echo ""
209+
write_matching_restricted_paths
210+
echo ""
211+
write_collaborator_permission_api_error
212+
echo ""
213+
echo "Please retry this workflow. If the failure persists, inspect the collaborator permission API error above."
214+
} >> "$GITHUB_STEP_SUMMARY"
215+
exit 1
216+
fi
217+
218+
case "$COLLABORATOR_PERMISSION" in
219+
admin|maintain|write|triage)
220+
HAS_TRUSTED_SIGNAL=true
221+
LABEL_ACTION="not needed (collaborator permission is a trusted signal)"
222+
TRUSTED_SIGNALS="collaborator_permission:$COLLABORATOR_PERMISSION"
223+
;;
224+
*)
225+
# read or none: not a trusted signal. In a public repo, read
226+
# can be the effective permission for any GitHub user.
227+
;;
228+
esac
229+
fi
178230
fi
179231
180232
NEEDS_REVIEW_LABEL=false
@@ -197,6 +249,7 @@ jobs:
197249
echo ""
198250
echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label."
199251
echo "- **Author**: $PR_AUTHOR"
252+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
200253
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
201254
echo ""
202255
write_matching_restricted_paths
@@ -216,6 +269,7 @@ jobs:
216269
echo "## Restricted Paths Guard Completed"
217270
echo ""
218271
echo "- **Author**: $PR_AUTHOR"
272+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
219273
echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
220274
echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS"
221275
echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`"

0 commit comments

Comments
 (0)