Post

WordPress: Store Sensitive Data as Server Environment Variables

WordPress doesn’t support .env files natively. The right pattern is to set sensitive values (API keys, tokens, license keys) as server environment variables and read them in wp-config.php with getenv(). They never touch the codebase or git history.


Apache (VPS / cPanel)

In your vhost config (e.g. /etc/apache2/sites-enabled/yoursite-le-ssl.conf):

1
2
3
4
5
6
7
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    SetEnv MY_API_KEY your-api-key-here
    SetEnv PAYMENT_SECRET your-payment-secret
</VirtualHost>

Restart Apache:

1
sudo systemctl restart apache2

Nginx + PHP-FPM

In your server block (e.g. /etc/nginx/sites-available/yoursite), pass the vars via fastcgi_param:

1
2
3
4
5
6
7
8
9
10
11
server {
    server_name example.com;
    root /var/www/html;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param MY_API_KEY "your-api-key-here";
        fastcgi_param PAYMENT_SECRET "your-payment-secret";
    }
}

Restart Nginx and PHP-FPM:

1
sudo systemctl restart nginx php8.2-fpm

DDEV (local development)

Add vars to .ddev/config.yaml under web_environment:

1
2
3
web_environment:
  - MY_API_KEY=your-local-test-key
  - PAYMENT_SECRET=your-local-secret

Restart DDEV:

1
ddev restart

Read the variables in wp-config.php

Once the server var is set, read it with getenv() and fall back to a default for local if needed:

1
2
3
4
// wp-config.php

define( 'MY_API_KEY', getenv('MY_API_KEY') ?: '' );
define( 'PAYMENT_SECRET', getenv('PAYMENT_SECRET') ?: '' );

Then use the constant anywhere in your theme or plugin:

1
$key = MY_API_KEY;

Verify the variable is set

Quick PHP snippet to confirm the var is being picked up (remove after testing):

1
var_dump( getenv('MY_API_KEY') );

Or via WP-CLI:

1
wp eval "var_dump(getenv('MY_API_KEY'));"

Why not just hardcode in wp-config.php?

wp-config.php often ends up in git (or should be excluded but accidentally isn’t). Server environment variables are:

  • Outside the codebase entirely
  • Not visible in git history
  • Per-environment by default (local, staging, prod each have their own values)

This post is licensed under CC BY 4.0 by the author.