Dotenv Provider
Traditional .env file storage for secrets
Caution
We do not recommend the Dotenv provider for new projects. Use it only for legacy workflows that still require
.envcompatibility. Read Where .env Went Wrong to learn why.
The Dotenv provider stores secrets in local .env files for development setups and compatibility with existing tools.
At a glance
| Provider | dotenv |
| URI | dotenv[:path] |
| Access | Read and write |
| Best for | Local development and compatibility with .env-based tools |
| Authentication | None |
| Default storage | .env next to secretspec.toml (plain text) |
Quick start
# Initialize from existing .env
$ secretspec init --from .env
# Set a secret
$ secretspec set DATABASE_URL --provider dotenv
Enter value for DATABASE_URL: postgresql://localhost/mydb
# Run with secrets
$ secretspec run --provider dotenv -- npm startConfiguration
URI format
# Default (.env next to secretspec.toml)
dotenv
# Custom paths
dotenv:.env.local
dotenv:config/.env
dotenv:/absolute/path/.env
# Home-relative path (0.18+)
dotenv:~/.config/my-project/.env
Starting in SecretSpec 0.18, a leading ~ path component expands to the current user’s home directory.
Environment variable
$ export SECRETSPEC_PROVIDER=dotenv:.env.localProject configuration
secretspec.toml
[providers]
local = "dotenv:.env.local"
[profiles.default]
DATABASE_URL = { description = "Database URL", providers = ["local"] }Storage model
Changed in version 0.20
Dotenv parsing and rendering use dotenv-ng syntax. Dollar signs and expressions such as $TOKEN and ${TOKEN} are literal; the provider does not substitute them from the process environment. When writing, SecretSpec leaves values unquoted when they already round-trip and otherwise double-quotes and escapes them. Keys may include hyphens, leading digits, leading dots, and Unicode, but not whitespace, =, #, or control characters.
Dotenv uses standard KEY=VALUE pairs:
.env
DATABASE_URL=postgresql://localhost/mydb
API_KEY=sk-1234567890
DEBUG=true # Comments supported
# Multi-line values must be quoted
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"
The file itself provides the namespace. Project and profile names are not included in keys; use a different file when environments need separate values:
$ secretspec run --provider dotenv:.env.production -- node server.jsUse existing secrets
By default each secret reads the key named after it. A secret’s ref field reads a key stored under a different name: item is the .env key (field is not supported). Reads and writes target that key in place; the secret’s own name is ignored.
[profiles.default]
DATABASE_URL = { description = "DB", ref = { item = "POSTGRES_URL" }, providers = ["dotenv://.env.shared"] }Security considerations
Caution
Secrets are stored in plain text. Use this provider only where that is acceptable, and always add secret-bearing
.envfiles to.gitignore.
Last updated Oct 11, 2026