Skip to main content

Detect environment configuration drift before it causes production incidents

Project description

๐Ÿ” Kryptorious DraftGuard

Detect environment configuration drift before it causes production incidents.

Python 3.9+ License: MIT PyPI version

DraftGuard scans your dev, staging, and production config files and catches mismatches, missing keys, default leakage, and secret exposure before they break production.


Quick Start

pip install kryptorious-draftguard

# Scan current directory comparing dev โ†’ prod
draftguard scan .

# Compare specific environments
draftguard scan /app --envs dev,staging,prod

# JSON output for CI/CD pipelines
draftguard scan . --format json --fail-on high

# Audit a single environment for issues
draftguard audit ./prod

# Show detailed key-by-key diff
draftguard diff ./dev ./prod --format markdown

What It Detects

Severity Rule Description
๐Ÿ”ด CRITICAL Missing keys Key exists in .env.example or dev but missing in production
๐Ÿ”ด CRITICAL Secret exposure API keys, tokens, passwords using default/placeholder values
๐ŸŸ  HIGH Value mismatches Same key, different values across environments (unexpected)
๐ŸŸ  HIGH Default leakage Production config still using changeme/localhost defaults
๐ŸŸก MEDIUM Type drift String in dev but number in prod (or vice versa)
โš ๏ธ WARNING Extra keys Keys in production not documented in example files
๐Ÿ”ต INFO Expected diffs DATABASE_URL, DEBUG, etc. โ€” flagged but non-blocking
๐Ÿ”ต INFO Comment drift Documentation comments differ between environments

Smart Detection

  • Knows what's expected: DATABASE_URL, DEBUG, HOST, PORT etc. are flagged as INFO not errors
  • Pattern matching: Recognizes API keys (API_KEY, SECRET, TOKEN, PASSWORD, JWT_*, ENCRYPTION_*)
  • Default detection: Catches changeme, your-*-here, localhost, 127.0.0.1, <placeholder> patterns
  • Type inference: Integer vs string vs boolean vs URL vs duration

Supported Formats

  • .env files (via python-dotenv)
  • .env.example, .env.production, .env.staging, .env.local
  • YAML config files (config.yaml, config.yml)
  • JSON config files (config.json, appsettings.json)
  • TOML config files (config.toml)
  • Docker Compose environment: sections
  • Kubernetes ConfigMap and Secret YAML files

CLI Reference

Usage: draftguard [OPTIONS] COMMAND [ARGS]

Commands:
  scan     Scan directory tree for all config files and compare environments
  compare  Compare two specific config directories
  audit    Audit a single environment for issues (empty values, defaults, weak secrets)
  diff     Show detailed key-by-key diff between two config directories

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

draftguard scan [DIR]

# Basic scan
draftguard scan .

# Multi-environment
draftguard scan /app --envs dev,staging,prod

# JSON output + exit code for CI
draftguard scan . --format json --fail-on critical -o report.json

# Markdown report
draftguard scan . --format markdown -o drift-report.md

# Summary only
draftguard scan . --format summary

draftguard compare DIR1 DIR2

draftguard compare ./dev-configs ./prod-configs
draftguard compare ./dev ./staging --envs development,staging

draftguard audit [DIR]

draftguard audit .              # Auto-detect environment
draftguard audit ./prod --env production
draftguard audit ./prod --fail-on warning

draftguard diff DIR1 DIR2

draftguard diff ./dev ./prod
draftguard diff ./dev ./prod --format json
draftguard diff ./staging ./prod --format markdown

CI/CD Integration

GitHub Actions

name: Config Drift Check

on:
  pull_request:
    paths:
      - '.env*'
      - '**/config.*'
      - 'docker-compose*.yml'
  push:
    branches: [main]

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install DraftGuard
        run: pip install kryptorious-draftguard

      - name: Check config drift
        run: |
          draftguard scan . --envs dev,prod --format json -o draftguard-report.json --fail-on high

      - name: Upload report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: draftguard-report
          path: draftguard-report.json

GitLab CI

drift-check:
  image: python:3.11
  script:
    - pip install kryptorious-draftguard
    - draftguard scan . --envs staging,prod --format json --fail-on critical
  only:
    - merge_requests
    - main

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: draftguard
        name: Config Drift Check
        entry: draftguard scan . --fail-on warning
        language: system
        pass_filenames: false
        always_run: true

Programmatic API

from draftguard.parser import ConfigParser
from draftguard.scanner import ConfigScanner
from draftguard.differ import Differ
from draftguard.rules import DriftRules

# Scan and compare
parser = ConfigParser()
scanner = ConfigScanner(parser=parser)
differ = Differ(parser=parser)

