Working with encrypted env files
Dotvault has first-class support for Laravel’s encrypted env file format. You can open, edit, encrypt, decrypt, and rotate keys on .env*.encrypted files entirely from inside the app — no PHP, no artisan env:decrypt, no temporary plaintext copies sitting on disk waiting to embarrass you.
What Laravel’s encrypted env files actually are
php artisan env:encrypt reads your .env, writes an encrypted copy to .env.encrypted, and prints the encryption key once. Pass --env=staging and it works on .env.staging instead, producing .env.staging.encrypted. php artisan env:decrypt goes the other way, taking the key from --key or from a LARAVEL_ENV_ENCRYPTION_KEY environment variable, and refusing to overwrite an existing plaintext file unless you add --force.
The important part is what does not happen. Laravel does not read .env.encrypted at runtime. It reads a plaintext .env, the same as always. So an encrypted env file is a way to keep an env file in your repository, not a way to run your application from one. Something in your deploy has to run the decrypt step before the app boots.
Whether you actually want them
Worth asking before you commit to the workflow, because the answer is often no.
If your .env is gitignored and has never been committed, encrypted env files buy you very little. You already have the property that matters. If you deploy through a managed platform that holds environment variables in its own dashboard, they buy you less than nothing: the platform is not going to run env:decrypt for you, so you are maintaining an encrypted file that nothing reads.
Where they do earn their place is a deploy you control, where the env file genuinely needs to travel with the code. A repo that needs to be clonable and deployable without a side-channel handover. A team that would rather review a change to an encrypted file in a pull request than field a Slack message asking what the new variable is called. If that is your situation, the rest of this guide is for you. If your deploy does not run env:decrypt, the encrypted file is documentation, not configuration.
Supported formats
Dotvault implements Laravel’s encryption itself, using AES-256-CBC and AES-128-CBC with HMAC-SHA256 verification. The cipher follows your key length: 32 bytes gives you AES-256-CBC, 16 gives you AES-128-CBC, and the base64: prefix Laravel uses is handled for you. Both Laravel sub-formats are supported:
- Standard. The entire file is encrypted as a single payload.
- Readable. Variable names are visible; each value is encrypted individually.
Standard is what php artisan env:encrypt writes, and Dotvault writes the same payload, including the PHP string serialisation env:decrypt expects on the way back out. A file Dotvault saves is a file artisan can read. Names and values are both hidden, and a change to one variable rewrites the whole blob, so a diff tells a reviewer only that the file changed.
Readable exists for the review problem. Because the names stay in the clear, a pull request shows which keys changed without showing what they changed to, which is usually the thing a reviewer actually needs. Two things to know before you switch to it. It encrypts KEY=value lines only, so comments and blank lines are dropped, and converting back to Standard does not bring them back. And it is not the shape artisan reads, so if anything outside Dotvault has to decrypt the file, stay on Standard.
The format is detected automatically when you open a file. You can convert between Standard and Readable from the encryption settings in the editor, and the key does not change when you do.
Opening an existing encrypted file
Dotvault detects .env*.encrypted files in your project and marks them in the sidebar. Click one and you’ll be prompted to paste the encryption key. Once the key is accepted:
- The file is decrypted in memory.
- Dotvault stores the key securely, scoped to that file’s absolute path.
- You get the normal editor — edit variables, add sections, run sync — exactly as you would with a plaintext file.
- Saving re-encrypts the file automatically before writing it back to disk.
You only paste the key once per file per machine. Every subsequent open is transparent.
Encrypting a plaintext file
To encrypt a file that isn’t encrypted yet, use the Encrypt button in the editor toolbar, or right-click the file in the sidebar and pick Encrypt. Dotvault generates a key for you, stores it, and writes the encrypted file alongside the original. It’ll also offer to stage the .env*.encrypted file in git for you.
You can paste your own key instead of taking the generated one, which is what you want if the project already has a LARAVEL_ENV_ENCRYPTION_KEY in circulation. Either way you have to tick two boxes confirming you have saved the key somewhere before Dotvault will proceed, because it will not show you that key again afterwards.
The plaintext file is left where it is. Encrypting does not delete it, and you would not want it to: your framework and your test runner still need to read it locally.
What to commit and what to hand over separately
Three rules, and the order matters.
- Commit the
.env*.encryptedfile. That is the whole point of it. - Keep the plaintext file out of git. If it has never been committed, add it to
.gitignoreand leave it there. Right after you encrypt, Dotvault offers to untrack it and add the.gitignoreline for you, alongside staging the encrypted file. - Never commit the key. Not in the repo, not in a
.envvariable in the repo, not in a CI log. It goes in your password manager for people, and in your deploy platform’s secret store for machines, whereenv:decryptcan read it asLARAVEL_ENV_ENCRYPTION_KEY.
One thing untracking does not do is rewrite history. git rm --cached stops the file being committed from now on; it stays in every commit that already contained it, and in every clone anyone has taken. Dotvault says so at the time if the plaintext file has history. If secrets have been in a commit, the fix is not a gitignore line, it is rotating the credentials themselves. There is a guide on env files and git that goes further into that, and one on the mistakes that put them there.
Mislabelled files
Dotvault notices when a file’s name and its actual contents don’t match. If a file is named .env.encrypted but actually contains plaintext (or vice versa), you’ll get a warning. The detector is tri-state — encrypted, mislabelled, or plaintext — and uses both the filename pattern and a content sniff, so it won’t be fooled by a rename alone.
Path-scoped keys
Encryption keys in Dotvault are scoped to the absolute path of the encrypted file. That means:
- Two different encrypted files in two different projects have two completely independent keys.
- Keys are encrypted at rest via
safeStorage, protected by your macOS Keychain, and are never written to disk in plaintext. - Keys survive the file being removed and re-added inside Dotvault.
If you rename an encrypted file, always do it from inside Dotvault — right-click the file and pick Rename. Dotvault atomically renames the file on disk and migrates the keychain entry along with it, so you don’t have to paste the key again. If you rename the file outside Dotvault, the keychain entry is orphaned; Dotvault will prompt you for the key the next time you open the renamed file, and it tidies up the orphaned entry automatically on the next launch.
Rotating keys
If you suspect a key has leaked — or you saved it somewhere you shouldn’t have — use Rotate key. Dotvault generates a new key, re-encrypts the file’s contents with it, and replaces the stored key. Save the new key somewhere safe (a password manager) immediately: Dotvault deliberately never shows the key again after first save.
Rotation happens in place, keeps the file’s current format, and does not change the variables inside. What it cannot do is reach backwards. Every copy of the file that was encrypted with the old key is still readable by anyone holding that key, including whichever commit you were worried about and whichever teammate has left. So rotating the env file’s key and rotating the secrets inside it are two separate jobs, and if the file itself got out, you need both.
If you lose the key
While Dotvault still has the key stored, you are fine: open the file, hit Rotate key, and save the new one properly this time.
If you’ve lost both the Dotvault keychain entry and any external copy, the file is unrecoverable. That’s how encryption is supposed to work. There is no recovery flow, no support override and no reset link, and the longer answer on that spells out why.
Going back to plaintext
If you decide the workflow is not for you, right-click the encrypted file in the sidebar and pick Decrypt to plaintext. Dotvault writes the decrypted contents to the same filename without the .encrypted suffix, then removes the encrypted file and its stored key, and it says so before it does it. That is a one-way door for that file: you are not left holding both versions, and the key is gone. Encrypt again afterwards and you get a new one.
Sharing with your team
Commit the .env*.encrypted file to git. Share the key through your password manager — never in chat, never in email, never in the repo itself. Each teammate opens the file in Dotvault, pastes the key once, and from then on it’s transparent for them too.
A teammate needs no PHP and no artisan to do that, which is an answer in its own right. Encrypted files also take part in comparison and sync exactly like plaintext ones, so an encrypted production file can be kept in step with a plaintext local one. If you want the cryptographic specifics rather than the workflow, the security page lists them.