▸ Agent Skills
2 min read

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 .env compatibility. 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

Providerdotenv
URIdotenv[:path]
AccessRead and write
Best forLocal development and compatibility with .env-based tools
AuthenticationNone
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 start

Configuration

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.local

Project 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.js

Use 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 .env files to .gitignore.


Last updated Oct 11, 2026