← Back to Main Site

Documentation

๐Ÿš€ Quick Start Guide

Go from a chaotic environment to a single Environment Contract โ€” documented, validated, and compiled into typed code โ€” in less than 5 minutes. This guide will walk you through the essential workflow.

๐ŸŽฌ Prefer visual learning? Check out the Features & Examples page for real-life walkthroughs with before/after scenarios and animations.

1. Install EnvShield

You'll need Python 3.10 or newer. Install EnvShield directly from PyPI โ€” it's a standalone CLI, no dependencies on your project's stack.

Terminal
pip install envshield

2. Initialize Your Project (Three Paths)

Choose the path that fits your project. All three create a schema (`env.schema.toml`) that becomes your single source of truth.

Option A: Brand New Single-Service Project
# Scaffolds a schema from your framework (Next.js, Django, Flask, etc.)
# Also creates a git hook and updates .gitignore
envshield init
Option B: Existing Single-Service Project (Faster!)
# Reads your existing .env file and auto-generates 90% of the schema
# The tool detects secrets, suggests defaults, and saves you manual work
envshield import .env.production --interactive
Option C: Multi-Service Monorepo
# Finds every service (api, web, worker, ...), registers them, and seeds
# each schema from that service's own real, current config -- in one command
envshield service discover

๐Ÿ’ก Verified example: we ran envshield import against a real 59-variable Flask config โ€” it correctly classified all 27 secrets and suggested real default values for 15 of the non-secret variables, with zero manual TOML written.

3. Curate Your Schema (The Contract)

Open the newly created `env.schema.toml`. This is your Environment Contract โ€” the single source of truth for all configuration. Review each variable, add human-readable descriptions, and mark which ones are secrets. This is the ONLY file you'll hand-edit.

env.schema.toml
[DATABASE_URL]
description = "The full connection string for the database."
secret = true

[LOG_LEVEL]
description = "Controls the application's log verbosity (DEBUG, INFO, WARNING, ERROR)"
secret = false
defaultValue = "info"

[STRIPE_API_KEY]
description = "Stripe API secret for payment processing"
secret = true

๐Ÿ’ก Why this matters: This schema now drives everything โ€” your `.env.example` generation, your typed config code, your validation, your onboarding wizard. Once it's right, everything stays in sync automatically.

4. Sync Documentation & Setup Your Environment

Now generate your `.env.example` (documentation) from the schema, and create your local `.env` file interactively. EnvShield will prompt you for each variable, hide secrets as you type, and validate everything.

Terminal
# Generate .env.example from your schema (docs stay in sync)
envshield schema sync

# Interactively create your local .env (you'll be prompted for each var)
envshield setup

# Or create a different env file:
envshield setup .env.local

๐Ÿ’ก What just happened: Your `.env.example` was regenerated from the schema (never stale again), and you created your local `.env` without any manual copy-paste or guessing about which vars are secrets.

5. You're All Set!

Your environment is now secure and documented. The Git pre-commit hook is active and will scan for secrets before each commit. Your configuration is guaranteed to be in sync with your schema. You're ready to go!

Terminal
# Verify everything is in order
envshield doctor

# Now build something amazing!
python app.py  # or npm start, etc.

6. (Optional) Compile Your Contract Into Code

Turn the schema into the actual config your app imports โ€” typed, validated, and with secrets masked by default. Auto-detected for your stack, or set explicitly with --lang.

Terminal
# Python (pydantic-settings)
envshield generate --lang python

# TypeScript (zod)
envshield generate --lang typescript

๐Ÿ’ก Core Concepts: The Environment Contract

EnvShield treats configuration as a **contract** โ€” a formal agreement between your schema and your application. Understanding these three artifacts is key to mastering this workflow. Only the first one is hand-written โ€” the other two are always generated from it.

  • The Schema (`env.schema.toml`): This file is the **Environment Contract** itself. It's the undisputed source of truth, defining every variable your project needs, what it does, whether it's a secret, and if it has a default value. It lives in your repository and is version-controlled like the rest of your code.
  • The Example File (`.env.example`): This file is the **human-readable documentation**. It's a build artifact that is automatically generated from your schema via the `schema sync` command. You never edit this file by hand; you commit it so that anyone browsing your repository can quickly understand the configuration requirements without needing the tool installed.
  • The Generated Config Module: This is the **machine-readable enforcement** of the contract. Running `envshield generate` compiles the schema into real, importable `pydantic-settings` (Python) or `zod` (TypeScript) code โ€” your application reads its configuration through this typed, validated module instead of raw `os.getenv`/`process.env` calls.

๐ŸŽฏ Why EnvShield is Different

