> ## 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-5 — Missing permissions specification

> Workflows without explicit permissions inherit the repo's default GITHUB_TOKEN scope, which is often broader than needed.

| Field    | Value                                                                                                                                                   |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Category | `CICD-SEC-5`                                                                                                                                            |
| Severity | **MEDIUM**                                                                                                                                              |
| OWASP    | [CICD-SEC-5: Insufficient PBAC](https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-05-Insufficient-PBAC-Pipeline-Based-Access-Controls) |
| Auto-fix | ✓ ([what it does](#auto-fix))                                                                                                                           |

## What the check does

Flags any workflow that:

* Has no top-level `permissions:` block, **and**
* Has at least one job without a job-level `permissions:` block.

A workflow passes the check if either *all* jobs declare permissions or the workflow itself does.

## Why it matters

When a workflow doesn't declare `permissions:`, the `GITHUB_TOKEN` falls back to the repository/organization default — which is often **write** access to contents, issues, pull requests, and more. Any step (including a third-party action) then runs with that broad token. An action compromise becomes a repo compromise.

Explicit `permissions:` is the **principle of least privilege** for the workflow token.

## Vulnerable example

```yaml theme={null}
name: ci
on: pull_request
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test
```

No `permissions:` anywhere — uses the repo default.

## Safe alternatives

**Read-only by default:**

```yaml theme={null}
permissions: read-all

jobs:
  test:
    ...
```

**Explicit minimum:**

```yaml theme={null}
permissions:
  contents: read

jobs:
  test:
    ...
```

**Per-job, with one job that needs more:**

```yaml theme={null}
jobs:
  test:
    permissions:
      contents: read
    ...
  release:
    permissions:
      contents: write
      packages: write
    ...
```

## Auto-fix

`--fix` prepends `permissions: read-all` to the top of the workflow. This is the safest default — every existing step can still read code and metadata, but no writes.

<Note>
  If a job actually needs write access (e.g. publishing a release), the auto-fix will break it. Review the diff and add explicit job-level write permissions where needed.
</Note>
