Hard-coded secrets (API keys, passwords, tokens, and certificates embedded in source code) are one of the most persistent and underestimated risks in software development. A single leaked credential can be the difference between a routine day and a breach that makes the news.
Why this deserves a place in your security strategy:
- The exploitation window is minutes, not days. Automated scanners continuously sweep public repositories for credentials. Research shows secrets pushed to GitHub are typically found within minutes. The question is not whether a leaked secret gets discovered; it is whether an attacker finds it before you do.
- You cannot fix what you cannot see. Most engineering organisations genuinely do not know how many hard-coded secrets exist across their codebases, CI/CD configurations, Dockerfiles, and log outputs. Without systematic detection, you are managing a risk you cannot quantify.
- Secrets sprawl far beyond source code. API keys and passwords turn up in configuration files, pipeline logs,
.envfiles, application startup output, and test fixtures, across every repository and every team. A single audit is a snapshot; CheckMate provides continuous visibility. - Compliance frameworks require demonstrable controls. PCI-DSS, SOC 2, ISO 27001, and GDPR require active, evidenced controls over credential management. Exception justifications, scan history, and immutable audit trails are the kind of artefacts that pass an audit, not policies alone.
- False positives destroy adoption. Security tooling that cries wolf gets disabled. CheckMate's AI triage layer reduces analyst noise, ensuring the findings that surface are worth acting on.
CheckMate uses a multi-layered detection engine combining entropy analysis, structural context, and pattern recognition to find hard-coded secrets in:
- Source code (Java, C/C++, C#, Ruby, Scala, Go, and more)
- Configuration files (YAML, XML,
.env, properties files) - Log files and application output
- Sensitive file types (certificates, key stores, private keys)
- Git repositories, including remote repositories scanned directly by URL
Detection results include:
- The exact location (file, line, column) of the finding
- Checksums of the detected secret value for safe deduplication and tracking
- A severity rating and secret type classification
- Source code context as evidence
Alert fatigue is the enemy of effective security. CheckMate integrates with any OpenAI-compatible endpoint (including local, air-gapped models via Ollama) to automatically assess whether a finding is a genuine secret or a false positive. Each AI-triaged finding gets a fpLikelihood score, a plain-language summary, remediation hints, and a full token usage audit trail. Critically, your code never leaves your infrastructure: you control the AI, and you hold the keys.
Not every flagged value is actionable immediately. CheckMate exceptions are first-class governed entities, not a simple ignore list. Each exception requires:
- A mandatory justification and reason
- A defined scope (global, project, directory, file, exact line, or secret checksum)
- An optional expiry date (exceptions auto-expire; risk doesn't just disappear)
- A full, immutable audit trail of who created, modified, or revoked the exception
This gives security and compliance teams a defensible, auditable record of every suppression decision.
CheckMate can push scan.completed and finding.detected events to any external HTTP endpoint: Slack, Jira, PagerDuty, SIEM platforms, or custom CI/CD pipelines. Payloads are HMAC-signed for authenticity verification. Security operations don't have to poll; they get notified.
Scan results can be exported in SARIF 2.1.0 format, including partialFingerprints, enabling seamless ingestion into GitHub Code Scanning, enterprise SIEM dashboards, and vulnerability management platforms, with no middleware required.
The CheckMate API server includes a built-in scheduler for continuous, automated repository monitoring. Security posture is not a point-in-time measurement; CheckMate keeps watching so you don't have to manually trigger audits.
| Mode | Description |
|---|---|
| CLI | Developer workstation, scripting, one-shot audits |
| Docker | Container-native scanning in any environment |
| API Server | Self-hosted platform with REST API, JWT auth, and SQLite persistence |
| GitHub Action | Native CI/CD integration; block secrets before they merge |
| Desktop App | GUI application for non-CLI users |
| LSP Server | IDE integration (Language Server Protocol) for in-editor warnings |
brew install adedayo/tap/checkmateDownload the latest pre-built binaries for your operating system from the releases page.
docker pull ghcr.io/adedayo/checkmateA graphical desktop version of CheckMate is available: CheckMate Desktop Application.
# Scan a local directory
checkmate search /path/to/your/project
# Scan a remote git repository directly
checkmate search https://github.com/example/repository.git
# Scan with SARIF output for GitHub Code Scanning
checkmate search --sarif /path/to/project > results.sarif
# Generate a PDF audit report
checkmate search --pdf /path/to/project| Flag | Description |
|---|---|
--calculate-checksums |
Compute checksums of detected secrets (default: true) |
--exclude-tests |
Skip test files during scanning |
-e, --exclusion <file> |
Use an exclusion YAML configuration file |
--json |
Generate output in JSON format (default: true) |
--pdf |
Generate a native PDF audit report |
--report-ignored |
Include ignored files and values in reports |
--running-commentary |
Stream results as they are found (useful for large repos) |
--sample-exclusion |
Generate a sample exclusion YAML file |
--sarif |
Generate SARIF 2.1.0 output |
--sensitive-files |
List all registered sensitive file types |
--sensitive-files-only |
Scan only for sensitive files (certificates, key stores) |
-s, --source |
Include source code evidence in results (default: true) |
--verbose |
Enable verbose output |
Run CheckMate as a persistent, self-hosted API service:
checkmate api --port 17283 --data-path ~/.checkmateThe API server provides:
- JWT-authenticated REST endpoints for projects, scans, findings, exceptions, and webhooks
- Real-time scan event streaming via Server-Sent Events (SSE)
- Automated scheduled scanning of monitored repositories
For full API capabilities including BYOK AI Triage, Webhook Notifications, and Auditable Exceptions, see the Features & Capabilities Documentation.
# Scan a local directory
docker run --rm -v $(pwd):/data ghcr.io/adedayo/checkmate search /data
# Scan a remote git repository
docker run --rm ghcr.io/adedayo/checkmate search https://github.com/example/repository.gitAdd CheckMate to your CI/CD pipeline to catch secrets before they merge:
- name: CheckMate Secret Scan
uses: adedayo/checkmate@latestCheckMate generates executive-ready PDF audit reports natively:
checkmate search <path> --pdfPDF report generation is 100% native and runs directly out of the box with zero external dependencies.
CheckMate scans files in parallel and gates its rule set behind a literal prefilter, so that on any given file only the rules that could possibly match are actually run. On ordinary source this skips well over 90% of the vendor rule set.
Tuning never changes results. The worker count, the prefilter and the progress interval are performance controls only. The test suite scans a reference corpus with the prefilter on and off, and at different worker counts, and requires the findings to be byte-identical. Scans are also deterministic: the same tree produces the same findings in the same order, on every run and regardless of which worker happened to finish first.
| Variable | Default | Effect |
|---|---|---|
CHECKMATE_SCAN_WORKERS |
GOMAXPROCS |
Files scanned concurrently. Set to 1 for sequential scanning, or lower to cap CheckMate's footprint on a shared CI runner. |
CHECKMATE_PROGRESS_INTERVAL |
250ms |
Progress reporting interval. Accepts 500ms, 2s, or a bare number read as milliseconds. |
CHECKMATE_CLONE_CONCURRENCY |
4 |
Repositories cloned at once. |
CHECKMATE_DISABLE_PREFILTER |
unset | Set to 1 to run every rule against every file. An escape hatch; should not change results. |
CHECKMATE_PRUNE_DIRS |
unset | Comma-separated directory names to skip. Replaces the built-in list; set empty to disable. |
# Cap CheckMate at 4 workers on a shared build agent
CHECKMATE_SCAN_WORKERS=4 checkmate search ./my-projectDirectory pruning is off by default, deliberately. Skipping node_modules,
vendor, dist and .git is worth roughly 2Γ on a dependency-heavy tree β but
those directories are scanned today and they hold real secrets: .npmrc auth
tokens, API keys baked into dist/bundle.js, https://user:token@host remotes
in .git/config. That is a coverage decision, so it is yours to make rather
than ours:
CHECKMATE_PRUNE_DIRS='node_modules,vendor,dist,.git' checkmate search ./my-projectIf a scan is slower than you expect and pruning is not appropriate, the usual
cause is a small number of very large single-line files β minified bundles,
serialised blobs or base64 assets β rather than the file count. Run with
--verbose to see which file is being scanned.
For benchmark methodology and the equivalence-testing approach, see
docs/testing.md.
CheckMate is designed to support the following security and compliance scenarios:
| Use Case | How CheckMate Helps |
|---|---|
| Pre-commit / PR scanning | Block secrets from entering the codebase at the source via GitHub Action |
| Repository-wide audit | Establish a baseline of existing exposure across all repositories |
| Continuous monitoring | Automated, scheduled scans catch regressions as codebases evolve |
| Audit evidence | Exception justifications, immutable audit trails, and PDF reports provide auditor-ready documentation |
| SIEM integration | SARIF output and webhooks feed findings into enterprise monitoring infrastructure |
| Air-gapped AI triage | Reduce analyst workload without sending sensitive code to third-party cloud services |
| PCI-DSS / SOC 2 / ISO 27001 | Demonstrate active, continuous controls over credential management |
CheckMate is structured as a layered platform:
checkmate/
βββ cmd/ # CLI commands (search, api, lsp-serve)
βββ pkg/
β βββ ai/ # BYOK AI triage client (OpenAI-compatible)
β βββ api/ # REST API handlers and routing
β βββ auth/ # JWT authentication
β βββ cron/ # Scheduled scan automation
β βββ lsp/ # Language Server Protocol support
β βββ report/ # SARIF report generation
β βββ reports/pdf/ # Native PDF report generation
β βββ sdk/ # Shared types (Finding, AIAnnotation, etc.)
β βββ store/sqlite/ # SQLite-backed persistence with versioned migrations
The scanner engine itself lives in checkmate-plugin/secrets-finder, a separate, reusable module, allowing CheckMate to be embedded or extended independently of the platform.
Contributions are welcome. Please open an issue or pull request on GitHub.
BSD 3-Clause License. See LICENSE for details.
Author: Dr. Adedayo Adetoye (Dayo): https://github.com/adedayo
