GitLab Security & compliance

Active leaked secrets

Part of the GitLab scanner findings check · fix arrives as a guide

What it is

GitLab secret detection has found an active credential in the repository.

Why it matters

The credential is in history and readable by everyone with project access. Detection confirms it exists; it does not do anything about it still being valid.

Where the finding comes from

GitLab’s secret detection job scans commits for credential patterns and writes its findings to the vulnerability report (Secure → Vulnerability report). It runs from a template include — if the job is not in the pipeline, nothing is scanning:

# .gitlab-ci.yml include: - template: Jobs/Secret-Detection.gitlab-ci.yml

The job itself runs on every tier and leaves a gl-secret-detection-report.json artifact; the aggregated vulnerability report that this check reads is a GitLab Ultimate feature and only holds data once the scanners have run in a pipeline.

What “active” changes

A leaked secret finding means a credential-shaped string is readable by everyone with repository access — including every future clone, fork and CI runner, because git history does not forget. Active means it still authenticates. That reorders everything: the credential’s validity is the emergency, its presence in history is the cleanup.

The playbook, in strict order

Rotate first. Any other order leaves a live key exposed while you tidy git:

1. Rotate the credential at the provider — new key issued, old key revoked. 2. Check the provider’s audit/usage log for calls you did not make, from IPs you do not recognise, since the first leaked commit. 3. Replace the literal in code with an environment variable or CI/CD variable (Settings → CI/CD → Variables, masked and protected). 4. Only then decide whether rewriting history is worth it — for a rotated key it is usually not; the string left behind is dead.

History rewriting (git filter-repo) invalidates every clone and open merge request, and the secret usually survives anyway in forks, CI caches and provider logs. Rotation is what actually ends the incident — treat rewriting as hygiene for special cases (a secret that cannot be rotated, a compliance requirement), not as the response.

Stop the next one at push time

Secret push protection rejects a push containing a detectable secret before it ever reaches the repository — Settings → Security configuration → Secret push protection. Pair it with a local pre-commit hook (gitleaks) so the developer finds out before GitLab has to:

# .pre-commit-config.yaml repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.24.0 hooks: - id: gitleaks

How lumioguard fixes it

lumioguard reads the vulnerability report on every scan, verifies which findings are still live credentials, and opens a guide per finding: the provider’s rotation steps, the audit-log query to run, the variable to move the value into, and the push-protection setting if it is off. The guide is written to be handed to whoever owns that credential — or to your coding agent.

Run them all on your app

Connect your repo and your live services with read-only scopes. The first scan is free, and nothing changes without your approval.