Most configuration tools solve one piece of the problem โ€” scanning, encryption, or cloud storage. EnvShield's focus is different: a schema-driven contract that works across multiple services in the same repo. Here's how it compares to the tools people usually reach for instead:

Feature EnvShield Gitleaks dotenvx Infisical
Schema-driven configuration โœ… Unique โŒ โŒ โŒ
Multi-service support โœ… Built-in โŒ โŒ โŒ
Typed config code generation โœ… Unique โŒ โŒ โŒ
Interactive onboarding โœ… โŒ โŒ โœ… Cloud-only
Works offline โœ… โœ… โœ… โŒ

The bottom line: Gitleaks detects secrets. dotenvx encrypts files. Infisical stores secrets in the cloud. EnvShield takes a different approach: a versioned schema that drives documentation, validation, onboarding, and typed code generation โ€” for one service or many โ€” all in one local-first CLI.


๐Ÿ“– A-to-Z Command Reference

๐Ÿ—๏ธ init

The "zero-to-hero" command. Run this first in a new project to scaffold a complete, best-practice configuration foundation.

What it does:

  • Intelligently inspects your project to detect the framework (e.g., Next.js, Django).
  • Creates an `env.schema.toml` file with smart defaults for that framework.
  • Creates a simple `envshield.yml` configuration file.
  • Safely updates your `.gitignore` file with necessary patterns.
  • Automatically installs the Git pre-commit hook for proactive security.

Flags:

--force or -f: Allows `init` to overwrite existing EnvShield files. It will always ask for a final confirmation before proceeding.

Use Case

You're starting a new Django project. You run `envshield init`. The tool detects Django, creates a schema with `SECRET_KEY` and `DATABASE_URL`, updates your `.gitignore`, and installs the security hook. Your project is set up for success in one command.

Already have more than one service in this repo? `init` bootstraps a single schema โ€” for a multi-service project, use `envshield service discover` instead.


๐Ÿšš import

The "get started yesterday" command. This is the fastest way to adopt EnvShield for an existing project with a large, messy `.env` file.

What it does:

  • Reads an existing `.env` file (like `.env.production`).
  • Intelligently analyzes each variable's key and value.
  • Automatically marks known secrets (API keys, tokens) using its built-in scanner logic.
  • Suggests default values for common variables (like `DEBUG` or `PORT`).
  • Generates a complete `env.schema.toml` file for you.

Arguments & Flags:

  • <file>: (Required) The path to the `.env` file you want to import.
  • --output or -o: Specify a different output path for the schema file (default: `env.schema.toml`).
  • --force or -f: Allows `import` to overwrite an existing schema file.
  • --interactive: Walks you through each variable one by one, letting you confirm if it's a secret and if you want to set a default value.

Use Case

You want to adopt EnvShield for a 2-year-old project. You run the command:

Terminal
envshield import .env --interactive

The tool guides you through all 50 variables, correctly guessing 45 of them, and generates a perfect schema file in two minutes instead of an hour of manual work.


๐Ÿ”ญ service

The fast path for multi-service projects. A subcommand with three actions: discover, add, and list.

discover โ€” What it does:

  • Scans your repo for directories that look like independent services โ€” a real dotenv file (any .env.* name, not just .env), or a recognizable Python config module.
  • Skips a directory that only has a generic project marker (pyproject.toml, package.json) with no actual config in it โ€” a shared library sitting next to your real services won't get mistaken for one.
  • Shows you what it found and asks before writing anything.
  • On confirmation, registers each service in envshield.yml and seeds its schema straight from its real, current config โ€” the same logic as import.
  • Safe to run again later: already-registered services are never re-suggested or touched. It bootstraps a fresh setup from nothing, or extends an existing one with whatever's new.
Terminal
$ envshield service discover

                     Discovered Services
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
โ”ƒ Name   โ”ƒ Directory      โ”ƒ Format โ”ƒ Config File           โ”ƒ
โ”กโ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ฉ
โ”‚ api    โ”‚ services/api   โ”‚ dotenv โ”‚ (default .env)        โ”‚
โ”‚ web    โ”‚ services/web   โ”‚ dotenv โ”‚ (default .env)        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
? Add these services to envshield.yml? (api, web pre-selected) Yes
โœ“ Registered api โ†’ services/api/env.schema.toml
โœ“ Registered web โ†’ services/web/env.schema.toml

add & list

envshield service add <name> <directory> registers one service by hand โ€” useful when you'd rather be explicit than rely on detection, with --local-file, --description, and --import <file> to seed its schema in the same step. envshield service list prints every service currently configured.

Use Case

