← 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

๐Ÿ”„ Intelligent Lifecycle Management & C6 Diff-Aware Scanning

EnvShield now includes two powerful features designed to make your workflow seamless while catching real security issues:

Intelligent Lifecycle Management

When you run init, service discover, or setup, EnvShield prompts to install Git hooks for you โ€” but only once. The post-merge hook is also smart: it only runs drift detection if schema files actually changed, preventing unnecessary output on code-only merges.

  • Smart Hook Prompting: Asked during initial setup, never spammed again
  • Pre-commit Hook: Scans for secrets before every commit
  • Post-merge Hook (Schema-Aware): Only runs `envshield doctor` if schema files changed

C6: Diff-Aware Secret Scanning

EnvShield's C6 feature solves the "false positives vs. missed secrets" problem by scanning only newly-added lines in excluded files. This is perfect for projects with intentional baseline secrets (like Zeus's local configs with 15+ fake dev secrets).

  • Line-Level Analysis: Compares HEAD vs. staged content to identify new lines
  • Pre-Existing Baseline Ignored: Old secrets don't trigger false positives
  • Real Secrets Caught: New secrets added to excluded files are flagged
  • Zero Configuration: Works automatically when scanning excluded files

Use case: Your local config file has 15 intentional fake secrets (committed to git for dev use). A teammate accidentally adds a real production secret. C6 catches the real secret while not flagging any of the 15 baseline fakes โ€” no false positives, no missed leaks.


๐Ÿ’ก 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, its type/format constraints, 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.

Every field a schema variable can have

Field Example Meaning
description "PostgreSQL connection string" Shown during setup; copied into generated code as documentation.
secret secret = true Hidden input in setup; masked in generated code (SecretStr / Secret<T>). Never given an inferred type during import.
defaultValue defaultValue = "5000" A fallback. Without it, the variable is required.
type type = "port" string (default) | int | float | bool | port (1โ€“65535) | url | email. Enforced by check/doctor/setup; drives the generated type.
enum enum = ["debug","info","warn","error"] Value must be one of these. Implies type = "enum". setup shows a picker, not free text.
pattern pattern = "^v\d+\.\d+\.\d+$" An extra regex constraint, layered on top of type.
requiredIf { var = "X_ENABLED", equals = "true" } Required only when another variable currently holds that value.

A variable with none of type/enum/pattern/requiredIf behaves exactly as it always has โ€” an unconstrained string, required unless it has a default. Schemas written before these fields existed remain fully valid.


๐Ÿงฉ Sharing Variables Across Services (`extends`)

A monorepo with ten services usually has five or six variables every one of them needs โ€” `LOG_LEVEL`, `SENTRY_DSN`, `DATADOG_API_KEY`. A schema can extend a shared base instead of redeclaring them in every service.

shared/base.schema.toml
[LOG_LEVEL]
description = "Log verbosity, shared across every service"
enum = ["debug", "info", "warn", "error"]
defaultValue = "info"

[SENTRY_DSN]
description = "Error tracking"
secret = true
services/api/env.schema.toml
extends = "../../shared/base.schema.toml"

[DATABASE_URL]
description = "API-specific"
secret = true

Loading services/api/env.schema.toml now transparently includes LOG_LEVEL, SENTRY_DSN, and DATABASE_URL โ€” every command just sees the merged result.

  • extends accepts a list, for more than one shared base.
  • Chains work: a base can itself extend another base. A circular chain is detected and rejected.
  • The child's own definition always wins on a conflict, in full โ€” fields aren't merged individually.

Honest limitation: extends resolves a local path within your project โ€” it doesn't fetch a schema from a separate git repository or a package registry today. See the Roadmap.


๐Ÿ“ฆ Validating Deployment Manifests

envshield check accepts a docker-compose file or a Kubernetes manifest, in addition to a plain .env file โ€” auto-detected by content, not extension.

Terminal
envshield check docker-compose.yml
envshield check k8s/deployment.yaml --container api

