> ## 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 — Reusable workflow called with secrets: inherit under a privileged trigger

> A pull_request_target / workflow_run job calls a reusable workflow with secrets: inherit, handing it every repository secret.

| Field    | Value                                                                                                                                        |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Category | `CICD-SEC-4`                                                                                                                                 |
| Rule ID  | `cicd-sec-4-secrets-inherit-pr-target`                                                                                                       |
| Severity | **HIGH**                                                                                                                                     |
| OWASP    | [CICD-SEC-4: Poisoned Pipeline Execution](https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-04-Poisoned-Pipeline-Execution) |
| Auto-fix | ✗                                                                                                                                            |

## What the check does

Fires only on workflows triggered by `pull_request_target` or `workflow_run`. Within those, it flags a job that calls a reusable workflow (a job-level `uses:`) with `secrets: inherit`.

`secrets: inherit` passes **every** secret available to the calling workflow into the called one.

## Why it matters

Under a privileged trigger the calling workflow already runs in an attacker-influenced context. `secrets: inherit` then widens the blast radius from "the secrets this job needs" to "every secret in the repository/organization": the called workflow — and any untrusted code it ends up running — can reach all of them. Passing only the specific secrets a reusable workflow needs keeps a single compromise from yielding the full secret store.

## Vulnerable example

```yaml theme={null}
on: pull_request_target
jobs:
  call:
    uses: ./.github/workflows/reusable.yml
    secrets: inherit          # every secret handed downstream
```

## Safe alternative

```yaml theme={null}
on: pull_request_target
jobs:
  call:
    uses: ./.github/workflows/reusable.yml
    secrets:
      deploy_token: ${{ secrets.DEPLOY_TOKEN }}   # only what's needed
```

Better still, keep untrusted-trigger workflows away from secrets entirely and do privileged work in a separate, trusted workflow.
