Skip to content

Secret Scanning

Secrets are kept out of the public repositories by three automatic checks: one before a commit, one on push and one in CI.

LayerWhenRules
pre-commit (local)before every commitgitleaks
GitHub push protection (server)on every pushGitHub’s secret patterns; the push is rejected
CI secret-scanpush to develop, pull request to develop or mastergitleaks, default rules, full history (fetch-depth: 0)

Push protection is on in every public repository of the organisation. It works on the server: a push that contains a detected secret is rejected, and git commit --no-verify does not get around it the way it skips a local hook.

The CI job of a library or a module pins the gitleaks version of the rev in its .pre-commit-config.yaml. The service’s CI job downloads the latest gitleaks release.

Running the Checks Without the Internal Config

Section titled “Running the Checks Without the Internal Config”

.pre-commit-config.yaml ships with every Python repository. Run pre-commit install after cloning.

Maintainer machines also plug in an internal gitleaks config, a blocklist that cannot be published, through a gitignored .gitleaks.toml symlink. Two places check for it and fail without it:

  • the first line of make check, grep -q "forbidden-names" .gitleaks.toml, which exits 1;
  • the pre-commit hook require-canonical-gitleaks-config, which runs the same check.

Without the config, run what make check wraps and skip the guard hook on commit:

Terminal window
uv run ruff check . && uv run ruff format --check .
make test
SKIP=require-canonical-gitleaks-config git commit ...

The change is still scanned: the CI secret-scan job runs gitleaks git with the default rules on every pull request to develop and master, and push protection guards the server side. The guard keeps maintainer machines on the internal config; it does not gate contributions.