Skip to content

Commit d3acad1

Browse files
TalZaccaiCopilot
andauthored
ci(security): push with default GITHUB_TOKEN, not App token (#361)
The fix-dependabot-alerts workflow was using the GitHub App token for git push, which required granting the App `Contents: write` at the installation level. That permission wasn't (and didn't need to be) granted, causing the scheduled run to 403 at `git push` with 'Permission to microsoft/TypeChat.git denied to typeagent-bot[bot]'. Match the TypeAgent workflow pattern instead: keep `persist-credentials: false` on checkout (so the token isn't reachable from untrusted `npm` scripts during the verify phase), but at the very end of the job re-inject the workflow's own GITHUB_TOKEN — already scoped to `contents: write` via the workflow-level `permissions:` block — for the git push. The App token is now used only where it must be: - `gh api dependabot/alerts` (the default GITHUB_TOKEN can't reach this endpoint) - `gh pr create` / labels / closing superseded PRs (so the PR identity is the bot, not github-actions) Verified end-to-end: a manual workflow_dispatch run against a temp branch passed git push and opened #360. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 246f677 commit d3acad1

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

.github/workflows/fix-dependabot-alerts.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,17 @@ jobs:
162162
- name: Create pull request
163163
if: ${{ steps.fix.outputs.changes == 'true' && steps.build.outputs.build_ok == 'true' }}
164164
env:
165+
# GH_TOKEN is the App token — used by the ``gh`` CLI for
166+
# ``gh pr create`` / labelling / closing superseded PRs so the
167+
# PR appears under the bot's identity.
165168
GH_TOKEN: ${{ steps.app-token-pr.outputs.token }}
169+
# GIT_PUSH_TOKEN is the workflow's default GITHUB_TOKEN, scoped
170+
# via the workflow-level ``permissions: contents: write`` block.
171+
# We use it only at the very end, after all untrusted ``npm``
172+
# scripts have finished running, to avoid persisting any push
173+
# credential in .git/config (where dependency build scripts
174+
# could read it).
175+
GIT_PUSH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
166176
run: |
167177
BRANCH="automated/fix-dependabot-alerts-$(date +%Y%m%d)-${{ github.run_number }}"
168178
git config user.name "github-actions[bot]"
@@ -188,10 +198,12 @@ jobs:
188198
Unfixable: ${{ steps.fix.outputs.unfixable_count }} package(s)
189199
190200
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
191-
# Push using the App token explicitly — we disabled
192-
# ``persist-credentials`` on checkout, so .git/config has no
193-
# creds to fall back on.
194-
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
201+
# Push using the workflow's default GITHUB_TOKEN (scoped to
202+
# contents:write at the workflow level). Configured here, not
203+
# via actions/checkout's ``persist-credentials``, so the token
204+
# isn't reachable from the npm install / build / test phase
205+
# earlier in the job.
206+
git remote set-url origin "https://x-access-token:${GIT_PUSH_TOKEN}@github.com/${{ github.repository }}.git"
195207
git push origin "$BRANCH"
196208
197209
APPLIED="${{ steps.fix.outputs.applied_packages }}"

0 commit comments

Comments
 (0)