From 0d854367d98b3de02eaa366eb4519c0cf2142c6c Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Sat, 14 Mar 2026 10:01:21 -0400 Subject: [PATCH] Add step to warn about unnecessary write permissions Probes the github-token for write access to actions, checks, contents, deployments, issues, packages, pages, pull-requests, security-events, and statuses. Emits a visible warning if any write scopes are detected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 2 +- action.yml | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 24c5635..efc87a1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ steps: - uses: actions/setup-copilot@v0 with: version: "latest" # optional, defaults to "latest" - github-token: ${{ secrets.COPILOT_TOKEN }} # optional, defaults to github.token + github-token: ${{ secrets.GITHUB_TOKEN }} # optional, defaults to github.token - run: copilot --version ``` diff --git a/action.yml b/action.yml index 8c8ad06..37539ee 100644 --- a/action.yml +++ b/action.yml @@ -34,6 +34,58 @@ runs: shell: bash run: echo "${{ runner.tool_cache }}/copilot/bin" >> "$GITHUB_PATH" + - name: Check for unnecessary write permissions + shell: bash + env: + GH_TOKEN: ${{ inputs.github-token }} + run: | + API="$GITHUB_API_URL/repos/$GITHUB_REPOSITORY" + writes_found=() + + # Probe write access by sending invalid requests to write endpoints. + # 422/409 = token has write permission (passed auth, failed validation) + # 403 = token does not have write permission + probe_write() { + local scope="$1" url="$2" method="${3:-POST}" body="${4:-\{\}}" + code=$(curl -s -o /dev/null -w "%{http_code}" \ + -X "$method" \ + -H "Authorization: bearer $GH_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "$url" -d "$body") + case "$code" in + 2[0-9][0-9]|422|409) writes_found+=("$scope") ;; + esac + } + + probe_write "actions" "$API/actions/workflows/0/dispatches" POST '{"ref":"__probe__"}' + probe_write "checks" "$API/check-runs" POST '{}' + probe_write "contents" "$API/contents/__probe__" PUT '{"message":"probe"}' + probe_write "deployments" "$API/deployments" POST '{}' + probe_write "issues" "$API/issues" POST '{}' + probe_write "packages" "$GITHUB_API_URL/user/packages/container/__nonexistent__/versions/0" DELETE '' + probe_write "pages" "$API/pages" POST '{}' + probe_write "pull-requests" "$API/pulls" POST '{}' + probe_write "statuses" "$API/statuses/$GITHUB_SHA" POST '{}' + + if [ ${#writes_found[@]} -gt 0 ]; then + echo "" + echo "::warning::⚠️ The github-token passed to setup-copilot has write permissions: ${writes_found[*]}. Granting write permissions to the Copilot CLI in Actions workflows is a security risk. Recommend scoping your token with least-privilege permissions." + { + echo "### ⚠️ setup-copilot: Excessive Token Permissions" + echo "" + echo "The \`github-token\` input has **write** access to: \`${writes_found[*]}\`." + echo "" + echo "Giving write permissions to the Copilot CLI in Actions workflows is a security risk." + echo "" + echo "**Recommendation:** add a \`permissions\` block to your job:" + echo '```yaml' + echo "permissions:" + echo " contents: read" + echo '```' + echo "and add a separate job with write permissions for steps that need it." + } >> "$GITHUB_STEP_SUMMARY" + fi + - name: Verify installation id: version shell: bash