Skip to content

feat(controls): add pipeline secret detection via gitleaks (ISSUE-309)#164

Draft
predictor2718 wants to merge 5 commits into
getplumber:mainfrom
predictor2718:feature/pipeline-secret-detection
Draft

feat(controls): add pipeline secret detection via gitleaks (ISSUE-309)#164
predictor2718 wants to merge 5 commits into
getplumber:mainfrom
predictor2718:feature/pipeline-secret-detection

Conversation

@predictor2718
Copy link
Copy Markdown

@predictor2718 predictor2718 commented May 15, 2026

Closes #149

Problem

Plumber has no way to catch hardcoded secrets (API tokens, private keys, passwords) committed directly in pipeline YAML. They only get flagged by post-merge scanners, not at lint time.

What changed

New pipelineMustNotLeakSecretsInConfig control (ISSUE-309) that runs gitleaks against the resolved pipeline YAML and emits ISSUE-309/critical findings for any matches.

Touches control/secret_detection.go, control/codes.go, control/catalog.go, control/task.go, configuration/plumberconfig.go, configuration/registry.go, .plumber.yaml.

Disabled by default since gitleaks must be installed separately. When enabled:

gitlab:
  controls:
    pipelineMustNotLeakSecretsInConfig:
      enabled: true
      # gitleaksPath: /usr/local/bin/gitleaks
      # gitleaksConfigPath: /path/to/.gitleaks.toml

Note on issue code

ISSUE-301 through ISSUE-308 are already taken. Used ISSUE-309 as the next available, happy to change if there's a preferred numbering.

Testing

Unit tests in control/secret_detection_test.go cover the disabled case, missing binary, clean pipeline, and a pipeline with a fake hardcoded GitHub PAT. Also ran manually against a real GitLab CI project — 0.0% compliance with the secret present, 100% after removing it.

AI disclosure

Written with Claude Code assistance and reviewed and tested manually.

@thomasboni
Copy link
Copy Markdown
Contributor

Hello @predictor2718, thanks a lot for this PR !

We will review it with the team early next week.

@Joseph94m
Copy link
Copy Markdown
Collaborator

@predictor2718 Hello, I will have a look at this today.

@Joseph94m
Copy link
Copy Markdown
Collaborator

Joseph94m commented May 18, 2026

Hey @predictor2718 first, genuine thanks. The PR is well-structured, the tests are thoughtful, and several of your design calls (the --no-git flag, the 30s timeout, the gitleaksConfigPath escape hatch, the fact that gitleaks-missing degrades silently rather than hard-failing) all hold up. The fixtures and config knobs are exactly right.

I owe you a heads-up though: there's been an architectural shift inside Plumber over the last few weeks that wasn't loudly documented yet (and the issue template on #149 was stale — it suggested files like control/controlGitlabPipelineSecretScan.go, which is the deprecated pre-Rego pattern).

Detection logic for all shipping controls now lives in policies/*.rego, with the Go layer reserved for collector-side enrichment (calling external APIs / binaries and stuffing results into the pipeline IR).

So merging this PR as-is would commit a sizable chunk to the deprecated pattern. To save your time, I'll do the architectural rewrite myself — keeping your test fixtures, your config-knob design (gitleaksPath / gitleaksConfigPath), the gitleaks invocation shape, and your commit in the history with credit. The result will land in this PR so you get in the contributor list.

Also, I'll update the contribution docs / issue template.

@predictor2718 please ensure that allow maintainers is enabled on this PR.

Joseph94m added 2 commits May 18, 2026 18:25
The detection mechanism is being moved from a Go function in control/
to the project's standard collector + Rego pattern. This commit wipes
the old Go implementation; the next commit lands the Rego version
that uses the same control config knobs (gitleaksPath / gitleaksConfigPath)
and the same fixtures + design intent from the original contribution.
  Rewrites the secret detection control to match the project's current
  collector + Rego pattern. Detection runs in collector/gitleaks_scan.go
  and writes redacted hits to pipeline.GitleaksHits; policies/leaked_secrets.rego
  turns each hit into an ISSUE-301 finding.

  Cross-provider with the existing (still benched) GitHub toJson(secrets)
  rule under the same control name. Raw secret values never leave the
  collector: each Preview is redacted to first/last 4 chars.

  Closes getplumber#149.
@Joseph94m Joseph94m marked this pull request as draft May 18, 2026 15:31
@Joseph94m
Copy link
Copy Markdown
Collaborator

I've done part of the re-writing. Will continue on this once v0.3.0 is released with the new engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Detect leaked pipeline secrets

3 participants