Alternatives to app secrets

Published

Updated

Reviewedbyfl

🔐

Keep secrets out of Git.

App secrets from the old fortrabbit platform do not exist on the new one. ENV vars cover most cases. For stricter needs, keep secrets in CI, in a secrets manager, or encrypt the values and keep only the key private.

App secrets on the old platform stored security-sensitive config as key-value pairs in a JSON file, separate from the ENV vars. Few apps used them, and they caused confusion, so the new platform has no app secrets.

Alternatives for app secrets

  • Store secrets as ENV vars. Keep the values out of logs and error output, see ENV vars and security.
  • Deploy a secrets file not tracked in Git via rsync or SSH as a one-off step outside the normal deploy flow.
  • If your CI/CD pipeline handles deploys, inject secrets there — GitHub Actions, GitLab CI, and Bitbucket Pipelines all have built-in secret storage.
  • Use a dedicated commercial secrets manager: Doppler, HashiCorp Vault, Infisical, or AWS Secrets Manager are common choices.
  • Encrypt individual secret values and store them as env vars. Encrypted values are safe to expose; only the key needs protecting. We wrote about this pattern in how to keep a secret. For plain PHP use defuse/php-encryption; Laravel has this built in via the Crypt facade and php artisan env:encrypt; Symfony offers a secrets vault with php bin/console secrets:set.

Encrypted ENV vars in plain PHP

This example uses defuse/php-encryption. Install the package:

composer require defuse/php-encryption
shell

Generate a key once and save it outside of Git, for example in a file uploaded by SFTP:

php -r "echo \Defuse\Crypto\Key::createNewRandomKey()->saveToAsciiSafeString();"
shell

Encrypt each secret locally and store the output, prefixed with ENC:, as an ENV var:

$key = \Defuse\Crypto\Key::loadFromAsciiSafeString(trim(file_get_contents('/path/to/app.key')));
echo 'ENC:' . \Defuse\Crypto\Crypto::encrypt('my-secret-value', $key);
php

At bootstrap, decrypt every ENV var with the ENC: prefix. getenv() reads the ENV vars also when PHP leaves $_ENV empty:

$key = \Defuse\Crypto\Key::loadFromAsciiSafeString(trim(file_get_contents('/path/to/app.key')));
foreach (getenv() as $name => $value) {
    if (str_starts_with($value, 'ENC:')) {
        $_ENV[$name] = \Defuse\Crypto\Crypto::decrypt(substr($value, 4), $key);
    }
}
php

Written by humans and AI in collaboration.

AI use & editorial processEdit on GitHub ↗