Summary
detect._SENSITIVE_PATTERNS's .env/.envrc regex:
re.compile(r'(^|[\\/])\.(env|envrc)(\.|$)', re.IGNORECASE)
matches any .env-prefixed filename followed by . or end-of-string — so it flags .env.example, .env.sample, .env.template, .env.dist, .envrc.example, etc. identically to real secret files like .env, .env.local, .env.production. There's no carve-out for the well-known "safe to commit" template-suffix convention.
Observed (graphifyy 0.9.25)
graphify-init on a repo containing a template .env.example (documented example vars only, no real secrets) reports it under skipped_sensitive, so it's silently absent from the graph.
>>> import re
>>> pat = re.compile(r'(^|[\\/])\.(env|envrc)(\.|$)', re.IGNORECASE)
>>> [(n, bool(pat.search(n))) for n in
... ['.env', '.env.example', '.env.sample', '.env.template', '.env.local', '.envrc']]
[('.env', True), ('.env.example', True), ('.env.sample', True),
('.env.template', True), ('.env.local', True), ('.envrc', True)]
No current escape hatch
Why this differs from the #1225 "no broad override" stance
PR #1921's discussion intentionally keeps Stage 2 patterns (.env, key files, secrets dirs) hard-excluded so a user's broad allowlist glob can't accidentally pull in a real secret file. This request is narrower: a specific, principled suffix carve-out for a naming convention whose entire purpose is "safe to commit," not a user-controlled allowlist. It doesn't reopen the risk #1921 is guarding against.
Suggested fix
Exempt filenames ending in a known template suffix ahead of the Stage 2 check:
_ENV_TEMPLATE_SUFFIXES = ('.example', '.sample', '.template', '.dist')
if not (re.search(r'\.(env|envrc)\.', name, re.IGNORECASE)
and name.lower().endswith(_ENV_TEMPLATE_SUFFIXES)):
if any(p.search(name) for p in _SENSITIVE_PATTERNS):
return True
Happy to open a PR if this shape looks right to a maintainer.
Summary
detect._SENSITIVE_PATTERNS's.env/.envrcregex:matches any
.env-prefixed filename followed by.or end-of-string — so it flags.env.example,.env.sample,.env.template,.env.dist,.envrc.example, etc. identically to real secret files like.env,.env.local,.env.production. There's no carve-out for the well-known "safe to commit" template-suffix convention.Observed (graphifyy 0.9.25)
graphify-initon a repo containing a template.env.example(documented example vars only, no real secrets) reports it underskipped_sensitive, so it's silently absent from the graph.No current escape hatch
.graphifyignore!negation only affects_is_ignored();_is_sensitive()never consultsignore_patterns, so it can't rescue a Stage 2 hit..graphifyincludeis dead (.graphifyinclude is dead code: loaded on every detect() run but never consumed #2112) — current code just warns and points at.graphifyignorenegation, which (per above) doesn't actually work here.--excludefeeds the same_is_ignoredpath as.graphifyignore.Why this differs from the #1225 "no broad override" stance
PR #1921's discussion intentionally keeps Stage 2 patterns (
.env, key files, secrets dirs) hard-excluded so a user's broad allowlist glob can't accidentally pull in a real secret file. This request is narrower: a specific, principled suffix carve-out for a naming convention whose entire purpose is "safe to commit," not a user-controlled allowlist. It doesn't reopen the risk #1921 is guarding against.Suggested fix
Exempt filenames ending in a known template suffix ahead of the Stage 2 check:
Happy to open a PR if this shape looks right to a maintainer.