docker-compose: merges environment: with any env_file: references (environment: wins on a conflict, matching Compose's own precedence). A bare KEY with no value, or anything sourced only from env_file, is treated as present-but-not-visible-here rather than flagged missing.

Kubernetes: Deployment, StatefulSet, DaemonSet, Job, CronJob, and bare Pod manifests, including multi-document (`---`-separated) files. A `ConfigMap`/`Secret` referenced via `envFrom` is resolved if it's defined in the same file; a `valueFrom` reference is treated the same as compose's `env_file` case.

Multiple services/containers in one file? `--container` picks which one. Omit it and EnvShield tries your `--service` name first, before asking you to be explicit.

Register it once: `init`/`service discover`/`service add` auto-detect a compose file and register it. Once registered, plain `envshield check` validates it automatically alongside your `.env`, and `doctor` gains a "Deployment Manifest" health check โ€” shown only for projects that have one registered.

Terminal
envshield service add api services/api --deployment-manifest docker-compose.yml --container api

Honest limitation: EnvShield only reads deployment manifests โ€” it never generates or rewrites one.


๐ŸŽฏ Why EnvShield is Different

EnvShield isn't trying to replace a dedicated secret scanner or a cloud secret manager โ€” it's the schema/contract/codegen layer that sits alongside whichever of those you already use. Here's how it compares to the tools people usually reach for instead:

Capability EnvShield Gitleaks dotenvx Doppler / Infisical
Schema-driven validation (types, enums, conditional requirements) โœ… โŒ โŒ โŒ
Multi-service schema management, with shared/composed schemas โœ… โŒ โŒ Partial (multi-environment, not a documented shared contract)
Typed config code generation โœ… โŒ โŒ โŒ
Validates deployment manifests (compose, Kubernetes) โœ… โŒ โŒ โŒ
Interactive onboarding โœ… โŒ โŒ โœ… (hosted)
Secret detection depth/accuracy โš ๏ธ Good enough for most teams โœ… Best in class, actively maintained โœ… Varies by plan
Syncs real secret values across a team/environments โŒ (never touches real values) โŒ Encrypts values in the file โœ…
Works offline โœ… Always โœ… โœ… Depends on plan/self-hosting

The honest bottom line: if raw secret-detection accuracy is your main concern, run Gitleaks (or similar) alongside `scan` rather than relying on it alone โ€” its maintainers focus on detection full-time, EnvShield's `scan` doesn't try to compete on that axis. If syncing real secret values across a team is your main need, Doppler/Infisical solve that, and EnvShield deliberately doesn't attempt it. What EnvShield is the only thing here that does at all: one schema, in your own git repo, that's simultaneously documentation, a validation contract, a codegen input for two languages, and something your deployment manifests are checked against.


๐Ÿ“– 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, --example-file, --description / -d, --schema (a non-default schema path), and --import <file> to seed its schema in the same step. --deployment-manifest registers a docker-compose file or Kubernetes manifest to validate automatically (auto-detected if omitted โ€” see Deployment Manifests), and --container names which service/container in it is this one, if it isn't named the same. 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 โ€” or, these days, a docker-compose file or a Kubernetes manifest โ€” 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), variables present but not matching their declared `type`/`enum`/`pattern`, and extra variables that aren't in the schema โ€” helping you find configuration errors before they cause runtime bugs, not after. When you don't pass a file argument, it also checks the registered deployment manifest (if any) in the same run โ€” see Deployment Manifests.

Arguments & Flags:

  • [file]: The file to validate. Omit it to check the project's/service's default local file (and its registered deployment manifest, if any).
  • --service / -s: On a multi-service project, which service's schema to check against.
  • --container: For a docker-compose or Kubernetes manifest declaring more than one service/container, which one to check. Tried against `--service`'s name automatically first.

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. Add it as a CI step (see the README's Maintaining EnvShield section) and this becomes a pull-request check, not a post-deploy surprise.


๐Ÿช„ 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, including type/enum/pattern constraints, not just presence.
  • Ensures your `.env.example` file is in sync with the schema.
  • Verifies that the security hook is installed where Git will actually run it (respecting a configured `core.hooksPath`, e.g. Husky).
  • If a deployment manifest is registered for this project/service, validates it too โ€” this check is only shown at all when one actually is.

Flags:

--fix: If the doctor finds a problem, it interactively asks if you want to fix it โ€” re-running `init`, regenerating `.env.example`, installing the hook, or, for missing/blank/invalid local values, running the same `setup` wizard used for onboarding (which fixes exactly what's wrong and leaves everything else untouched).

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.
  • Types each field from its schema's explicit `type`/`enum`/`pattern` when set (`AnyUrl`, `EmailStr`, `Literal[...]`, a regex-constrained string) โ€” or, if none is set, infers `int`/ `bool`/`string` from the shape of `defaultValue`, same as always. 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. See the full field reference above for every key a variable can have โ€” here's a realistic file using several of them together:

env.schema.toml
# A schema can extend a shared base -- see "Sharing Variables Across Services" below.
# extends = "../../shared/base.schema.toml"

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

[API_PORT]
description = "Port the API listens on."
type = "port"
defaultValue = "5000"

[LOG_LEVEL]
description = "Controls the application's log verbosity."
enum = ["debug", "info", "warn", "error"]
defaultValue = "info"

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

[FEATURE_X_ENABLED]
description = "Toggles the new billing flow."
type = "bool"
defaultValue = "false"

[FEATURE_X_API_KEY]
description = "Only needed once feature X is turned on."
secret = true
requiredIf = { var = "FEATURE_X_ENABLED", equals = "true" }

โš™๏ธ 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
    # Auto-detected by `service discover`/`service add`, or set with
    # --deployment-manifest / --container -- see Deployment Manifests above.
    deployment_manifest: docker-compose.yml
    container: api
  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

A single-service/root project registers its deployment manifest at the top level instead (there's no `services:` block to hold it): a bare `deployment_manifest: docker-compose.yml` (and optional `container:`) alongside `project_name`.

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

Everything documented on this page is available now, free, and stays that way โ€” nothing here moves behind a paywall later.

Available now, free, forever โœ…

  • Schema-driven configuration management, with real types, enums, patterns, and conditional requirements
  • Multi-service support, with automatic service discovery and shared/composed schemas (`extends`)
  • Typed config code generation (Python + TypeScript)
  • Deployment-manifest validation (docker-compose, Kubernetes)
  • Interactive onboarding wizard
  • Configuration drift detection
  • Pre-commit secret scanning

Being explored โ€” no committed timeline

What actually gets built next is driven by what real projects hit first, not a fixed plan. Currently under consideration:

  • Team secret sharing & environment coordination: a hosted way to share actual secret values and coordinate per-environment (dev/staging/prod) overrides across a team โ€” the one thing this tool is explicit about not doing today.
  • Cross-repo schema sharing: today's `extends` is local-path-only, within one project. Referencing a base schema across separate repositories isn't supported yet.
  • Secret-manager integrations: pulling real values from Vault/AWS/GCP Secrets Manager for local `setup`/`check`, without EnvShield ever storing them itself.

If any of these would matter to you, open a discussion โ€” real usage, not a roadmap slide, decides what ships next.