Security. Secure Environemnt Variables
Dracory applications load configuration from environment variables.
This guide covers the advanced features for protecting those values, including encrypted environment vaults and runtime secret management.
Key Concepts
-
EnvEnc – Dracory's environment encryption module that derives a working key from a
password (stored in
ENVENC_KEY_PRIVATE) and decrypts vault files at runtime. -
Vault files – Encrypted
.env.<environment>.vaultdocuments that store sensitive key-value pairs. Each environment can have its own vault. -
Hybrid loading – The configuration loader hydrates values from the plain
.envfile first and then overlays secrets decrypted from the vault.
When to Use Vaults
Use vaults when:
- You need to commit configuration alongside your code without exposing secrets.
- Multiple environments share a repository but require distinct credentials.
- Operations teams manage secrets centrally and deliver encrypted bundles to development teams.
Vaults are optional for local development. The configuration loader skips vault
hydration entirely when APP_ENVIRONMENT=testing to simplify automated tests.
Preparing a Vault
-
Ensure
ENVENC_KEY_PRIVATEis set in.env. This is the password that will derive the encryption key. - Decide the target environment, for example
developmentorproduction. -
Create the vault file path
.env.<environment>.vault(for example.env.production.vault). -
Encrypt secrets using
github.com/dracory/envenc. A common workflow is:# Create a JSON or .env style payload with the secrets you want to store. cat <<'EOF' > secrets.env STRIPE_KEY_PRIVATE=sk_live_xxx STRIPE_KEY_PUBLIC=pk_live_xxx SMTP_PASSWORD=super-secret EOF # Encrypt the payload using your private key password. go run github.com/dracory/envenc/cmd/envenc \ encrypt --password "$ENVENC_KEY_PRIVATE" \ --input secrets.env \ --output .env.production.vault -
Commit the resulting
.env.production.vaultfile as part of your deployment assets. Do not commit the temporarysecrets.envfile.
Runtime Requirements
To hydrate secrets at runtime:
- Set
ENVENC_USED=truein.env(or the environment). - Provide
ENVENC_KEY_PRIVATEwith the password used during encryption. -
Place the corresponding
.env.<environment>.vaultfile either on disk or embed it ininternal/resources.
When the application starts, config.NewFromEnv will:
- Read
.envusingenv.Load. - Detect
ENVENC_USEDand derive the working key viaderiveEnvEncKey. - Hydrate secrets from the vault file on disk if it exists.
- Hydrate embedded vault content from
internal/resourcesas a fallback. - Validate that the required keys were provided after hydration.
Any failure (missing vault file, wrong password, malformed payload) surfaces as an
error from config.NewFromEnv and prevents the application from booting with partly
configured secrets.
Rotating Vault Passwords
- Generate a new
ENVENC_KEY_PRIVATEvalue. - Re-encrypt each environment vault with the new password.
- Update the password wherever the application is deployed.
- Restart the application to pick up the new secrets.
Because the derived key is deterministic for a given password, all vault files for an environment must be re-encrypted using the new password before redeploying.
Working with Embedded Vaults
Dracory can embed vault files using internal/resources. To embed:
- Add the vault file (for example
.env.production.vault) underinternal/resources. - Ensure it is referenced in the resources embed configuration.
- Deploy the binary without shipping separate vault files.
At runtime, config.NewFromEnv first checks the file system for
.env.<environment>.vault. If it is absent, the loader attempts to read the file from
internal/resources. This enables Docker or serverless deployments where writing to
disk is restricted.
Local Development Tips
-
Keep
ENVENC_USED=falselocally unless you specifically want to practice the vault workflow. - Store the vault password in a secure password manager, not plaintext docs.
- Use different passwords per environment to reduce blast radius.
- Automate vault encryption and distribution through CI tasks to prevent manual mistakes.
Troubleshooting
| Symptom | Likely Cause | Resolution |
|---|---|---|
config.NewFromEnv returns an error about ENVENC_KEY_PRIVATE |
ENVENC_USED=true without a password |
Set ENVENC_KEY_PRIVATE in .env or disable vaults |
Vault hydration fails with file not found |
Missing .env.<environment>.vault |
Ensure the vault file exists on disk or embedded resources |
Decryption fails with invalid ciphertext |
Wrong password or corrupted file | Re-encrypt the vault with the correct password |
| Secrets not available after boot | Keys missing from vault payload | Confirm that the encrypted payload includes the expected entries |