Skip to content

Commit 0a062f0

Browse files
authored
Require a maintainer to add a label on PRs from forks (#342)
Prevent untrusted code execution by requiring manual approval via safe-to-update label for fork PRs. Fork PRs will be skipped unless a maintainer adds the label after security review. Same-repository PRs continue to run automatically. Fixes: #341
1 parent d64c892 commit 0a062f0

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

.github/workflows/update-tools.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,79 @@ permissions:
1717
pull-requests: write
1818

1919
jobs:
20+
# Security check for fork PRs - prevents untrusted code execution with write permissions
21+
security-check:
22+
name: Security Check for Fork PRs
23+
runs-on: ubuntu-latest
24+
if: github.event_name == 'pull_request'
25+
outputs:
26+
is-fork: ${{ steps.check-fork.outputs.is-fork }}
27+
has-label: ${{ steps.check-label.outputs.has-label }}
28+
should-run: ${{ steps.check-fork.outputs.should-run }}
29+
steps:
30+
- name: Check if PR is from a fork
31+
id: check-fork
32+
run: |
33+
# Get PR details from GitHub API
34+
PR_DATA=$(gh pr view ${{ github.event.pull_request.number }} --json isCrossRepository,labels --repo ${{ github.repository }})
35+
36+
IS_FORK=$(echo "$PR_DATA" | jq -r '.isCrossRepository')
37+
echo "is-fork=$IS_FORK" >> $GITHUB_OUTPUT
38+
39+
if [ "$IS_FORK" = "false" ]; then
40+
echo "PR is from the same repository - workflow will run automatically"
41+
echo "should-run=true" >> $GITHUB_OUTPUT
42+
else
43+
echo "PR is from a fork - checking for 'safe-to-update' label"
44+
45+
# Check if PR has the safe-to-update label
46+
HAS_LABEL=$(echo "$PR_DATA" | jq -r '.labels | map(select(.name == "safe-to-update")) | length > 0')
47+
48+
if [ "$HAS_LABEL" = "true" ]; then
49+
echo "PR has 'safe-to-update' label - workflow will run"
50+
echo "should-run=true" >> $GITHUB_OUTPUT
51+
else
52+
echo "PR does not have 'safe-to-update' label - workflow will be skipped"
53+
echo "should-run=false" >> $GITHUB_OUTPUT
54+
fi
55+
fi
56+
env:
57+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
59+
- name: Check label status
60+
id: check-label
61+
if: steps.check-fork.outputs.is-fork == 'true'
62+
run: |
63+
PR_DATA=$(gh pr view ${{ github.event.pull_request.number }} --json labels --repo ${{ github.repository }})
64+
HAS_LABEL=$(echo "$PR_DATA" | jq -r '.labels | map(select(.name == "safe-to-update")) | length > 0')
65+
echo "has-label=$HAS_LABEL" >> $GITHUB_OUTPUT
66+
env:
67+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68+
69+
- name: Post instructions for fork PRs without label
70+
if: steps.check-fork.outputs.is-fork == 'true' && steps.check-fork.outputs.should-run == 'false'
71+
uses: peter-evans/create-or-update-comment@v5
72+
with:
73+
issue-number: ${{ github.event.pull_request.number }}
74+
body: |
75+
## Security Notice: Fork PR Tool Update Workflow
76+
77+
This PR is from a forked repository. For security reasons, the automatic tool list update workflow requires a maintainer to add the `safe-to-update` label before it will run.
78+
79+
A maintainer will review this PR and add the label if appropriate. The workflow will then automatically update the tool lists.
80+
81+
---
82+
83+
**Why is this needed?** This workflow executes code and connects to MCP servers specified in spec files. To prevent potential security issues, we require manual verification for fork PRs.
84+
2085
detect-changes:
2186
name: Detect Changed Specs
2287
runs-on: ubuntu-latest
88+
needs: [security-check]
89+
if: |
90+
always() &&
91+
(github.event_name == 'workflow_dispatch' ||
92+
(github.event_name == 'pull_request' && needs.security-check.outputs.should-run == 'true'))
2393
outputs:
2494
matrix: ${{ steps.set-matrix.outputs.matrix }}
2595
has-changes: ${{ steps.set-matrix.outputs.has-changes }}

0 commit comments

Comments
 (0)