How to Commit Secrets Safely with Encrypted Environment Files

env_encrypted: lets you commit .env.encrypted to git — Laravel's own format, decrypted by Neo in memory at deploy.

6 min read v0.24.0

The problem

Secrets have to live somewhere. .env files are the usual answer, and the usual answer to keeping them safe is "don't commit it" — which works until someone forgets, or until you need the same secret reproducibly in CI without a separate manual step.

Encrypt once, commit the result

php artisan env:encrypt

This is Laravel's own command — the format is Illuminate\Encryption\Encrypter's, not something Neo invented. It prints a key once (store it in a password manager) and writes .env.encrypted, which is safe to commit: without the key, it's unreadable.

env_encrypted: .env.encrypted

At deploy, Neo decrypts it in memory — the plaintext never touches disk on the server.

Where the key comes from

In order, first match wins: --env-key flag, NEO_ENV_KEY, LARAVEL_ENV_ENCRYPTION_KEY (the same variable Laravel's own env:decrypt reads — a CI pipeline that already sets it needs no Neo-specific setup), a key saved in ~/.neo/keys.json, or an interactive prompt that offers to save it for next time.

neo env key set my-app base64:xxxxx   # save once, deploys stop prompting
NEO_ENV_KEY=base64:xxxxx neo deploy   # CI: no prompt at all

Without PHP handy

neo env encrypt      # writes .env.encrypted — byte-compatible with php artisan env:decrypt
neo env decrypt --stdout

Useful on a machine without PHP, or in a CI image that doesn't carry the full Laravel toolchain.

What this protects, and what it doesn't

This protects your repository and your laptop — the plaintext secret is never visible in either. It does not protect the server at rest: decrypted values still ship as ordinary container environment variables and are stored in /etc/neo/state.json on the server (root-only, mode 0600). If you need secrets that never touch server state at all, that's a different, harder problem — Neo's encryption is specifically about keeping secrets out of git and off your development machine.

A wrong key fails loudly, not silently

A mistyped key fails the decryption's MAC check and aborts the deploy rather than shipping with garbage values — and importantly, it's not cached until it successfully decrypts something, so one typo doesn't poison every future deploy attempt.

Try it yourself — Neo is free, with every feature unlocked.

Get started free