> For the complete documentation index, see [llms.txt](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails/guardrail-types/secrets-guardrails.md).

# Secrets Guardrails

Gate a pull request on the secrets it introduces, or on secrets anywhere in the repository.

Secrets guardrails catch credentials on a pull request. They come in two rules, and a guardrail holds one of them:

| Rule                   | Fires when                                                             | Builder tile                   |
| ---------------------- | ---------------------------------------------------------------------- | ------------------------------ |
| **Secret Scanning**    | A secret appears in a commit the pull request adds                     | **Exposed Secret**             |
| **Repository Secrets** | A matching secret exists anywhere in the repository's secret inventory | **Existing Repository Secret** |

Both rules use the `Repository` entity, so a secrets guardrail is **dedicated**.

## Secret Scanning

Rather than scanning only the final squashed diff, Heeler scans **every commit in the PR/MR window** (merge-base → head) independently — so a secret added in one commit and removed in another is still caught.

{% hint style="info" %}
**Scope of the scan.** The **Secret Scanning** rule evaluates the **PR/MR window only** (merge-base → head) — the commits the pull request adds. Secrets that already existed on the base branch before the PR aren't flagged by this rule; they surface in [Operate → Secrets](/mrecEO40m5D6bt7Pq5pE/findings/secrets.md), and they are what the **Repository Secrets** rule gates on. No baseline setup is required — the rule scans the PR's own history directly.
{% endhint %}

## Repository Secrets

The **Repository Secrets** rule violates a pull request when a matching secret exists anywhere in the **repository's secret inventory**, including git history, regardless of what the pull request touches. The pull request is where the violation is reported; the repository's state is what it is reported on.

Three filters narrow which secrets count. Each field is a filter, and leaving one empty means it doesn't filter:

| Filter                   | You provide                                                                                                           |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| **Secret type**          | A single detection rule — for example `aws.2`. Empty matches every rule.                                              |
| **Detection confidence** | One or more of High, Medium, Low, Unknown. Empty matches every confidence.                                            |
| **Validation status**    | One or more of the five action buckets — Rotate Now, Rotate, Triage, No Action, Expected. Empty matches every status. |

Two exclusions apply ahead of the filters:

* A secret carrying an **exception** never counts, whichever filters are set.
* The repository's own [secret ignore settings](/mrecEO40m5D6bt7Pq5pE/catalog/repositories/settings.md) apply — ignored confidences, ignored rule IDs and ignored file paths are excluded here exactly as they are in the secrets inventory.

A **Repository Secrets** guardrail must hold **exactly one rule**; the builder rejects a second condition on the same guardrail.

A violation this rule raises clears when the **underlying secret is remediated or excepted**. Pushing another commit to the branch does not clear it, because the rule is not reading the branch.

## What's reported

Each detected secret includes its commit SHA, file path, and line number, plus:

| Field                    | Values                                                                                                               |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| **Secret type**          | The kind of credential detected                                                                                      |
| **Detection confidence** | High, Medium, Low, Unknown                                                                                           |
| **Action bucket**        | Rotate Now, Rotate, Triage, No Action, Expected. Each choice includes every underlying status mapped to that bucket. |

A **Repository Secrets** violation also carries a link to that secret in the repository's secrets inventory.

{% hint style="info" %}
**Validation is the key signal.** A secret Heeler confirms is live (**Rotate Now**) is the one to treat as critical — see how this drives prioritization in [how secrets are prioritized](/mrecEO40m5D6bt7Pq5pE/findings/secrets.md#how-secrets-are-prioritized).
{% endhint %}

## What developers see on the PR

When a secrets guardrail matches, each detected secret is surfaced on the pull request with its **secret type**, the **file path and line**, the **commit SHA** that introduced it, and its underlying **validation status** (for example, Active Credential or Assumed Valid). The rule itself is configured with an **action bucket**, so one selection consistently covers every status that calls for the same response. Under **Block**, the status check fails and, with branch protection enabled, the merge is held until the secret is removed and the credential rotated.

How a violation resolves depends on the rule:

* **Secret Scanning** — a later commit that removes the secret resolves the violation within the PR.
* **Repository Secrets** — the check report states that repository-level violations reflect the current state of the repository rather than this branch's changes, and resolve when the underlying finding is remediated or excepted.

Actions and scope are the standard **Observe / Warn / Block** across the [scope model](/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails.md#scope-where-each-guardrail-applies).

{% hint style="warning" %}
**Block stops the merge, not the exposure.** The secret entered git history the moment the branch was pushed — anyone who can clone the repository can read it, merged or not. What the guardrail buys you is **real-time notice to the developer and the reviewer**, at the moment the mistake is cheapest to respond to. The credential still has to be **rotated and revoked at its provider**.

Pair the guardrail with a [**workflow**](/mrecEO40m5D6bt7Pq5pE/operate/workflows.md) on the **New Secret Detected** trigger that **opens a ticket auto-assigned to the owning team** and **messages your security team** — so rotation is guaranteed by process, not left to whoever noticed the check. The full response runbook is [Contain a leaked secret](/mrecEO40m5D6bt7Pq5pE/solutions-and-use-cases/contain-a-leaked-secret.md).
{% endhint %}

## When the pull-request scan does not run

The **Secret Scanning** rule depends on a scan of the PR/MR window. When that scan reaches no verdict, the guardrail records the execution as **Not Evaluated** with the reason rather than as a pass — an empty findings list is equally what a scan that never ran leaves behind. See [execution results](/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails.md#execution-results).

| Reason                                         | What happened                                                                      |
| ---------------------------------------------- | ---------------------------------------------------------------------------------- |
| `secret scanning disabled for this repository` | The repository is excluded from secret scanning.                                   |
| `no base commit`                               | The pull request carries no base commit to scan from.                              |
| `base commit unavailable`                      | The base commit is not present in the clone.                                       |
| `no common history with the base branch`       | The base and head commits share no ancestor, which typically follows a force push. |
| `scan error`                                   | The scan ran with its inputs present and errored.                                  |

A warning line appears on the pull request naming what did not run, the reason, and the guardrail that reached no verdict.

**Not Evaluated does not block the merge.** The status check passes; the execution and the warning line are the record that a verdict is missing. Open the [Pull Requests](/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails.md#pull-requests-tab) tab or the guardrail's detail drawer to see which guardrails reached no verdict, and [Operational Health](/mrecEO40m5D6bt7Pq5pE/administer-and-monitor/operational-health.md) for scan errors on that repository.

## Related

* [Guardrail Types](/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails/guardrail-types.md) — the other rule families and the shared scope model.
* [Secrets](/mrecEO40m5D6bt7Pq5pE/findings/secrets.md) — detection, validation and prioritization.
* [Repository Settings](/mrecEO40m5D6bt7Pq5pE/catalog/repositories/settings.md) — the per-repository secret ignore settings both rules honor.
* [Contain a Leaked Secret](/mrecEO40m5D6bt7Pq5pE/solutions-and-use-cases/contain-a-leaked-secret.md) — the response runbook.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.heeler.com/mrecEO40m5D6bt7Pq5pE/prevent/pr-guardrails/guardrail-types/secrets-guardrails.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