You're adopting EnvShield in an existing Turborepo with five apps. Instead of hand-writing envshield.yml and running import five times, one command finds them all, and one confirmation seeds all five schemas from their real, current .env files.


๐Ÿ’ช scan

Your project's personal bodyguard. It scans files for hardcoded secrets and undeclared environment variables used in your code.

Arguments & Flags:

  • [PATHS]...: The specific files or directories to scan. If you don't provide a path, it scans the current directory.
  • --staged: Scans only the files you've staged for your next Git commit. This is the heart of the pre-commit hook.
  • --config <file>: Use a different `envshield.yml` for this specific scan.
  • --exclude <pattern>: A glob pattern to exclude from this specific scan. Can be used multiple times.

Use Case

Your pre-commit hook is blocking a commit because of a secret in a test file. You realize you forgot to add an exclusion rule. You can add it to `envshield.yml` to fix it permanently, or use a one-off command to bypass it for now:

Terminal
git commit -m "My commit" --no-verify # Bypass the hook for now
envshield scan . --exclude "**/tests/*"

๐Ÿ›‘ install-hook

Manually installs the Git pre-commit hook if you skipped it during `init` or if it was removed.

What it does:

Creates (or overwrites) a `pre-commit` script in your `.git/hooks/` directory that runs `envshield scan --staged`.

Use Case

You've added `envshield` to a project that already had a different pre-commit hook. After you manually merge the two scripts, you can run `envshield install-hook --force` to create the final, combined hook.


๐Ÿ“š schema

The `schema` command is a subcommand with one action: `sync`. It's your primary tool for keeping your project's documentation (`.env.example`) perfectly in sync with your schema.

Usage

Terminal
envshield schema sync

Use Case

You add a new `REDIS_URL` variable to your `env.schema.toml`. Before you commit, you run `envshield schema sync`. The `.env.example` is instantly and correctly updated with the new variable and its description, ready to be committed.


โœ… check

The "is it plugged in?" command for your local setup. It validates a local environment file against the official contract in `env.schema.toml`.

What it does:

It reports variables missing entirely, variables declared but still left blank (e.g. a required secret checked in as an empty placeholder), and extra variables that aren't in the schema โ€” helping you find configuration errors before they cause runtime bugs, not after.

Use Case

Your app fails to start after a teammate's PR. You run the command:

Terminal
envshield check .env.local

The tool reports `Missing in Local: NEW_SERVICE_API_KEY`, instantly telling you what's wrong.


๐Ÿช„ setup

A taste of the automated onboarding magic. This is the perfect command for getting started on a project.

What it does:

It looks at whatever you already have โ€” your real local file if one exists, or `.env.example` as a template if not โ€” and prompts you only for variables that are still blank or missing, showing each one's description and masking input for secrets. On a multi-service project, running it with no `--service` asks which one (or All services, walking through each service's wizard in turn). If your local config isn't a dotenv file โ€” e.g. a Python module โ€” it patches just the missing values into it in place, instead of overwriting the file.

Use Case

You just cloned a new project. You run `envshield setup`. The tool asks you for the `DATABASE_URL` and `STRIPE_API_KEY`, then generates your fully-populated `.env` file. You are ready to run the project in minutes.


๐Ÿฉบ doctor

The "turn it off and on again" command for your entire configuration. It runs a comprehensive suite of health checks on your project's `envshield` setup.

What it does:

  • Checks that your `envshield.yml` and `env.schema.toml` files exist and are valid.
  • Validates your local `.env` file against the schema.
  • Ensures your `.env.example` file is in sync with the schema.
  • Verifies that the security hook is installed and active.

Flags:

--fix: The magic wand. If the doctor finds a problem, it will interactively ask you if you want to fix it automatically.

Use Case

Something just feels wrong with your setup. You run `envshield doctor`. It reports that your `.env.example` is out of date and the Git hook is missing. You run `envshield doctor --fix`, answer "Yes" to both prompts, and the tool fixes everything for you.


๐Ÿงฌ generate

The command that turns your contract into code. It compiles `env.schema.toml` into a typed, validated config module โ€” no more raw `os.getenv()` / `process.env` calls scattered through your codebase, and no more secrets that can accidentally end up in a log line.

What it does:

  • Renders every variable in your schema into a real, importable module: `pydantic-settings` for Python, or a `zod`-validated module for TypeScript.
  • Infers each variable's type (`str`, `int`, `bool` / `string`, `number`, `boolean`) from its `defaultValue`. Variables with no default become required fields โ€” the module raises a validation error at import time if they're missing.
  • Wraps every `secret = true` variable in a masked type (`SecretStr` in Python, a local `Secret<T>` wrapper in TypeScript) so it can't accidentally leak via a `print()`, `console.log`, `JSON.stringify`, or stack trace. You call `.get_secret_value()` / `.value` explicitly to read it.

