Secure Workflow Permissions

Apply two security practices to GitHub Actions workflows: 1) Enforce least privilege - Set `permissions: {}` at the workflow level (or default deny) and only add the minimal scopes required for each job/step.

copy reviewer prompt

Prompt

Reviewer Prompt

Apply two security practices to GitHub Actions workflows:

1) Enforce least privilege

  • Set permissions: {} at the workflow level (or default deny) and only add the minimal scopes required for each job/step.

2) Safely pass dynamic workflow data into shell

  • Values coming from needs.*.outputs (e.g., tag/version strings) should not be interpolated repeatedly into shell snippets.
  • Instead, pass them through a controlled job-level environment variable (or a dedicated setup step) and always quote them when used in bash/script invocations.

Example pattern:

permissions: {}

jobs:
  extract-release-info:
    # ...

  create-tarball:
    needs: extract-release-info
    runs-on: ubuntu-latest
    env:
      RELEASE_TAG: $

    steps:
      - name: Create tarball
        run: |
          echo "Creating tarball for version ${RELEASE_TAG}..."
          # If using a script, pass quoted args:
          # ./utils/releasetools/01_create_tarball.sh "${RELEASE_TAG}"

This reduces blast radius (least privilege) and mitigates shell-injection risk when dynamic workflow outputs are consumed by bash.

Source discussions