Security Best Practices
Security Best Practices
DotEnv gives you strong encryption by default, but most real-world incidents come from how secrets are handled, not how they're encrypted. This page is the short, practical checklist for running DotEnv safely.
Use least-privilege API tokens
API tokens carry scoped permissions — grant only what the integration actually needs:
- Start from the read-only preset. Most consumers (apps, deploy steps, dashboards) only need to read secrets, not write, decrypt server-side, or rotate keys. The built-in read-only preset grants exactly read access to secrets, projects, targets, environments, and the organization.
- Scope by project and environment. Permissions can be narrowed to a specific project, target, or environment, so a token for a staging service can't touch production.
- Separate decrypt from read.
secret:readreturns ciphertext;secret:decryptis a distinct permission. Only grantsecret:decryptto tokens that genuinely need server-side decryption. - One token per consumer. Give each service/CI job its own token so you can revoke it without disrupting everything else.
See API Keys (web) to create and scope tokens.
Roles at a glance
For people (rather than tokens), assign the least privileged role that lets someone do their job:
| Role | Intended for | Notes |
|---|---|---|
| Owner | Organization owner | Full control, including billing and deletion |
| Administrator | Team/project admins | Manage projects, members, and keys; no billing |
| Member | Day-to-day contributors | Read/write secrets and history (no server decrypt) |
| Developer | Development teams | Broader project/target access, can decrypt |
| Auditor | Compliance / reviewers | Read-only, incl. audit log; no decrypt |
| Billing Manager | Finance | Billing only |
| API User | Integrations | Minimal read + decrypt for automation |
Lock down CI
CI is the most common place secrets leak. Treat it as untrusted:
- Read-only by default. Give CI a read-only, project/environment-scoped token. CI almost never needs to write secrets or rotate keys.
- Inject keys via the runner's secret store, never as plaintext in the workflow file.
- Pass client keys by file, not value. Use
--client-key=<file>so the key never appears in the command line, shell history, or process listing. Avoid passing the literal key string. - Don't print secrets. Never
echoa secret or a key into build output — CI logs are often retained and broadly readable.
Enforce two-factor authentication
- Enable 2FA on every account. DotEnv supports authenticator apps (TOTP), email, and SMS codes.
- Enforce 2FA org-wide for sensitive organizations. Enforcement includes a grace period so members can enrol before access is restricted; after it, members must keep at least one 2FA method enabled to retain access.
- Account settings stay reachable even under enforcement, so you can always finish enrolling.
See Account & Security (web) and Organizations (web).
Rotate keys on a cadence
- Set a regular rotation schedule for encryption keys, and rotate immediately if a key may have been exposed (leaked into chat, a log, a repo, or a departed team member's machine).
- Rotated keys become immutable so historical secret versions stay decryptable; use the re-encrypt-history flow when you need old versions readable under the new key. See Key Management.
- Rotate API tokens too, and revoke any token whose consumer is decommissioned.
Prefer client-side encryption for high-sensitivity projects
For secrets that DotEnv should never be able to read, use client-managed keys. The platform stores only a one-way key-check proof and cannot decrypt your values (zero-knowledge). You take on key custody in exchange — store the passphrase in a password manager or vault, and ensure it's recoverable by more than one trusted person. See Encryption Model and Client-Side Encryption (CLI).
Secret hygiene
.gitignoreyour.envfiles. Pulled secrets land in local files — keep them out of git.- Never paste live secrets, keys, or passphrases into AI chats, tickets, or chat threads. If it happens, treat the value as compromised and rotate it.
- Don't reuse keys across projects or environments. A compromise should be contained to one scope.
- Treat secret names as non-sensitive but secret values as always sensitive — only the value is encrypted.
- Review the audit log periodically to catch unexpected access or changes. See Audit Logging.
Related
Was this article helpful?
Help us improve this article
Thank you for your feedback!