Skip to content

GerhardBotha97/KeyHound

Repository files navigation

KeyHound

KeyHound is a local, privacy‑first secret detector for VS Code. It scans your files as you work and flags likely credentials (API tokens, keys, webhooks, connection strings) before they escape your editor.

This repository contains the VS Code extension, its scanning engine, and a small catalog of detection rules.

Highlights

  • Fast, incremental scans of the current file and the workspace
  • Built‑in rules for common providers (AWS, Slack, GitHub, Stripe, Google, MongoDB, npm, Twilio, …)
  • Optional entropy‑based detection for generic high‑entropy tokens
  • Inline suppressions and workspace ignores
  • Findings panel with quick actions (ignore, redact, export)
  • Local only — no telemetry and no network calls during scanning

Quick Start

  1. Install dependencies: npm install
  2. Build the extension: npm run compile && npm run build:webview
  3. Launch in VS Code:
    • Open this folder in VS Code
    • Press F5 to start an Extension Development Host
  4. In the Dev Host, open the sample test data under testing/ or @testing/
  5. Run “KeyHound: Scan Workspace” or “KeyHound: Scan Current File” from the Command Palette

Packaging a .vsix for local install:

  • npm run package:vsix (requires @vscode/vsce which is in devDependencies).

Commands

  • KeyHound: Scan Current File — scan the active editor
  • KeyHound: Scan Workspace — scan all files (excludes common build folders)
  • KeyHound: Scan Git Diff — scan only lines changed vs. HEAD
  • KeyHound: Open Findings Panel — open the panel view of all current findings
  • KeyHound: Toggle Entropy Rule — enable/disable entropy‑based rule globally
  • KeyHound: Ignore Rule (workspace) — add rule to .keyhoundignore
  • KeyHound: Ignore Path — add a path pattern to .keyhoundignore
  • KeyHound: Ignore Rule (file) — ignore a rule for a specific path
  • KeyHound: Redact Occurrence — replace a match with a placeholder

Using the Findings Panel

Open via “KeyHound: Open Findings Panel”. From the panel you can:

  • Insert an inline ignore next to a specific match
  • Ignore a rule globally or for a single file pattern
  • Redact an occurrence in place
  • Export all current findings as JSON or CSV

Suppression and Ignores

KeyHound supports three layers of suppression:

  • Inline suppressions (within a file)

    • Single line: keyhound-ignore: <ruleId>[, <ruleId>…]
      • Applies to the same line and also to the following line (convenience for comment‑above style)
      • Example: const token = "..."; // keyhound-ignore: slack.bot_token
      • Multiple occurrences on the same line are supported: // keyhound-ignore: generic.high_entropy // keyhound-ignore: slack.bot_token
    • Block: surround a region with:
      • keyhound-ignore-start: <ruleId>[, …]
      • keyhound-ignore-end
  • Workspace ignores (.keyhoundignore at the repo root)

    • rule: <ruleId> — ignore a rule across the workspace
    • rule: <ruleId> -> <glob> — ignore a rule for matching paths
    • path: <glob> — ignore matching paths regardless of rule
    • Globs are matched with picomatch (dotfiles included).
  • Settings

    • KeyHound: Toggle Entropy Rule quickly disables the generic entropy rule.

If inline ignore comments are added/removed, KeyHound performs a full file rescan so findings reappear/disappear immediately.

Rules

Rules live under rules/ and use JSONC (JSON with comments). Each rule conforms to src/config/schema.ts and one of three methods:

  • regex — standard global regex match
    • Example (AWS Access Key ID):
      {
        "id": "aws.access_key",
        "name": "AWS Access Key ID",
        "method": "regex",
        "pattern": "AKIA[0-9A-Z]{16}",
        "severity": "high",
        "confidence": "high",
        "redact": "AWS_ACCESS_KEY_ID"
      }
  • prefix — find tokens that start with one of the configured prefixes and extend through token characters
    • Example (AWS Secret Access Key env lines):
      {
        "id": "aws.secret_access_key",
        "name": "AWS Secret Access Key",
        "method": "prefix",
        "prefixes": ["AWS_SECRET_ACCESS_KEY=", "aws_secret_access_key=\t"],
        "severity": "high",
        "confidence": "medium"
      }
  • entropy — detect long, base64/hex‑ish strings above a Shannon entropy threshold

Additional examples are provided for GitHub, GitLab, Stripe, Google, Slack webhook, npm, Twilio, and MongoDB connection strings.

Redaction placeholder

  • When using the “Redact Occurrence” action, the replacement text is derived from the rule’s redact field and the matched value (see src/redact.ts).

Configuration

User/workspace settings (settings.json):

  • keyhound.enableEntropyRule (boolean, default: true) — enable/disable the generic entropy rule

Internal defaults (see src/config/defaultConfig.ts):

  • entropyThreshold: 4.5
  • ignorePatterns: ["**/fixtures/**", "docs/code/*"] (used by future config)

Test Data

Two directories provide quick, manual validation data:

  • @testing/ — one compact sample per rule; ideal for a quick smoke test

Run “KeyHound: Scan Workspace” in the Extension Development Host to see findings from both.

How It Works

  • Rules are loaded from rules/ and watched for changes (src/scanner/rulesLoader.ts)
  • Scans run on document open/change and on explicit commands (src/extension.ts)
  • Incremental scanning:
    • When a file changes, only the changed ranges are rescanned for speed
    • Findings outside changed ranges are preserved, re‑validated against ignores, and deduplicated
    • Any change touching inline ignore markers triggers a full‑file rescan
  • Diagnostics are published per VS Code URI (src/diagnostics/publish.ts)
  • Only real files are scanned — virtual documents like Git diffs are ignored to avoid duplicates

Performance

  • The scanner operates under a small per‑scan time budget (default ~20ms per design notes) and dedupes results.

Privacy

  • KeyHound runs locally in your editor. No findings or file contents are sent anywhere.

Developing

  • Build: npm run compile
  • Watch (TypeScript): npm run watch
  • Lint: npm run lint
  • Build webview bundle: npm run build:webview
  • Package VSIX: npm run package:vsix

Project layout:

  • src/ — extension entry (extension.ts), scanning engine, diagnostics, UI panel
  • rules/ — detection rules (JSONC)
  • @testing/ — sample data used for manual validation
  • webview/ — small UI to view/export findings

Contributing

  • Add new rules under rules/ using JSONC and include a short sample in @testing/
  • Follow naming: <provider>.<type> for id and title‑case for name
  • Keep regexes as specific and anchored as feasible to reduce noise
  • Prefer confidence: medium or high for precise rules; use low sparingly

If you have a Gitleaks/Kingfisher rule you’d like ported, open an issue or PR with references. We plan to add a converter for common rule formats.

Troubleshooting

  • “Problems shows entries for .git virtual files” — ensure you’re on a build that ignores non‑file URIs (we skip git: scheme).
  • “Inline ignore removed but finding didn’t reappear” — the current build forces a full rescan when ignore markers are added/removed; try saving the file once. If it persists, file an issue with a minimal example.
  • “Too many entropy findings” — run KeyHound: Toggle Entropy Rule to disable, or add inline ignores for specific lines.

Roadmap

  • Rule packs and auto‑update
  • First‑class support for more providers
  • CLI for CI usage (sharing the same engine)
  • Richer config surface (enable/disable by tag, per‑folder thresholds)

About

KeyHound is a local, privacy‑first secret detector for VS Code.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published