From 5b001ad737955920e3657cb7e0b582fc273abd06 Mon Sep 17 00:00:00 2001 From: notgitika Date: Mon, 20 Jul 2026 17:18:46 -0400 Subject: [PATCH] fix(ci): scope and revoke E2E GitHub App tokens --- .github/workflows/e2e-tests-full.yml | 50 ++++++++++++++++++++++++---- .github/workflows/e2e-tests.yml | 37 ++++++++++++++++++-- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/.github/workflows/e2e-tests-full.yml b/.github/workflows/e2e-tests-full.yml index c3ec90c2c..cced4cd71 100644 --- a/.github/workflows/e2e-tests-full.yml +++ b/.github/workflows/e2e-tests-full.yml @@ -19,13 +19,15 @@ concurrency: cancel-in-progress: false permissions: - id-token: write # OIDC — lets GitHub assume an AWS IAM role via short-lived token (no stored keys) contents: read jobs: e2e: runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} environment: e2e-testing + permissions: + id-token: write # OIDC - lets this job assume the E2E AWS role. + contents: read timeout-minutes: 60 strategy: fail-fast: false @@ -61,14 +63,30 @@ jobs: - run: npm ci - name: Build CLI run: npm run build - - name: Generate GitHub App Token + - name: Resolve private CDK repository + id: cdk-repo + env: + CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + run: | + owner="${CDK_REPO%%/*}" + repository="${CDK_REPO#*/}" + if [[ -z "$owner" || -z "$repository" || "$repository" == */* || "$owner/$repository" != "$CDK_REPO" ]]; then + echo "::error::CDK_REPO_NAME must use the owner/repository format" + exit 1 + fi + echo "owner=$owner" >> "$GITHUB_OUTPUT" + echo "repository=$repository" >> "$GITHUB_OUTPUT" + - name: Generate repository-scoped GitHub App token id: app-token uses: actions/create-github-app-token@v3 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: aws - - name: Build CDK package + owner: ${{ steps.cdk-repo.outputs.owner }} + repositories: ${{ steps.cdk-repo.outputs.repository }} + permission-contents: read + skip-token-revoke: true + - name: Clone CDK repository run: | if [ -n "${{ inputs.cdk_branch }}" ] && [ "${{ inputs.cdk_branch }}" != "main" ]; then CDK_BRANCH="${{ inputs.cdk_branch }}" @@ -84,14 +102,29 @@ jobs: fi echo "Using CDK branch: $CDK_BRANCH" git clone --depth 1 --branch "$CDK_BRANCH" "https://x-access-token:${CDK_REPO_TOKEN}@github.com/${CDK_REPO}.git" /tmp/cdk-repo + git -C /tmp/cdk-repo remote remove origin + env: + CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} + CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + - name: Revoke GitHub App token + if: always() && steps.app-token.outputs.token != '' + env: + CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} + GITHUB_API_URL: ${{ github.api_url }} + run: | + curl --fail-with-body --silent --show-error \ + --request DELETE \ + --header "Accept: application/vnd.github+json" \ + --header "Authorization: Bearer ${CDK_REPO_TOKEN}" \ + --header "X-GitHub-Api-Version: 2022-11-28" \ + "${GITHUB_API_URL}/installation/token" + - name: Build CDK package + run: | cd /tmp/cdk-repo npm ci npm run build TARBALL=$(npm pack --pack-destination "$RUNNER_TEMP" | tail -1) echo "CDK_TARBALL=$RUNNER_TEMP/$TARBALL" >> "$GITHUB_ENV" - env: - CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} - CDK_REPO: ${{ secrets.CDK_REPO_NAME }} - name: Install CLI globally run: npm install -g "$(npm pack | tail -1)" - name: Run E2E tests (shard ${{ matrix.shard }}) @@ -119,6 +152,9 @@ jobs: # OS where --with-deps works. See #1715. runs-on: ubuntu-latest environment: e2e-testing + permissions: + id-token: write # OIDC - lets this job assume the E2E AWS role. + contents: read timeout-minutes: 30 steps: - uses: actions/checkout@v7 diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 33f16bdc1..3d4f849ba 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -35,7 +35,6 @@ concurrency: cancel-in-progress: true permissions: - id-token: write # OIDC — lets GitHub assume an AWS IAM role via short-lived token (no stored keys) contents: read jobs: @@ -72,6 +71,9 @@ jobs: e2e: needs: authorize if: needs.authorize.outputs.is_authorized == 'true' + permissions: + id-token: write # OIDC - lets this job assume the E2E AWS role. + contents: read # Run on our AWS CodeBuild-hosted runner instead of a GitHub-hosted runner. # GitHub-hosted runner IPs rotate through shared pools whose reputation trips # the service WAF (403s before the request reaches service code); dedicated @@ -117,23 +119,52 @@ jobs: E2E,${{ secrets.E2E_SECRET_ARN }} parse-json-secrets: true - - name: Generate GitHub App Token + - name: Resolve private CDK repository + id: cdk-repo + env: + CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + run: | + owner="${CDK_REPO%%/*}" + repository="${CDK_REPO#*/}" + if [[ -z "$owner" || -z "$repository" || "$repository" == */* || "$owner/$repository" != "$CDK_REPO" ]]; then + echo "::error::CDK_REPO_NAME must use the owner/repository format" + exit 1 + fi + echo "owner=$owner" >> "$GITHUB_OUTPUT" + echo "repository=$repository" >> "$GITHUB_OUTPUT" + - name: Generate repository-scoped GitHub App token id: app-token uses: actions/create-github-app-token@v3 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: aws + owner: ${{ steps.cdk-repo.outputs.owner }} + repositories: ${{ steps.cdk-repo.outputs.repository }} + permission-contents: read + skip-token-revoke: true # Clone CDK repo for bundle script (requires App token for private repo access) - name: Clone CDK repo run: | CDK_BRANCH="${INPUT_CDK_BRANCH:-main}" echo "Cloning CDK from branch: $CDK_BRANCH" git clone --depth 1 --branch "$CDK_BRANCH" "https://x-access-token:${CDK_REPO_TOKEN}@github.com/${CDK_REPO}.git" /tmp/cdk-repo + git -C /tmp/cdk-repo remote remove origin env: INPUT_CDK_BRANCH: ${{ inputs.cdk_branch }} CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + - name: Revoke GitHub App token + if: always() && steps.app-token.outputs.token != '' + env: + CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} + GITHUB_API_URL: ${{ github.api_url }} + run: | + curl --fail-with-body --silent --show-error \ + --request DELETE \ + --header "Accept: application/vnd.github+json" \ + --header "Authorization: Bearer ${CDK_REPO_TOKEN}" \ + --header "X-GitHub-Api-Version: 2022-11-28" \ + "${GITHUB_API_URL}/installation/token" - run: npm ci