Arguments & Flags:

  • [output_file]: Where to write the generated module. Defaults to `config.py` or `config.ts` depending on the resolved language.
  • --lang or -l: `python` or `typescript`. If omitted, EnvShield auto-detects from your project the same way `init` does โ€” Next.js, Vite, and Node.js projects default to TypeScript; everything else defaults to Python.
  • --force or -f: Allows `generate` to overwrite an existing output file.

Use Case

Your Next.js app currently reads `process.env.STRIPE_SECRET_KEY` directly in six different files, with no validation that it's actually set. You run:

Terminal
envshield generate --lang typescript

EnvShield writes `config.ts` with a `zod` schema built from your contract. You replace the six direct `process.env` reads with `import { env } from './config'` โ€” now a missing or malformed variable fails loudly at startup instead of silently at runtime, and `env.STRIPE_SECRET_KEY` prints as `**********` anywhere it's accidentally logged.


โš™๏ธ The `env.schema.toml` File

This file is the heart of your configuration. It's a TOML file where you define every environment variable your project needs. Here's a breakdown of the keys for a variable:

env.schema.toml
[DATABASE_URL]
# (Required) A human-readable explanation of what this variable is for.
# This is used to generate comments in your .env.example file.
description = "The full connection string for the PostgreSQL database."

# (Required) A boolean that marks the variable as sensitive. Used right now
# by `setup` (hides the value as you type it) and `generate` (wraps it in
# SecretStr / a Secret type so it can't leak into a log line by accident).
secret = true

# (Optional) A default value for the variable.
# If a variable has a defaultValue, `envshield check` will not report it as missing.
# It will also be pre-filled in your .env.example file.
defaultValue = "postgres://user:pass@localhost:5432/mydb"

โš™๏ธ The `envshield.yml` File

This file controls EnvShield's own settings โ€” and, for a multi-service project, it's where every service is registered. envshield service discover writes this file for you (see below); this is what it looks like under the hood.

envshield.yml โ€” single service
# The name of your project (used for display purposes).
project_name: my-project

# Global settings for the secret scanner.
secret_scanning:
  # A list of file patterns to ignore during scans (e.g., test files).
  exclude_files:
    - "**/tests/*"
    - "**/test/*"
envshield.yml โ€” multi-service
services:
  api:
    path: services/api/env.schema.toml
  web:
    path: services/web/env.schema.toml

  # A service whose local config isn't a dotenv file at all -- e.g. a
  # Flask app that keeps its local config in a plain Python module --
  # points `local_file` at it directly. EnvShield reads/writes it as
  # source, patching or appending plain assignments in place rather
  # than treating it like a dotenv file.
  worker:
    path: services/worker/env.schema.toml
    local_file: services/worker/config/settings.local.py

Every command accepts --service <name>. Omit it on a single-service project and nothing changes; omit it on a multi-service project and you're prompted โ€” pick one service, or All services to run against every one of them in the same command.


๐Ÿ›ฃ๏ธ Roadmap: The Future is Bright

Phase 1 is the free, powerful foundation. But the journey doesn't end here. Upcoming paid tiers will turn EnvShield into a complete collaboration and automation platform for teams and enterprises.

Phase 1: The Local Guardian (Free, Live Now) โœ…

Everything you need for a single developer or small team:

  • Schema-driven configuration management
  • Multi-service support, with automatic service discovery
  • Typed config code generation (Python + TypeScript)
  • Interactive onboarding wizard
  • Configuration drift detection
  • Pre-commit secret scanning

Phase 2: The Team Collaborator (Paid Tier, Coming Soon)

Scale to teams with environment profiles and automation:

  • Environment Profiles: Switch between dev/staging/prod configurations with one command.
  • Schema Diffing: See exactly what configuration changed between environments.
  • Automated Onboarding: Setup command that also runs database migrations, docker compose, and custom scripts.
  • Team Collaboration: Securely share secrets with teammates via encrypted links.
  • CI/CD Integration: Validate configuration before deployment, inject secrets into pipelines.

Phase 3: The Enterprise System (Paid Tier, Future)

Mission-critical features for large organizations:

  • Cloud Secret Vault: Optional centralized backend for teams that need it (not required, everything still works locally).
  • Vault Integration: Pull secrets from HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, etc.
  • Audit Logs & RBAC: Complete compliance trail of all secret access with role-based access control.
  • Policy Engine: Enforce naming conventions, require descriptions, mandate secrets for certain patterns.