From ea10f9558949ffc8908539b4f0cfd854fdf6c286 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Thu, 20 Aug 2026 23:10:16 -0700 Subject: [PATCH] refactor: use github-sts for Slack config token rotation --- .../setup-slack-config-token/action.yml | 19 +++++++++++++------ .github/sts/slack-config.sts.yaml | 2 +- .github/workflows/preview_deploy.yml | 4 +--- .github/workflows/preview_destroy.yml | 2 +- .github/workflows/preview_sweep.yml | 2 +- .github/workflows/production.yml | 2 +- .github/workflows/pull_request.yml | 2 +- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/actions/setup-slack-config-token/action.yml b/.github/actions/setup-slack-config-token/action.yml index d3b0d07..6cbd114 100644 --- a/.github/actions/setup-slack-config-token/action.yml +++ b/.github/actions/setup-slack-config-token/action.yml @@ -2,9 +2,6 @@ name: Setup Slack config token description: Setup a Slack app config token, rotating the repo refresh token when needed inputs: - github-token: - description: GitHub token with repository secrets write permission - required: false slack-config-refresh-token: description: Slack app config refresh token required: false @@ -20,11 +17,21 @@ outputs: runs: using: composite steps: + # Rotating the refresh token requires writing it back to repository + # secrets. The calling job must grant `id-token: write`; authorization is + # the slack-config trust policy in .github/sts/. + - name: Mint GitHub token + if: inputs.slack-config-access-token == '' && inputs.slack-config-refresh-token != '' + id: github_token + uses: tempoxyz/gh-actions/actions/github-sts@dd1014bf8244fded7a501e701cafab240a4f9f0e # main + with: + policy: slack-config + - name: Setup Slack config token id: token shell: bash env: - GH_TOKEN: ${{ inputs.github-token }} + GH_TOKEN: ${{ steps.github_token.outputs.token }} SLACK_CONFIG_REFRESH_TOKEN: ${{ inputs.slack-config-refresh-token }} SLACK_CONFIG_ACCESS_TOKEN: ${{ inputs.slack-config-access-token }} run: | @@ -38,11 +45,11 @@ runs: exit 1 fi if [ -z "$GH_TOKEN" ]; then - echo "Missing github-token. Rotating SLACK_CONFIG_REFRESH_TOKEN requires a GitHub token with repository secrets read/write permission." + echo "Missing GitHub token. Rotating SLACK_CONFIG_REFRESH_TOKEN requires a token with repository secrets read/write permission." exit 1 fi gh api "repos/${{ github.repository }}/actions/secrets/public-key" > /dev/null || { - echo "github-token cannot read repository Actions secrets. For a fine-grained PAT, grant Repository permissions > Secrets: Read and write. For a classic PAT, grant repo scope." + echo "GitHub token cannot read repository Actions secrets. Confirm the slack-config trust policy grants secrets: write and the STS app installation holds the repository Secrets permission." exit 1 } RESPONSE=$(curl -fsS -X POST https://slack.com/api/tooling.tokens.rotate \ diff --git a/.github/sts/slack-config.sts.yaml b/.github/sts/slack-config.sts.yaml index 0e9f36b..20e4e9d 100644 --- a/.github/sts/slack-config.sts.yaml +++ b/.github/sts/slack-config.sts.yaml @@ -2,7 +2,7 @@ # repository Actions secrets, so setup-slack-config-token can persist the # rotated SLACK_CONFIG_REFRESH_TOKEN after calling Slack's tooling.tokens.rotate # (rotation invalidates the previous refresh token, so the new one must be -# stored immediately). Replaces the SLACK_GH_TOKEN fine-grained PAT. +# stored immediately). # # refs/heads/main covers the production deploy and the scheduled preview sweep; # pull_request covers preview deploy/destroy runs. Jobs that reference a GitHub diff --git a/.github/workflows/preview_deploy.yml b/.github/workflows/preview_deploy.yml index 8e506d6..cdece7b 100644 --- a/.github/workflows/preview_deploy.yml +++ b/.github/workflows/preview_deploy.yml @@ -22,8 +22,6 @@ on: required: true FEE_PAYER_PRIVATE_KEY_TESTNET: required: true - SLACK_GH_TOKEN: - required: false SECRET_KEY: required: true SLACK_CONFIG_ACCESS_TOKEN: @@ -35,6 +33,7 @@ on: permissions: contents: read + id-token: write issues: write pull-requests: write @@ -94,7 +93,6 @@ jobs: id: slack_token uses: ./.github/actions/setup-slack-config-token with: - github-token: ${{ secrets.SLACK_GH_TOKEN }} slack-config-refresh-token: ${{ secrets.SLACK_CONFIG_REFRESH_TOKEN }} slack-config-access-token: ${{ secrets.SLACK_CONFIG_ACCESS_TOKEN }} diff --git a/.github/workflows/preview_destroy.yml b/.github/workflows/preview_destroy.yml index 18c2680..e1368b2 100644 --- a/.github/workflows/preview_destroy.yml +++ b/.github/workflows/preview_destroy.yml @@ -10,6 +10,7 @@ concurrency: permissions: contents: read + id-token: write issues: write pull-requests: write @@ -58,7 +59,6 @@ jobs: continue-on-error: true uses: ./.github/actions/setup-slack-config-token with: - github-token: ${{ secrets.SLACK_GH_TOKEN }} slack-config-refresh-token: ${{ secrets.SLACK_CONFIG_REFRESH_TOKEN }} slack-config-access-token: ${{ secrets.SLACK_CONFIG_ACCESS_TOKEN }} diff --git a/.github/workflows/preview_sweep.yml b/.github/workflows/preview_sweep.yml index 41fdda7..3b851d0 100644 --- a/.github/workflows/preview_sweep.yml +++ b/.github/workflows/preview_sweep.yml @@ -11,6 +11,7 @@ concurrency: permissions: contents: read + id-token: write issues: write pull-requests: write @@ -33,7 +34,6 @@ jobs: continue-on-error: true uses: ./.github/actions/setup-slack-config-token with: - github-token: ${{ secrets.SLACK_GH_TOKEN }} slack-config-refresh-token: ${{ secrets.SLACK_CONFIG_REFRESH_TOKEN }} slack-config-access-token: ${{ secrets.SLACK_CONFIG_ACCESS_TOKEN }} diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 1de6f7f..8325be7 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -95,6 +95,7 @@ jobs: cancel-in-progress: false permissions: contents: read + id-token: write steps: - name: Checkout uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 @@ -108,7 +109,6 @@ jobs: id: slack_token uses: ./.github/actions/setup-slack-config-token with: - github-token: ${{ secrets.SLACK_GH_TOKEN }} slack-config-refresh-token: ${{ secrets.SLACK_CONFIG_REFRESH_TOKEN }} slack-config-access-token: ${{ secrets.SLACK_CONFIG_ACCESS_TOKEN }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7e77550..e9546f6 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -25,6 +25,7 @@ jobs: needs: check permissions: contents: read + id-token: write issues: write pull-requests: write uses: ./.github/workflows/preview_deploy.yml @@ -40,5 +41,4 @@ jobs: SECRET_KEY: ${{ secrets.SECRET_KEY }} SLACK_CONFIG_ACCESS_TOKEN: ${{ secrets.SLACK_CONFIG_ACCESS_TOKEN }} SLACK_CONFIG_REFRESH_TOKEN: ${{ secrets.SLACK_CONFIG_REFRESH_TOKEN }} - SLACK_GH_TOKEN: ${{ secrets.SLACK_GH_TOKEN }} TEMPO_API_KEY: ${{ secrets.TEMPO_API_KEY }}