Show HN: ConfigLedger -Find configuration drift across code, CI, Docker and docs ConfigLedger, a new open-source CLI tool from DevFoundry-labs, detects configuration drift across code, CI, Docker, and documentation without collecting secret values. The tool, available in v0.1, scans multiple surfaces including Python, JavaScript, Docker, and Kubernetes YAML, and flags issues like undefined consumption and sensitive literals. It requires Python 3.12 or newer and can be installed via pip. Find configuration drift across code, examples, CI, containers, deployment YAML, and docs—without collecting secret values. ConfigLedger is a local, deterministic CLI for answering questions that are surprisingly hard in a real repository: - Where is DATABASE URL consumed, delivered, exemplified, and documented? - Which active keys have no documented setup path? - Which sample or deployment defaults disagree? - Which example keys are unused? - Did someone put a literal value next to a sensitive-looking key? It runs offline, executes no repository code, needs no account, and sends nothing to an AI service. bash $ configledger scan examples/demo --no-cache --fail-on none ConfigLedger Scanned 4 artifacts; found 4 configuration keys. Findings: 1 critical, 2 high, 2 medium, 1 low. CRITICAL config.sensitive-literal — SUPPORT TOKEN SUPPORT TOKEN looks sensitive and has a non-placeholder literal in an example surface. - .env.example:3 example - app.py:5 consumption HIGH config.undefined-consumption — ANALYTICS KEY ANALYTICS KEY is consumed but no definition, example, or delivery surface was found. - app.py:4 consumption Environment and configuration keys are duplicated across source code, .env.example , Docker, CI, Kubernetes, and documentation. Format-specific linters see one file type; secret scanners look for leaked values. ConfigLedger builds a source-linked, per-key provenance record across all of those surfaces and evaluates transparent drift rules. ConfigLedger does not replace a secret manager, configuration loader, or vulnerability scanner. It deliberately analyzes names and safe metadata—not runtime values. ConfigLedger requires Python 3.12 or newer. python -m pip install configledger For development or before the first package-index release: git clone https://github.com/DevFoundry-labs/configledger.git cd configledger python -m pip install . Scan the current repository: configledger scan . Try the reproducible included demo without letting findings change the shell exit code: configledger scan examples/demo --no-cache --fail-on none Export machine-readable or review-friendly output: configledger scan . --format json --output configledger-report.json configledger scan . --format markdown --output configledger-report.md configledger scan . --format schema --output .env.generated.example Inspect one key: configledger show DATABASE URL . | Surface | Evidence recognized in v0.1 | |---|---| | Python | os.getenv , os.environ , Pydantic-style settings and aliases | | JavaScript / TypeScript | process.env.KEY , indexed access, import.meta.env.KEY | | Dotenv examples | .env.example , .env.sample , .env.template | | Dockerfile | ARG , ENV , and variable references | | Docker Compose / YAML | environment , env , and interpolated variables | | GitHub Actions | env , vars , and secrets references | | Kubernetes-like YAML | env entries and name keys confidence-tagged | | Markdown | Backticked keys, tables, and key/value-style references | Unsupported or ambiguous syntax is reported as a diagnostic or omitted. ConfigLedger never treats incomplete static evidence as proof that runtime configuration is safe. | Rule | Default severity | Meaning | |---|---|---| config.undefined-consumption | High | A consumed key has no definition, example, or delivery evidence. | config.unused-declaration | Low | A defined/example key has no consumption or delivery evidence. | config.undocumented | Medium | An active key has no Markdown documentation evidence. | config.default-drift | High | Non-secret default fingerprints disagree across surfaces. | config.sensitive-literal | Critical | A sensitive-looking key has a non-placeholder literal in an example. | List rules from the installed version: configledger rules Create .configledger.toml at the repository root: scan ignore paths = "vendor/ ", "generated/ " ignore keys = "TEST ONLY " internal keys = "CI", "INTERNAL " max files = 5000 max file bytes = 1000000 max total bytes = 25000000 rules disabled = "config.unused-declaration" fail on = "high" info, low, medium, high, critical, or none rules.severity "config.undocumented" = "low" Command-line --fail-on overrides the policy for that run. See configuration reference /DevFoundry-labs/configledger/blob/main/docs/configuration.md . Baselines contain finding fingerprints, not configuration values: configledger baseline create .configledger-baseline.json . configledger baseline compare .configledger-baseline.json . The compare command exits with status 1 when new fingerprints appear. | Code | Meaning | |---|---| | 0 | Scan completed and no finding met the failure threshold. | | 1 | Findings met the threshold, a key was not found, or baseline comparison found new findings. | | 2 | Invalid path, policy, report path, or other usage error. | | 3 | Reserved for unexpected internal failures. | .env , .env.local , private keys, binaries, and common dependency/build directories are excluded before reading.- Example/deployment literals are represented by hashes and redacted excerpts; raw values are not stored in reports or SQLite. - Repository modules, scripts, containers, and workflows are never executed. - Discovery is bounded and rejects out-of-root symlink reads. - Core operation is offline and has no telemetry or AI provider. Read the threat model /DevFoundry-labs/configledger/blob/main/docs/threat-model.md and security policy /DevFoundry-labs/configledger/blob/main/SECURITY.md before scanning untrusted repositories in sensitive environments. safe discovery → format extractors → normalized occurrences → per-key provenance → deterministic rules → reports / SQLite cache The CLI, library API, persistence model, and reporter boundaries are described in architecture.md /DevFoundry-labs/configledger/blob/main/docs/architecture.md . The versioned JSON contract is scan-result.schema.json /DevFoundry-labs/configledger/blob/main/schemas/scan-result.schema.json . python -m venv .venv Windows: .venv\Scripts\activate macOS/Linux: source .venv/bin/activate python -m pip install -e ". dev " ruff format --check . ruff check . mypy src pytest --cov=configledger --cov-report=term-missing python -m build See CONTRIBUTING.md /DevFoundry-labs/configledger/blob/main/CONTRIBUTING.md for extractor and rule contribution guidance. - v0.1: Local inventory, six extractor families, five rules, four report formats, baselines, SQLite cache. - v0.2: SARIF, richer framework adapters, GitHub Action annotations, ignore explanations. - v0.3: Stable extractor SDK and community compatibility fixtures. The project will remain local-first and deterministic. New features must improve configuration provenance rather than turn ConfigLedger into a secret manager or generic code-intelligence platform. Apache License 2.0. See LICENSE /DevFoundry-labs/configledger/blob/main/LICENSE .