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
Update: Since publishing this content it’s become clear that the information I received from WP Engine is inaccurate. The SSH Gateway is transient and any files outside of this path will disappear when your SSH session ends.
This makes WP Engine private keys a bit tricky.
What can’t you do?
- Whilst
_wpeprivatefolder is the only persistent place, WP Engine discourages storing or using custom.keyfiles manually. - You could upload SSL certificates through the dashboard, but that won’t work in dev because you need a domain named to be linked before you can use this feature.
What can you do?
Not a lot. The only option available to you is to store your .key in wp-config.php and reference it in the code. If your code needs a physical key; you’re stuffed. You’ll need to use another hosting provider, like Cloudways which provides a /private_html folder.
The information in this section is here for legacy only. It is no longer accurate.
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
- Log in to the User Portal
- Click on the environment name to connect to
- In the Overview section, locate SSH Login (right at the bottom of the page, at the time of writing)
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/ 😬