dev_configs = scanner.scan(Path("./dev"))
prod_configs = scanner.scan(Path("./prod"))

result = differ.compare_environments("dev", "prod", dev_configs, prod_configs)

print(f"Found {result.total_findings} issues:")
for finding in result.findings:
    print(f"  [{finding.severity.value}] {finding.key}: {finding.message}")

# Audit single environment
findings = differ.audit_environment("prod", prod_configs)

# Custom rules
rules = DriftRules(expected_diff_keys={"MY_CUSTOM_URL"})
differ = Differ(rules=rules)

Example Output

Table Format (default)

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘         ๐Ÿ” KRYPTORIOUS DRAFTGUARD v1.0.0         โ•‘
โ•‘   Detect config drift before it causes outages   โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

๐Ÿ“‚ Scanning: /app
   Found 6 config files across 3 environments

                        Summary
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Severity  โ”‚ Count โ”‚ Status   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ๐Ÿ”ด CRITICAL โ”‚   3  โ”‚ โŒ FAIL  โ”‚
โ”‚ ๐ŸŸ  HIGH     โ”‚   2  โ”‚ โŒ FAIL  โ”‚
โ”‚ ๐ŸŸก MEDIUM   โ”‚   1  โ”‚ โœ… OK   โ”‚
โ”‚ โš ๏ธ WARNING  โ”‚   0  โ”‚ โœ… OK   โ”‚
โ”‚ ๐Ÿ”ต INFO     โ”‚   5  โ”‚ โœ… OK   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

              Findings (11 issues)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Severity  โ”‚ Category        โ”‚ Key                  โ”‚ Message                              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ๐Ÿ”ด CRITICAL โ”‚ secret_exposure โ”‚ SECRET_KEY           โ”‚ Secret key has default value in dev  โ”‚
โ”‚ ๐Ÿ”ด CRITICAL โ”‚ missing_key     โ”‚ NEW_FEATURE_EXPERโ€ฆ  โ”‚ Key exists in dev but missing in prodโ”‚
โ”‚ ๐Ÿ”ด CRITICAL โ”‚ secret_exposure โ”‚ API_KEY              โ”‚ Secret key has placeholder in dev    โ”‚
โ”‚ ๐ŸŸ  HIGH     โ”‚ value_mismatch  โ”‚ MAX_UPLOAD_SIZE     โ”‚ Value mismatch between dev and prod  โ”‚
โ”‚ ๐ŸŸ  HIGH     โ”‚ value_mismatch  โ”‚ RATE_LIMIT           โ”‚ Value mismatch: 100 vs 1000          โ”‚
โ”‚ ๐ŸŸก MEDIUM   โ”‚ type_drift      โ”‚ PORT                 โ”‚ Integer in dev but string in prod    โ”‚
โ”‚ ๐Ÿ”ต INFO     โ”‚ value_mismatch  โ”‚ DATABASE_URL         โ”‚ Expected difference                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ฅ Premium โ€” Supercharge Your Config Safety

Get the DraftGuard Premium license for just $9 (lifetime, one-time payment):

โœ… Kubernetes-native support โ€” Helm chart value diffs, Kustomize overlays, sealed secrets validation
โœ… Custom rule engine โ€” Write your own drift detection rules in YAML/Python
โœ… Slack / Discord alerts โ€” Real-time notifications when drift is detected
โœ… Team dashboard โ€” Web UI to track drift across all your projects and environments
โœ… Historical trends โ€” Track config changes over time, see drift patterns
โœ… Encrypted secret scanning โ€” Validate values against HashiCorp Vault / AWS Secrets Manager
โœ… Priority support โ€” Direct access to the Kryptorious engineering team

๐Ÿ‘‰ Get DraftGuard Premium โ€” $9 Lifetime


Development

git clone https://github.com/kryptorious/draftguard.git
cd draftguard
pip install -e ".[dev]"

# Run tests
pytest

# With coverage
pytest --cov=draftguard --cov-report=term-missing

# Run linters
ruff check .
black --check .

License

MIT ยฉ Kryptorious


Website ยท GitHub ยท Premium ($9)

Made with โค๏ธ by the Kryptorious team

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kryptorious_draftguard-1.0.0-py3-none-any.whl (24.6 kB view details)

Uploaded Python 3

File details

Details for the file kryptorious_draftguard-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for kryptorious_draftguard-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1800174587463d2c0b546bd5ddca437b84df941d7ff0d94bdf70b1fb846c12a0
MD5 7cc37df21f395feab091ba53f9876985
BLAKE2b-256 8f7a2f7f38ff97cfa327c108ee5cd4ff3fb71699d3e48fd3aef053a6e6544279

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page