> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipefort.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CICD-SEC-4 — Default GITHUB_TOKEN permissions are read-write

> Every workflow without an explicit `permissions:` block gets a write-capable token. Massively widens PPE blast radius.

| Field    | Value                                      |
| -------- | ------------------------------------------ |
| Category | `CICD-SEC-4`                               |
| Severity | **HIGH**                                   |
| Auto-fix | ✓ (via `--fix-settings` or web Fix button) |
| Source   | Repository configuration                   |

## What the check does

Reads `GET /repos/{owner}/{repo}/actions/permissions/workflow`. Fires when `default_workflow_permissions` is `"write"` (the legacy default).

## Why it matters

The `GITHUB_TOKEN` injected into every workflow run is the implicit credential most workflows use. With write-capable defaults:

* A poisoned step (any `${{ github.event.* }}` injection, any compromised third-party action — see [CICD-SEC-3](/rules/cicd-sec-3) and [CICD-SEC-4](/rules/cicd-sec-4)) inherits write access to contents, deployments, packages, and more.
* Workflows that don't actually need write get it anyway. The principle of least privilege is violated by default.
* Per-workflow `permissions:` blocks ([CICD-SEC-5](/rules/cicd-sec-5)) help, but the *baseline* still leaks generosity to any workflow that forgets to declare them.

GitHub now ships new repos with the read-only default, but older repos retain the write-capable one until manually changed.

## How to fix

Settings → Actions → General → **Workflow permissions** → select **"Read repository contents and packages permissions"**.

Then update workflows that actually need write to declare it explicitly:

```yaml theme={null}
permissions:
  contents: write   # only what this job actually needs
```

This pairs with [CICD-SEC-5](/rules/cicd-sec-5) (workflows should declare `permissions:` explicitly).
