Envguard is a dependency-free Go CLI that catches dotenv drift before deployment. It compares one or more environment files with a safe template, rejects duplicate or malformed entries, validates typed constraints from an optional schema, and never prints secret values.
Requires Go 1.25.
go install github.com/1337lean/envguard/cmd/envguard@latestenvguard init --from .env --output .env.example
envguard check --template .env.example .env .env.production
envguard check --template .env.example --schema envguard.json --format json .env
envguard schema check envguard.jsonA runnable contract and development environment are available under examples/:
envguard check --template examples/example.env --schema examples/envguard.json examples/development.envWithout a schema, every template key is required and extra keys produce warnings. --strict-extra promotes extras to errors. When envguard.json exists it is loaded automatically; its absence is allowed only during this implicit discovery. A path supplied with --schema is mandatory and any missing, unreadable, non-regular, or invalid file returns operational exit code 3. Pass --no-schema to disable discovery; it cannot be combined with --schema.
{
"version": 1,
"allowExtra": false,
"variables": {
"APP_ENV": {"required": true, "type": "enum", "values": ["development", "staging", "production"]},
"PORT": {"required": true, "type": "integer", "min": 1, "max": 65535},
"API_URL": {"required": true, "type": "url", "schemes": ["https"]},
"DEBUG": {"type": "boolean", "allowEmpty": true},
"DATABASE_PASSWORD": {"required": true, "type": "string", "secret": true, "minLength": 20}
}
}Supported types are string, integer, number, boolean, url, json, and enum. Constraints are type-specific: strings accept length bounds and a pattern, integer and number accept numeric bounds, enum requires values, and URL accepts schemes. Unknown fields, duplicate JSON keys, duplicate enum values, duplicate schemes, and irrelevant constraints are rejected.
Envguard parses dotenv syntax itself and never shells out, expands variables, or executes substitutions. Inputs are limited to 1 MiB. Diagnostics contain key names, line numbers, and rule names but not values. init writes only sorted keys with blank values and refuses to overwrite unless --force is present.
Exit codes are stable: 0 valid, 1 validation findings, 2 usage error, and 3 operational error.
gofmt -w .
go vet ./...
go test ./...
go test -race ./...
go build ./cmd/envguardSee schema reference and threat model.
MIT