Gate is an experimental local CLI for finding secret-like patterns in source files and git history. It can install a repository-local pre-commit hook, emit JSON or SARIF, optionally ask supported providers whether a detected credential is accepted, and attempt bounded source-to-environment rewrites.
Gate is a pattern scanner, not proof that a repository is secret-free. Findings require review, rules can produce false positives, and credentials can be missed. A clean result should be one layer in a wider review and secret-management process.
Documentation: penumbraforge.com/gate/wiki
Requires Node.js 22 or later and npm 10 or later.
npm install -g @penumbraforge/gate
gate init
gate scan --all
gate fix --dry-rungate init can create .gateignore, update .gitignore, and install a pre-commit hook in the current repository. Review every generated file before committing it.
You can also run a one-off scan without a global install:
npx @penumbraforge/gate scan --all- Scans explicit paths, staged files, changed files, all tracked files, or a bounded number of commits.
- Uses regular-expression and entropy-based rules. These are heuristics, not semantic analysis.
- Emits text, JSON, or SARIF and exits non-zero when findings or scan errors remain.
- Respects
.gatercand.gateignore; exclusions reduce coverage and should be reviewed.
111 unique detection rules (80 built-in + 68 FORTRESS pack, deduplicated).
By severity: critical 54 · high 43 · medium 11 · low 3
| Category | Rules |
|---|---|
| SaaS Tokens | 27 |
| Cloud Credentials | 24 |
| Authentication Tokens | 10 |
| AI/ML Keys | 7 |
| Database Credentials | 7 |
| Generic Secrets | 7 |
| Private Keys | 7 |
| API Keys | 6 |
| Infrastructure | 5 |
| Registry Tokens | 3 |
| PII | 2 |
| AI Keys | 1 |
| Code Injection | 1 |
| Encoding | 1 |
| Entropy Detection | 1 |
| Misconfiguration | 1 |
| Secrets Management | 1 |
Rule count is not the same as measured recall. Gate does not currently publish a comparative recall benchmark against other scanners.
gate verify and gate scan --verify make network requests for rule IDs with a supported verifier. The detected credential is sent to that credential's provider API, usually in an authorization header; GCP verification currently places the token in a provider URL query. Unsupported rules, partial credentials, timeouts, and unexpected responses return an unknown or incomplete status.
Verification is off for a normal scan unless enabled by CLI/config. Set GATE_OFFLINE=1 to disable verification requests. A hashed verification cache is stored under ~/.gate, but provider and network logs are outside Gate's control.
The current generated hook exports GATE_HOOK_TYPE, while the CLI's hook-specific verification/re-staging branch checks GATE_PRE_COMMIT. As a result, enabling verification in .gaterc can unexpectedly make provider requests from a generated hook, and hook-specific re-staging behavior may not activate. Keep verification disabled in hook configuration (or set GATE_OFFLINE=1) until that mismatch is fixed.
Treat live, inactive, and unknown as advisory observations. Provider behavior can change, and an inactive response does not prove that a value was never valid or that exposure caused no harm.
gate fix can extract recognized values into a plaintext .env, update .gitignore, create .env.example, and rewrite some quoted source assignments to environment-variable references. Adapters exist for several common file types, but not every finding, syntax shape, framework, or language is safely rewritable.
Important limits:
- Always run
gate fix --dry-runfirst and review the diff, tests, and application behavior afterward. - Moving a value does not rotate or revoke it. Rotate an exposed credential at its provider.
- JSON cannot reference environment variables directly; the current JSON path extracts a value but requires manual source/config migration.
- Multiple secrets that derive the same variable name and existing
.envconflicts require special review. - Generated imports and source substitutions are syntactic heuristics, not an AST-aware refactor.
- Undo snapshots are local recovery aids, not transactional rollback across every file or external system.
.env, remediation snapshots, purge replacement files, and Gate's local audit data should all be treated as sensitive. In the current audit implementation, the displayed match field is masked before persistence, but another internal finding field can still contain the raw secret.
gate install adds a pre-commit hook to the current repository. The hook scans staged files, but it is a local convenience boundary: hooks can be skipped, removed, or absent on another clone, and a pre-commit scan does not cover untracked/unstaged content or remote history. Because of the environment-variable mismatch described above, review hook behavior in a disposable commit before relying on interactive remediation or automatic re-staging.
The GitHub Action defaults to mode: report, which warns rather than blocks. Use mode: enforce or failure-mode: block when a non-zero policy decision is required. The Action installs the current published npm package on the runner when gate is not already available, so pin the Action to an immutable commit and review the package/version boundary for high-assurance use.
name: Gate
on: [pull_request, push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: penumbraforge/gate@v2
with:
mode: enforce
failure-mode: block
fail-on: high
verify: false
format: sarifEnabling verify: true sends supported candidate credentials to their provider APIs from the GitHub runner. SARIF upload and PR comments send finding metadata to GitHub. Slack notifications send finding counts/repository context to the configured Slack webhook.
gate incident prints provider-specific rotation and audit guidance, creates a local incident record, and writes a history-purge script plus a plaintext replacement file for manual review. It does not rotate a credential, inspect provider audit logs, execute the purge, force-push rewritten history, notify collaborators, or confirm that those actions were completed.
gate report maps recorded findings to selected OWASP, NIST, CIS, and SOC 2 references. The output is a scanner report, not an audit, certification, control assessment, or evidence that a system complies with those frameworks.
gate scan [files...] Scan explicit files; without files, scan staged files
gate scan --all Scan all tracked files
gate scan --changed Scan files changed from the upstream branch
gate scan --history <N> Scan the last N commits
gate verify [files...] Scan and attempt supported-provider verification
gate fix [files...] Attempt bounded remediation (all tracked by default)
gate fix --dry-run Preview remediation without writing
gate fix --undo Restore the latest local remediation snapshot where safe
gate incident [files...] Generate incident guidance/artifacts for pushed findings
gate report Generate a report from local audit data
gate purge Generate a manual git-filter-repo purge script
gate install Install the current repository's pre-commit hook
gate uninstall Remove Gate's managed pre-commit hook block
gate audit Inspect the local audit log
gate status Show local installation/configuration status
gate help Show the complete CLI help
Run gate <command> --help for the implemented options. The longer technical reference is in GUIDE.md.
Normal local scans do not require an account or send findings to a Penumbra Forge service. Network activity can still occur when you deliberately use provider verification or update checks, run the GitHub Action/integrations, or use npm to install the package. Gate has one external runtime npm dependency (js-yaml), so "local" does not mean "no supply-chain risk."
npm test
npm run docs
node bin/gate.js scan --allGenerated rule-count blocks in this README and GUIDE.md come from scripts/gen-docs.js.
Apache-2.0. See LICENSE and NOTICE.
Corrections and reproducible bug reports are welcome in the issue tracker.
