Skip to content
BETAGuardrails are in beta. The library, the configuration format and the CLI command can still change.

Guardrails / Collectors

Secrets in the checkout

Secrets found in the checkout, read from the report a secret scanner already left behind, or collected by running gitleaks or trufflehog when the runner carries one and no report is there. Only the rule, the file, the line and a fingerprint are collected: the matched value never is, because these facts are attached to the run event.

Facts keysecrets
Versionv1
Scriptsecrets.py
Timeout300 seconds

Tools

This collector reads what these tools report. It never installs one: a tool that is not on the runner is missing evidence, and the guardrails asking for these facts skip rather than fail.

ToolNeededDescription
gitleaksoptionalSecret detector, run over the checkout when no report is there. Preferred over trufflehog because it reports SARIF.
trufflehogoptionalSecret detector that verifies what it finds against the service it belongs to, run when gitleaks is not there.

Installing gitleaks

Install gitleaks with brew install gitleaks, or docker run --rm -v $(pwd):/repo zricethezav/gitleaks:latest detect --source /repo, or run the gitleaks/gitleaks-action@v2 step before this one and leave its report in the checkout.

Installing trufflehog

Install trufflehog with brew install trufflehog, or curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sh -s -- -b /usr/local/bin, or run the trufflesecurity/trufflehog@main step before this one.

Inputs

InputDescriptionDefaultEnvironment
reportsComma separated globs matched against every file in the working directory and against bare file names, naming the secret scanner reports to read. Narrow it when several reports are present and only one of them should decide.gitleaks*.sarif,gitleaks*.json,trufflehog*.json,.secrets.baselineGUARDRAIL_INPUT_REPORTS
scanHistoryWhether a tool the collector runs scans the repository's git history rather than the working tree. Reading the history finds a secret that was committed and then removed, and costs the whole log. Ignored when a report was found, because the report is what the pipeline already acted on.falseGUARDRAIL_INPUT_SCANHISTORY
maxFindingsMost findings to carry in the facts. The counts stay whole when findings are dropped.200GUARDRAIL_INPUT_MAXFINDINGS

A guardrail that declares an input of the same name passes it through, so the guardrail's configuration in buildnote.json is what decides these values.

A guardrail asks for these facts by name, and reads them back the same way:

json
{
  "collect": ["secrets"]
}
python
secrets = guardrail.facts("secrets")

Facts

The document secrets collects. A path carrying [] is an entry of the list before it, and one carrying [path] is a key of the object before it.

FactMeaning
sourcereport when a secret scanner's report was read, tool when the collector ran one itself, none when there was neither.
reasonWhy nothing was collected, present only when source is none. It names the globs that matched no readable report and the tool to install.
reportsEvery report that was read, in path order.
reports[].pathPath of the report, relative to the directory the CLI runs in.
reports[].modifiedWhen the report was last written, ISO 8601, so a stale report is recognisable.
reports[].formatFormat it was read as: sarif, gitleaks, trufflehog or detect-secrets.
tool.nameTool that was run, present only when no report was found and one was on the PATH.
tool.versionVersion that tool reported when the CLI probed it, which is the answer to which scanner decided this build was clean.
tool.pathWhere on the PATH it was resolved to.
tool.argsArguments it was run with, so the same scan runs by hand.
tool.exitCodeCode it exited with. A secret detector exits non zero when it finds something, so this is a result rather than a failure.
tool.durationMsHow long the invocation took.
counts.totalSecrets found, across every report that was read or everything the tool printed.
counts.bySeverity.criticalFindings the scanner verified against the service the credential belongs to, so it is known to be live.
counts.bySeverity.highFindings reported without being verified, which is what a secret detection usually is.
counts.bySeverity.mediumFindings the report rated medium.
counts.bySeverity.lowFindings the report rated low.
counts.bySeverity.infoFindings the report rated informational.
counts.bySeverity.unknownFindings the report gave no severity, or one nobody recognises.
findingsThe findings themselves, up to maxFindings.
findings[].idRule the scanner matched, such as aws-access-token, or the detector that matched it.
findings[].severitycritical, high, medium, low, info or unknown.
findings[].messageWhat the scanner said about the rule, truncated to 500 characters. Never the value it matched.
findings[].pathFile the secret was found in, relative to the working directory, or null.
findings[].lineLine it was found on, or null.
findings[].fingerprintStable identity of the finding across runs, derived from the rule, the file and the line, so the same secret is recognisable in a later build without carrying it.
droppedFindings left out because maxFindings was reached.

A collector that cannot finish prints what it had along with an incomplete key saying why, so the facts below the point it stopped are absent. A check that cares reads incomplete before the rest.

Example facts

The example facts collected by secrets collector:

json
{
  "source": "report",
  "reports": [
    {
      "path": "gitleaks.sarif",
      "modified": "2026-03-04T10:15:00Z",
      "format": "sarif"
    }
  ],
  "counts": {
    "total": 1,
    "bySeverity": {
      "critical": 0,
      "high": 1,
      "medium": 0,
      "low": 0,
      "info": 0,
      "unknown": 0
    }
  },
  "findings": [
    {
      "id": "aws-access-token",
      "severity": "high",
      "message": "aws-access-token has detected a secret in service/src/main/resources/application.yaml.",
      "path": "service/src/main/resources/application.yaml",
      "line": 14,
      "fingerprint": "19d0004f552705be"
    }
  ],
  "dropped": 0
}

Collected for

GuardrailCategoryInputs
secrets/detector-ransecretsnone
secrets/no-hardcoded-credentialssecretsnone

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412