keyhog-core 0.5.73

keyhog-core: shared data model and detector specifications for the KeyHog secret scanner
Documentation
# Docs: https://docs.cursor.com/ (API keys issued for the Cursor agent/API)
# Format: `key_` followed by exactly 64 hex chars (a 256-bit token).
# Added: home-turf bench (DET-17) (cursor fixtures were false-negatives).
# Precision: `key_` is a common variable name, but `key_` immediately
# followed by EXACTLY 64 hex chars (and a word boundary) is a specific,
# high-entropy shape that ordinary identifiers do not take.

[detector]
id = "cursor-api-key"
name = "Cursor API Key"
service = "cursor"
severity = "high"
ml = { match_mode = "lift", entropy_mode = "disabled", weight = 1.0, context_radius_lines = 5 }
match_confidence = { literal_prefix_weight = 0.35, context_anchor_weight = 0.20, entropy_weight = 0.20, high_entropy_partial_weight = 0.12, moderate_entropy_threshold = 3.0, moderate_entropy_weight = 0.05, low_entropy_penalty_floor = 2.0, low_entropy_min_match_length = 10, low_entropy_penalty_multiplier = 0.60, keyword_nearby_weight = 0.10, sensitive_file_weight = 0.10, companion_weight = 0.05, very_high_entropy_margin = 1.2999999999999998, named_anchor_floor = 0.55, assignment_context_multiplier = 1.0, string_literal_context_multiplier = 0.9, unknown_context_multiplier = 0.8, documentation_context_multiplier = 0.3, comment_context_multiplier = 0.4, test_context_multiplier = 0.3, encrypted_context_multiplier = 0.05, soft_context_suppression_threshold = 0.5, encrypted_context_suppression_threshold = 0.8, post_match = { placeholder_multiplier = 0.05, minimum_byte_diversity = 0.1, low_diversity_multiplier = 0.1, maximum_repeat_ratio = 0.8, degenerate_run_min_length = 10, degenerate_repeat_multiplier = 0.1, fixture_path_multiplier = 0.5, ml_context_reapply_below = 0.95 } }
keywords = ["key_", "cursor"]
# `key_` + EXACTLY 64 hex is a distinctive 256-bit-token shape; the hex body
# scores below the global 0.40 floor on entropy alone (DET-18). Self-declare a
# lower floor so the detector ships working.
min_confidence = 0.2

[[detector.patterns]]
regex = 'key_[0-9a-fA-F]{64}'
description = "Cursor API key (key_<64 hex>)"
group = 0

[[detector.tests]]
test_positive = "CURSOR_API_KEY=key_8c5a7657fc397e114def1b51dd520410ad50ece61e30b64261ff369ab275ef29"
test_negative = "primary_key_id = 42"