carabiner
Repository security · CLI · MIT

Configured is not the same as working.

carabiner makes any repository secure by default, keeps it that way with a ratchet that only turns one way, and then attacks your own defences to prove they actually fire.

Fast scan0.02s
Own suite31 / 96
Deps1

Every scanner already exists. Nobody runs them.

gitleaks, Trivy, Semgrep, OSV-Scanner are excellent and free. carabiner reimplements none of them. It fixes the three reasons the median repository still runs nothing.

Failure 01

Setup is per-tool, per-language, per-CI

Securing one repo means five READMEs and four config files. A two-hour job you do once and never repeat — so it never happens on repo number two.

Failure 02

The first run returns 400 findings

Point any scanner at a codebase older than a year and it buries you in findings about code nobody has touched since. The gate gets switched off, and now the tool has negative value — it looks like coverage.

Failure 03

The hook is configured. Nobody installed it.

The config is perfect and nothing runs. Invisible to every static checker, including this one — the only way to know is to plant a credential and watch what happens.

A ratchet turns one way

The mechanism that makes this installable in a ten-year-old repo on a Tuesday afternoon.

ACCEPTED · 340
  1. Adopt. carabiner init runs everything once and records every existing finding as accepted. Your build goes green immediately.
  2. Hold. From then on CI fails only on findings that are new. No cleanup sprint, no 400-item backlog blocking the release.
  3. Never slip. Accepted debt stays visible under carabiner debt, with the date it was taken on. It is recorded, not deleted.
  4. Survive a reformat. Findings are fingerprinted on content, never on line numbers — so adding an import at the top of a file does not resurrect the whole baseline.

Then it attacks you

Everything else reads files. The drill reads outcomes — it plants a private key, runs your installed hooks against it, and asks GitHub whether your protections are switched on at all.

carabiner drilllive output
$ carabiner drill

  HIGH     DRILL002  pre-commit hooks are configured but NOT installed
                     — the config looks right and nothing runs
           fix: run `pre-commit install`; until then every hook
                in that file is decorative

  HIGH     DRILL013  the default branch 'main' has no protection rule
                     — CI cannot gate what can be pushed to directly

  2 new   1.53s

A drill that could not run never reports as passing. No token, no network, no pre-commit binary all produce “could NOT be verified”, not a green check. Unverified is not secure — and a green check you did not earn is worse than no check at all.

Three ways in

Findings land in your PR’s Security tab, tracked across commits by the same fingerprint the ratchet uses.

.github/workflows/security.ymlyaml
permissions:
  contents: read
  security-events: write

steps:
  - uses: actions/checkout@v4
  - uses: MaXiMo000/carabiner@v0.2.1
  - uses: github/codeql-action/upload-sarif@v3
    with:
      sarif_file: carabiner.sarif

What it checks

A missing scanner degrades to an install hint. A scanner that fails produces a finding saying the check did not happen — a tool that errors is not a repo that is clean.

EngineChecksNeeds
ci · Actions pull_request_target with a PR-head checkout · script injection from github.event into run: · unpinned actions · token blast radius · self-hosted runnersnothing
ci · GitLab script injection from a merge-request title or branch name · unpinned remote include: · mutable image and service tagsnothing
repo .gitignore gaps · committed key material · missing disclosure policy · credentials embedded in git remotesnothing
secrets working tree every commit; history behind --all and one severity higher, because deleting the file is not remediationgitleaks
deps lockfile advisories across PyPI, npm, Go, Maven, crates.io and more — ids normalised to CVE so two scanners cannot report one problem twiceosv-scanner

Check the gear before you need it.