ci: use OIDC token-exchange for gh-pages deploys - #426
Open
OGPoyraz wants to merge 3 commits into
Open
Conversation
The gh-pages branch is protected by an org-wide ruleset that blocks direct pushes (requires a PR). The default GITHUB_TOKEN identity used by the gh-pages deploy step is not on that ruleset's bypass list, so every docs deploy has been failing with: remote: error: GH013: Repository rule violations found for refs/heads/gh-pages. remote: - Changes must be made through a pull request. Prior to #421, the workflow used personal_token: ${{ secrets.PUBLISH_DOCS_TOKEN }} instead of GITHUB_TOKEN, and that token's identity is allowed to bypass the ruleset (confirmed by successful gh-pages deploys through March 2025, well after the ruleset was created in May 2024). #421 switched to GITHUB_TOKEN as an intentional deviation from the module template, which is what broke this. Revert to PUBLISH_DOCS_TOKEN across the call chain, matching the current metamask-module-template: - publish-docs.yml: require PUBLISH_DOCS_TOKEN secret, use personal_token instead of github_token in the deploy step - publish-main-docs.yml / publish-rc-docs.yml: forward PUBLISH_DOCS_TOKEN to publish-docs.yml - publish-release.yml: require PUBLISH_DOCS_TOKEN secret, forward it to both gh-pages jobs - main.yml: forward PUBLISH_DOCS_TOKEN to publish-release.yml
Switch the gh-pages deploy from the static PUBLISH_DOCS_TOKEN secret to
the org's OIDC token-exchange service, matching the pattern already
used by MetaMask/snaps (publish-github-pages.yml).
Each job requests a short-lived contents:write token via
MetaMask/github-tools/.github/actions/get-token@v1, which exchanges
the job's signed OIDC identity token against ${{ vars.TOKEN_EXCHANGE_URL
}} (an org variable already inherited by this repo). That token is fed
into peaceiris/actions-gh-pages as personal_token, replacing the
static PUBLISH_DOCS_TOKEN secret used in the previous commit.
Benefits over the static-token approach:
- No long-lived secret stored in the github-pages environment.
- Token is minted per-run and expires in minutes.
- Nothing to rotate or accidentally leave stale (this is what caused
the original outage: PUBLISH_DOCS_TOKEN silently going unused for
months after #421 switched to GITHUB_TOKEN).
Changes:
- publish-docs.yml: add id-token: write permission, add "Get access
token" step using MetaMask/github-tools/.github/actions/get-token@v1,
use the exchanged token as personal_token instead of
secrets.PUBLISH_DOCS_TOKEN. Drop the now-unused PUBLISH_DOCS_TOKEN
secret declaration.
- publish-main-docs.yml / publish-rc-docs.yml: update caller
permissions to contents: read + id-token: write; drop the
PUBLISH_DOCS_TOKEN secret forwarding (no longer needed).
- publish-release.yml: same permission update for both gh-pages jobs;
drop the PUBLISH_DOCS_TOKEN secret requirement and forwarding.
- main.yml: drop the now-unused PUBLISH_DOCS_TOKEN forward to
publish-release.yml.
mcmire
approved these changes
Sep 1, 2026
This is something that we had to explicitly ask TechOps to do, so you may have to do the same. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Docs deploys to
gh-pageswere failing (GH013 ruleset rejection) because #421 switched the deploy token toGITHUB_TOKEN, which isn't allowed to bypass the org's push-protection ruleset ongh-pages.Fixes it by switching to OIDC token-exchange (same pattern as
MetaMask/snaps): each deploy job exchanges its OIDC identity for a short-livedcontents: writetoken viaMetaMask/github-tools/.github/actions/get-token@v1, instead of using a stored secret.Why this approach over reverting to the old
PUBLISH_DOCS_TOKENsecretThat secret still exists and would also fix the immediate issue, but it's been unused/unrotated since #421 — exactly the kind of staleness that let this regression go unnoticed.
Validation
actionlint v1.7.12: 0 errors on all changed filessnaps' working implementation exactly (permissions,get-tokenstep,personal_tokenwiring)vars.TOKEN_EXCHANGE_URLconfirmed already inherited by this repo at the org levelCaveat
Can't verify from the API whether the token-exchange service's server-side trust policy already allows
eth-sig-utilto bypass thegh-pagesruleset (it evidently does forsnaps). If not yet configured, theGet access tokenstep will fail with a clear error rather than a silent bad push.