Skip to content

- ci: add minimum required permissions to GitHub Actions workflows#582

Merged
mtracz merged 2 commits intomainfrom
copilot/audit-fix-github-actions-permissions
Mar 26, 2026
Merged

- ci: add minimum required permissions to GitHub Actions workflows#582
mtracz merged 2 commits intomainfrom
copilot/audit-fix-github-actions-permissions

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 25, 2026

All 6 workflows lacked explicit permissions blocks, defaulting to overly permissive GITHUB_TOKEN scopes. Adds least-privilege permissions to each workflow based on what it actually needs.

Changes

  • check-pr-title.ymlcontents: read + pull-requests: read (reads PR metadata)
  • test-and-lint-js.ymlcontents: read (checkout only)
  • test-and-lint-php.ymlcontents: read (checkout only)
  • deploy-to-beta-manually.ymlcontents: read (checkout + Docker/SSH deploy, no token writes)
  • deploy-to-prod.ymlcontents: read (same as beta)
  • run-command-on-beta.ymlpermissions: {} (SSH only, never checks out code)
Original prompt

Goal

Audit and fix all GitHub Actions workflows in .github/workflows/ by adding explicit permissions blocks with the minimum required permissions. This follows the security best practice of least-privilege (principle of minimal permissions).

Security principles to apply

  1. Add per-workflow permissions blocks with only what each workflow truly needs.
  2. Never leave workflows without explicit permissions — the default is overly permissive.
  3. Use pinned actions by SHA — all actions here are already pinned, keep them as-is.

Workflows to fix

.github/workflows/check-pr-title.yml (BlobSha: ef659ac254b7040788c3525543b29ab4ca7b6f65)

  • Trigger: pull_request — checks PR title using blumilksoftware/action-pr-title. Needs to read PR metadata.
  • Add top-level permissions:
    permissions:
      contents: read
      pull-requests: read

.github/workflows/test-and-lint-js.yml (BlobSha: 2ff180ed40190dfcc4001f3debafe334536dc56d)

  • Trigger: pull_request — lint/test JS, no writes needed.
  • Add top-level permissions:
    permissions:
      contents: read

.github/workflows/test-and-lint-php.yml (BlobSha: bc473654fad92d685ee99bb433d8e6d0888b6f86)

  • Trigger: pull_request — lint/test PHP, no writes needed.
  • Add top-level permissions:
    permissions:
      contents: read

.github/workflows/deploy-to-beta-manually.yml (BlobSha: 2b1fa8574b689e979e9d02d3b579cafaf53d4e61)

  • Trigger: workflow_dispatch — builds Docker, pushes to external registry, deploys via SSH. No GITHUB_TOKEN writes needed.
  • Add top-level permissions:
    permissions:
      contents: read

.github/workflows/deploy-to-prod.yml (BlobSha: b383c8ddbc2c74e781d39978eeb8310bb96e6f71)

  • Trigger: push on tags — same as deploy-to-beta but to production.
  • Add top-level permissions:
    permissions:
      contents: read

.github/workflows/run-command-on-beta.yml (BlobSha: 1a44179adbe92ad2769f0ad18df89f52ff36e8e8)

  • Trigger: workflow_dispatch — only runs SSH command, does NOT checkout code, does NOT need GITHUB_TOKEN at all.
  • Add top-level permissions (deny all):
    permissions: {}

Current file contents

check-pr-title.yml

name: Check PR Title
on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize
      - ready_for_review
      - reopened

jobs:
  check-pr-title:
    name: Check PR title
    timeout-minutes: 10
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-24.04

    steps:
      - uses: blumilksoftware/action-pr-title@e05fc76a1cc45b33644f1de51218be43ac121dd0 # v1.2.0

test-and-lint-js.yml

name: Test & lint JS stuff

on:
  pull_request:
    branches:
      - main
    types: 
      - opened
      - synchronize
      - reopened
      - ready_for_review
    paths:
      - '**.js'
      - '**.vue'
      - 'package.json'
      - 'package-lock.json'

jobs:
  test-and-lint-js:
    name: Test & lint JS stuff
    timeout-minutes: 10
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

      - name: Cache dependencies
        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
        with:
          path: node_modules
          key: ${{ runner.os }}-npm-dependencies-${{ hashFiles('package.lock') }}
          restore-keys: ${{ runner.os }}-npm-dependencies

      - name: Set up node
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
        with:
          node-version: 22.17.1

      - name: Instal npm dependencies
        run: npm clean-install

      - name: Run JS linter
        run: npm run lint

test-and-lint-php.yml

name: Test & lint PHP stuff

on:
  pull_request:
    branches:
      - main
    types: 
      - opened
      - synchronize
      - reopened
      - ready_for_review
    paths:
      - '**.php'
      - 'composer.json'
      - 'composer.lock'
      - 'phpunit.xml'
      - '.env.ci'
      - 'test-and-lint-php.yml'

jobs:
  test-and-lint-php:
    name: Test & lint PHP stuff
    timeout-minutes: 10
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-24.04
    env:
      # renovate: datasource=docker depName=php
      PHP_VERSION: 8.4.16
    services:
      postgres:
        image: postgres:15@sha256:a7711af921c380de0fda7c48a61fab5ac4def145fd9fc00ccea7355fd6270bb4
        env:
          POSTGRES_DB: toby-test
          POSTGRES_USER: toby
          POSTGRES_PASSWORD: password
        ports:
          - 5432:5432

    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

      - name: Validate composer.json and composer.lock
        run: composer validate

      - name: Cache dependencies
        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
        with:
          path: ven...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

⌨️ Start Copilot coding agent tasks without leaving your editor — available in [VS Code](https://gh.io/cca-vs-code-docs), [Visual Studio](https://gh.io/cca-visual-studio-docs), [JetBrains IDEs](https://gh.io/cca-jetbrains-docs) and [Eclipse](https://gh.io/cca-eclipse-docs).

Copilot AI changed the title [WIP] Audit and fix GitHub Actions workflows for permissions - ci: add minimum required permissions to GitHub Actions workflows Mar 25, 2026
Copilot AI requested a review from mtracz March 25, 2026 14:06
@mtracz mtracz marked this pull request as ready for review March 25, 2026 14:10
@mtracz mtracz requested a review from a team as a code owner March 25, 2026 14:10
@mtracz mtracz merged commit 0d866fb into main Mar 26, 2026
4 checks passed
@mtracz mtracz deleted the copilot/audit-fix-github-actions-permissions branch March 26, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants