Video Thumbnail for Lesson
4.4: Controlling GitHub Permissions

Controlling GitHub permissions

The GITHUB_TOKEN injected into every workflow starts with read access to repository contents and packages only. Tightening or widening those permissions protects your organization from unintended writes and helps enforce least privilege.

jobs:
  read-only-pr:
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: read # Can read PR data only
    continue-on-error: true # Avoids failing entire workflow
    steps:
      - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
      - name: List the first 5 open PRs (allowed)
        run: gh pr list --limit 5
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Attempt to add a label (expected to fail)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit 1 --add-label "documentation"
      - name: Confirm the failure
        if: failure()
        run: echo "❌  Write operation was blocked as expected – token is read-only."

  read-write-pr:
    runs-on: ubuntu-24.04
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
      - name: Attempt to add a label (expected to succeed)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr edit 1 --add-label "documentation"
      - name: Confirm the result
        if: success()
        run: echo "✅ Write operation succeeded!"

By scoping permissions at the job or workflow level you can grant just enough access for each automation task (and nothing more!).