Security & Secrets

Manage encrypted environment variables and vault workflows in Dracory.

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>.vault documents that store sensitive key-value pairs. Each environment can have its own vault.
  • Hybrid loading – The configuration loader hydrates values from the plain .env file 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

  1. Ensure ENVENC_KEY_PRIVATE is set in .env. This is the password that will derive the encryption key.
  2. Decide the target environment, for example development or production.
  3. Create the vault file path .env.<environment>.vault (for example .env.production.vault).
  4. 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
  5. Commit the resulting .env.production.vault file as part of your deployment assets. Do not commit the temporary secrets.env file.

Runtime Requirements

To hydrate secrets at runtime:

  • Set ENVENC_USED=true in .env (or the environment).
  • Provide ENVENC_KEY_PRIVATE with the password used during encryption.
  • Place the corresponding .env.<environment>.vault file either on disk or embed it in internal/resources.

When the application starts, config.NewFromEnv will:

  1. Read .env using env.Load.
  2. Detect ENVENC_USED and derive the working key via deriveEnvEncKey.
  3. Hydrate secrets from the vault file on disk if it exists.
  4. Hydrate embedded vault content from internal/resources as a fallback.
  5. 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

  1. Generate a new ENVENC_KEY_PRIVATE value.
  2. Re-encrypt each environment vault with the new password.
  3. Update the password wherever the application is deployed.
  4. 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:

  1. Add the vault file (for example .env.production.vault) under internal/resources.
  2. Ensure it is referenced in the resources embed configuration.
  3. 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=false locally 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