From 27a81e0f14b7ca72192bd118cd98e37b77a919c9 Mon Sep 17 00:00:00 2001 From: Jakub Domeracki Date: Tue, 25 Aug 2026 13:59:29 +0000 Subject: [PATCH 1/2] ci: use dedicated release App token to publish releases The Publish release step runs gh release create, which creates the v$version tag in addition to the release. The active tag-create protection ruleset blocks github-actions[bot] (the default GITHUB_TOKEN), producing HTTP 403: Resource not accessible by integration. Mint an installation token from a dedicated release GitHub App (RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY) and use it only for the Publish release step. The App is added to the ruleset bypass list as an Integration actor. Refs coder/security-automation#297 --- .github/workflows/release.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a5ca3ec3b555c..9dcbd4b5ce494 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -541,6 +541,18 @@ jobs: gcloud storage cp "./build/${detached_signature}" "gs://releases.coder.com/coder-cli/${version}/${cli_name}.asc" done + # Mint a short-lived installation token from the dedicated release + # GitHub App. The default GITHUB_TOKEN (github-actions[bot]) cannot be + # added to the "Auto-imported tag create protections" ruleset bypass + # list, so `gh release create` fails to create the tag with a 403. The + # App is added to that ruleset's bypass list as an Integration actor. + - name: Generate release App token + id: release_app_token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ vars.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + - name: Publish release run: | set -euo pipefail @@ -579,7 +591,9 @@ jobs: --release-notes-file "$CODER_RELEASE_NOTES_FILE" \ "${files[@]}" env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Use the dedicated release App token (github-actions[bot] is blocked + # from creating tags by the tag-create protection ruleset). + GITHUB_TOKEN: ${{ steps.release_app_token.outputs.token }} CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }} VERSION: ${{ steps.version.outputs.version }} CREATED_LATEST_TAG: ${{ steps.build_docker.outputs.created_latest_tag }} From 7e874a5ce5c44b72a590d467a6a145ac3c70f0f0 Mon Sep 17 00:00:00 2001 From: Jakub Domeracki Date: Tue, 25 Aug 2026 14:10:16 +0000 Subject: [PATCH 2/2] ci: store RELEASE_APP_ID as a secret instead of a variable --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9dcbd4b5ce494..35111471226ee 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -550,7 +550,7 @@ jobs: id: release_app_token uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: - app-id: ${{ vars.RELEASE_APP_ID }} + app-id: ${{ secrets.RELEASE_APP_ID }} private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} - name: Publish release