When you’re integrating external services like Salesforce, you often need to use a private key for JWT (JSON Web Token) authentication. On a normal VPS you’d simply store that key one level above the web root, but WP Engine’s managed WordPress setup doesn’t allow that.
This post explains why — and more importantly, how to do it properly and securely.
The problem
WP Engine’s file system is designed for security and performance.
Your WordPress install lives at:
/nas/content/live/{sitename}/
You can’t go “one level up” from here — it’s locked, and it’s designed that way.
That means /nas/content/live/{sitename}/../private/sf.key
simply isn’t possible.
So where can you safely store non-public files such as:
- Salesforce JWT private keys
- API credentials
- SSH or service tokens
The short answer: use your SSH Gateway home directory.
Why can’t I just use _wpeprivate/
?
You might spot a folder called _wpeprivate
in your environment.
Despite its name, it’s not a secure or permanent private directory — it’s intended for temporary migration files.
Anything inside could be included in backups, and it isn’t guaranteed to stay hidden from HTTP access.
So let’s skip that and use the supported, secure option.
The correct approach — SSH Gateway
Every WP Engine site has an SSH Gateway. When you connect via SSH or SFTP, you’re placed in your own isolated Linux home directory at:
/home/wpe-user/
That directory sits outside the webroot, is not publicly accessible, and persists between deploys.
It’s perfect for private keys and config files.
Step-by-step setup
1. Enable SSH Gateway
In your WP Engine dashboard, go to:
Environment → Utilities → SSH Gateway Access
and enable it (or request activation if you don’t see it).
You’ll get connection details like:
{sitename}@{sitename}.ssh.wpengine.net
2. Connect via SSH
From your terminal:
ssh {sitename}@{sitename}.ssh.wpengine.net
You’ll land in:
/home/wpe-user/
3. Create a secure .ssh
directory
mkdir -p ~/.ssh
chmod 700 ~/.ssh
4. Create or upload your key
Option A — Paste the key
nano ~/.ssh/sf_private.key
Paste your private key (include the BEGIN
/ END
lines), then press Ctrl + O
, Enter
, Ctrl + X
to save.
Option B — Upload the key
From your local machine:
scp ~/Downloads/sf_private.key {sitename}@{sitename}.ssh.wpengine.net:/home/wpe-user/.ssh/
5. Lock down permissions
chmod 600 ~/.ssh/sf_private.key
That ensures only your SSH user can read it.
6. Reference it in PHP
In your plugin or integration class:
$this->private_key_path = '/home/wpe-user/.ssh/sf_private.key';
Your application can now securely access the key, without ever exposing it to the web.
7. Confirm it’s private
Try hitting the URL directly:
curl https://yourdomain.com/.ssh/sf_private.key
You should get a 404 or “Forbidden” response.
If you ever get the file contents instead — something’s wrong!
Alternative: Environment Variables
If your app doesn’t need a file path, you can store the private key itself as an environment variable in the WP Engine portal (Utilities → Environment Variables), and load it with:
$private_key = getenv('SALESFORCE_JWT_KEY');
This approach keeps it completely off disk.
Final thoughts
This is one of those subtle WP Engine quirks that’s easy to bump into when you’re moving from a traditional VPS setup.
But once you know that /home/wpe-user/
exists, it becomes the perfect home for anything sensitive — certificates, keys, or config files you never want exposed.
I hope this saves you a few hours of head-scratching.
If you found this useful, share it — it might just stop someone else from pushing a private key into wp-content/private/
😬