From e3c1763e70a2f0c7005520393bf52e9e4c1225c1 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Tue, 2 Jun 2026 12:08:11 -0700 Subject: [PATCH 1/3] diag: print App token permissions before git push (TEMP) Add a temporary diagnostic step that prints what the refreshed App token can see on the repo, the install's repo selection, and a git/refs read probe, so we can see exactly why git push 403s. To be reverted once the underlying permission/install issue is fixed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/fix-dependabot-alerts.yml | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/fix-dependabot-alerts.yml b/.github/workflows/fix-dependabot-alerts.yml index 9decf913..8c2c7c11 100644 --- a/.github/workflows/fix-dependabot-alerts.yml +++ b/.github/workflows/fix-dependabot-alerts.yml @@ -159,6 +159,23 @@ jobs: app-id: ${{ vars.DEPENDABOT_APP_ID }} private-key: ${{ secrets.DEPENDABOT_APP_PRIVATE_KEY }} + - name: Diagnose App token (TEMP) + if: ${{ steps.fix.outputs.changes == 'true' && steps.build.outputs.build_ok == 'true' }} + env: + GH_TOKEN: ${{ steps.app-token-pr.outputs.token }} + run: | + set +e + echo "=== Token permissions on ${{ github.repository }} ===" + gh api "repos/${{ github.repository }}" --jq '.permissions' + echo "(exit=$?)" + echo "=== Installation repos (count + first 5) ===" + gh api /installation/repositories --jq '{total: .total_count, sample: [.repositories[].full_name][:5]}' + echo "(exit=$?)" + echo "=== Git refs read probe (same install-scope as push) ===" + gh api "repos/${{ github.repository }}/git/refs/heads/main" --jq '.object.sha' + echo "(exit=$?)" + echo "=== End diag ===" + - name: Create pull request if: ${{ steps.fix.outputs.changes == 'true' && steps.build.outputs.build_ok == 'true' }} env: @@ -191,6 +208,11 @@ jobs: # Push using the App token explicitly — we disabled # ``persist-credentials`` on checkout, so .git/config has no # creds to fall back on. + # TEMP DIAG: print the effective App-token permissions on this + # repo and the install's repo selection before attempting the + # push. Remove once the permission issue is resolved. + echo "(see Diagnose App token step output above for permissions)" + git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" git push origin "$BRANCH" From f355a97bfdb6b6264c0dd8dd66602cb30c8a2ffd Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Tue, 2 Jun 2026 12:26:45 -0700 Subject: [PATCH 2/3] ci(security): push with default GITHUB_TOKEN, not App token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match the TypeAgent workflow pattern: keep persist-credentials: false on checkout (so the token isn't reachable from 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 at the workflow level) for the git push. The App token is now used only where it must be — gh api dependabot/ alerts (which the default token can't reach) and gh pr create (so the PR identity is the bot, not github-actions). Means the App no longer needs Contents permission at all. Also removes the temporary diagnostic step that confirmed the permission issue. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/fix-dependabot-alerts.yml | 42 ++++++++------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/.github/workflows/fix-dependabot-alerts.yml b/.github/workflows/fix-dependabot-alerts.yml index 8c2c7c11..ade460f4 100644 --- a/.github/workflows/fix-dependabot-alerts.yml +++ b/.github/workflows/fix-dependabot-alerts.yml @@ -159,27 +159,20 @@ jobs: app-id: ${{ vars.DEPENDABOT_APP_ID }} private-key: ${{ secrets.DEPENDABOT_APP_PRIVATE_KEY }} - - name: Diagnose App token (TEMP) - if: ${{ steps.fix.outputs.changes == 'true' && steps.build.outputs.build_ok == 'true' }} - env: - GH_TOKEN: ${{ steps.app-token-pr.outputs.token }} - run: | - set +e - echo "=== Token permissions on ${{ github.repository }} ===" - gh api "repos/${{ github.repository }}" --jq '.permissions' - echo "(exit=$?)" - echo "=== Installation repos (count + first 5) ===" - gh api /installation/repositories --jq '{total: .total_count, sample: [.repositories[].full_name][:5]}' - echo "(exit=$?)" - echo "=== Git refs read probe (same install-scope as push) ===" - gh api "repos/${{ github.repository }}/git/refs/heads/main" --jq '.object.sha' - echo "(exit=$?)" - echo "=== End diag ===" - - name: Create pull request if: ${{ steps.fix.outputs.changes == 'true' && steps.build.outputs.build_ok == 'true' }} env: + # GH_TOKEN is the App token — used by the ``gh`` CLI for + # ``gh pr create`` / labelling / closing superseded PRs so the + # PR appears under the bot's identity. GH_TOKEN: ${{ steps.app-token-pr.outputs.token }} + # GIT_PUSH_TOKEN is the workflow's default GITHUB_TOKEN, scoped + # via the workflow-level ``permissions: contents: write`` block. + # We use it only at the very end, after all untrusted ``npm`` + # scripts have finished running, to avoid persisting any push + # credential in .git/config (where dependency build scripts + # could read it). + GIT_PUSH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | BRANCH="automated/fix-dependabot-alerts-$(date +%Y%m%d)-${{ github.run_number }}" git config user.name "github-actions[bot]" @@ -205,15 +198,12 @@ jobs: Unfixable: ${{ steps.fix.outputs.unfixable_count }} package(s) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" - # Push using the App token explicitly — we disabled - # ``persist-credentials`` on checkout, so .git/config has no - # creds to fall back on. - # TEMP DIAG: print the effective App-token permissions on this - # repo and the install's repo selection before attempting the - # push. Remove once the permission issue is resolved. - echo "(see Diagnose App token step output above for permissions)" - - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" + # Push using the workflow's default GITHUB_TOKEN (scoped to + # contents:write at the workflow level). Configured here, not + # via actions/checkout's ``persist-credentials``, so the token + # isn't reachable from the npm install / build / test phase + # earlier in the job. + git remote set-url origin "https://x-access-token:${GIT_PUSH_TOKEN}@github.com/${{ github.repository }}.git" git push origin "$BRANCH" APPLIED="${{ steps.fix.outputs.applied_packages }}" From 73e1c970fab41f7a714da3a1599714e343d19f59 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 19:30:12 +0000 Subject: [PATCH 3/3] fix: remediate Dependabot security alerts Automated by fix-dependabot-alerts workflow. Applied:minimatch Rolled back: Unfixable: 3 package(s) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- typescript/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 9504d04f..85dd9ba4 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1961,9 +1961,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz", - "integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "devOptional": true, "license": "ISC", "dependencies": {