diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4c62a6a964577c..05d95a1d6cefc1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -19,6 +19,8 @@ name: "Build" +# Security: write privileges are safe since this is triggered +# only by `push` (implying user has write access). on: push: branches: diff --git a/.github/workflows/notify_test_workflow.yml b/.github/workflows/notify_test_workflow.yml index 6c84cdde8a6a4b..4d1ea1d768ab92 100644 --- a/.github/workflows/notify_test_workflow.yml +++ b/.github/workflows/notify_test_workflow.yml @@ -25,6 +25,11 @@ name: "PR update" +# Security: `pull_request_target` events can be risky, but we: +# 1. Only grant write access for checks (a.k.a. check runs). +# 2. We are careful with untrusted inputs (i.e. don't use user-supplied +# variables in ways vulnerable to shell injection, etc.) +# 3. We don't check out the fork's head ref. on: pull_request_target: types: [opened, reopened, synchronize] diff --git a/.github/workflows/tmpl_build_and_test.yml b/.github/workflows/tmpl_build_and_test.yml index 48bcd2605637d5..4094b1f25f6526 100644 --- a/.github/workflows/tmpl_build_and_test.yml +++ b/.github/workflows/tmpl_build_and_test.yml @@ -42,6 +42,7 @@ on: Candidates: "build-only". default: '[ "build-only" ]' +# Default to minimal permissions for workflow. permissions: packages: read @@ -78,6 +79,9 @@ jobs: steps: - name: Set up Outputs id: variables + # Security: passing inputs.{os, branch} through workflow (above) inputs removes + # ability to do shell injection below. + # See: https://securitylab.github.com/resources/github-actions-untrusted-input/ run: | # Convert to lowercase to meet Docker repo name requirement REPO_OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') @@ -86,6 +90,23 @@ jobs: name: Build Image ${{ inputs.os }}-${{ inputs.branch }} runs-on: ubuntu-24.04 needs: [ precondition ] + # Security: this does not leak write access for our image repository to + # forked repos. + # + # We have `packages: write` permissions for our GITHUB_TOKEN below. However: + # + # - For `pull_request`, GitHub downgrades GITHUB_TOKEN permissions to + # read-only. + # - For `push` triggers on a fork, the GITHUB_TOKEN retains write + # permissions, but the `push` is happening in the context of the fork, not + # the upstream repo. + # - `pull_request_target` events (not used here) use the base repo's + # default branch. This prevents an attacker from adding code in a pull + # request which prints / leaks secrets, etc.. Also the GITHUB_TOKEN we + # use to grant access to writing to the image repo. is scoped to the + # repository it runs on. Even if a fork were to gain access to a + # GITHUB_TOKEN with write privileges, it doesn't grant access for other + # repositories to write. permissions: packages: write outputs: diff --git a/.github/workflows/update_build_status.yml b/.github/workflows/update_build_status.yml index d7c3be304a8ae2..a418ed57a55028 100644 --- a/.github/workflows/update_build_status.yml +++ b/.github/workflows/update_build_status.yml @@ -23,6 +23,8 @@ on: schedule: - cron: "*/15 * * * *" +# Security: privileged (can write) workflow is only triggered via schedule, +# so issues associated with forks do not apply. jobs: update: name: "Update Build Status"