Diff two .env/config files and flag risky changes — values are always masked, never shown or sent in full.
Config files drift between environments and deploys, and the risky changes
— a secret quietly cleared, debug mode left on, CORS opened to * — are
easy to miss in a wall of unrelated diffs. envsage diffs two .env files,
masks every value immediately, and flags what actually matters.
$ envsage before.env after.env
~ ALLOWED_HOSTS: ex*******om -> *
~ API_SECRET: ab****************56 -> xy**************12
~ DEBUG: f***e -> ****
RISK (high): ALLOWED_HOSTS — widened to allow everything ('*')
RISK (medium): API_SECRET — value changed, confirm intentional rotation
RISK (critical): DEBUG — debug mode appears to be turned on
- Values are never exposed, anywhere. Masking happens immediately after parsing — every downstream structure (the diff, the risk flags, the optional AI prompt) only ever holds a masked preview. Verified with tests that assert a crafted real-looking secret never appears in output, JSON, or the AI prompt string.
- Deterministic risk detection. Secret-looking keys removed or cleared,
debug flags turned on, host/origin restrictions widened to
*— all flagged by regex/logic, never by asking an LLM to judge it. - Optional AI layer, strictly additive.
--aionly ever receives key names, change types, and masked previews — never a real value, since the real value doesn't exist anywhere past the masking step.
pip install envsageenvsage before.env after.env # diff + risk scan, no AI needed
envsage before.env after.env --ai --provider mock # + AI advice, no key needed
envsage before.env after.env --json # machine-readable output--provider claude (default) · openai · ollama (local, no API key) ·
mock (offline, deterministic). Only used with --ai.
MIT — see LICENSE.