> ## 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-1 — Job/step condition is always true

> An if: that mixes literal text with expression blocks evaluates as a truthy string, so the guard never gates.

| Field      | Value                                                                                                                                               |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Category   | `CICD-SEC-1`                                                                                                                                        |
| Severity   | **HIGH**                                                                                                                                            |
| Confidence | HIGH                                                                                                                                                |
| OWASP      | [CICD-SEC-1: Insufficient Flow Control](https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-01-Insufficient-Flow-Control-Mechanisms) |
| Auto-fix   | ✓ (when the literal text between blocks is pure boolean glue)                                                                                       |

## What the check does

Flags an `if:` value — at the job or step level — that contains a `${{ … }}`
expression block **and** literal text outside it. GitHub then evaluates the
whole value as a string, and any non-empty string is truthy, so the condition
is always true and gates nothing.

## Why it matters

A condition that looks like a security gate but always passes is worse than no
gate — it creates false confidence. The classic mistake is joining two
expression blocks with a literal operator:

```yaml theme={null}
# ← both branches run unconditionally: the value is a non-empty STRING
if: ${{ github.event_name == 'push' }} && ${{ github.actor == 'admin' }}
```

GitHub concatenates `"true"`, `" && "`, and `"false"` into one truthy string.

## Safe alternative

Wrap the **entire** condition in a single expression block so it evaluates as
one boolean:

```yaml theme={null}
if: ${{ github.event_name == 'push' && github.actor == 'admin' }}
```

## Auto-fix

`pipefort --fix` (and the web app's fix button) merges the blocks into one
expression when the text between them is only boolean glue (`&&`, `||`, `!`,
parentheses, whitespace). When the residue contains real words the intent is
ambiguous, so the finding is left for manual remediation.
