Cloudflare Workers can securely store and access secrets like API keys, database credentials, or other sensitive information without exposing them in your worker code or client-side JavaScript.
Let’s see this in action. Imagine you have a Worker that needs to call an external API that requires an API key.
// worker.js
export default {
async fetch(request, env, ctx) {
const apiKey = env.EXTERNAL_API_KEY; // Accessing the secret
const url = `https://api.example.com/data?apiKey=${apiKey}`;
const apiResponse = await fetch(url);
const data = await apiResponse.json();
return new Response(JSON.stringify(data), {
headers: { 'content-type': 'application/json' },
});
},
};
Here, env.EXTERNAL_API_KEY is how you access the secret. The env object is provided by Cloudflare and contains your configured environment variables, including secrets.
The problem this solves is obvious: you absolutely cannot hardcode sensitive credentials directly into your worker code. If you did, anyone who could inspect your worker’s code (which, while not trivially accessible, isn’t impossible in certain scenarios) would have your secrets. Furthermore, you want to be able to change these secrets without redeploying your worker.
The mechanism is built around Cloudflare’s Workers KV (Key-Value) store and their more recent "Secrets" feature, which is essentially a managed, encrypted Key-Value store specifically for sensitive data. When you define a secret in your Worker’s settings via the Cloudflare dashboard or API, Cloudflare encrypts it. Your Worker then accesses this secret through the env object during runtime. The actual encryption and decryption happen transparently on Cloudflare’s infrastructure, meaning the plain-text secret never touches your worker’s execution environment in a way that could be easily exfiltrated.
To set this up:
- Go to your Worker’s dashboard. Navigate to the "Settings" tab for your Worker.
- Find "Variables". Under the "Configuration" section, you’ll see "Environment Variables" and "Secrets".
- Add a Secret. Click "Add variable", choose "Secret" from the dropdown, enter a name (e.g.,
EXTERNAL_API_KEY), and paste your sensitive value.
Once saved, this secret is available to your Worker via env.EXTERNAL_API_KEY.
The critical difference between regular environment variables and secrets is how they are handled. Regular environment variables are generally accessible in a more straightforward manner, and while still better than hardcoding, they might not offer the same level of cryptographic protection as secrets. Secrets are specifically designed for sensitive data, implying stronger encryption and access controls at the Cloudflare infrastructure level.
The env object is not just for secrets. It’s the unified interface for all environment-specific configurations, including both regular environment variables and secrets. This allows your worker code to remain agnostic to whether it’s accessing a sensitive API key or a non-sensitive configuration setting, simplifying your application logic.
When you deploy your worker, Cloudflare binds these secrets to your worker’s execution context. The env object is populated at runtime with these bindings. This means that even if your worker code is replicated across multiple edge locations, each instance securely accesses the same underlying secret managed by Cloudflare.
The most surprising true thing about this system is that even though you’re accessing secrets via env.SECRET_NAME, Cloudflare’s runtime environment does not, at any point, expose the decrypted secret to the JavaScript execution context in a way that could be read by other parts of your code or inspected through debugging tools. The binding is more of a secure, direct lookup mechanism where the secret is decrypted just-in-time for its intended use within an API call or a specific operation, and then immediately discarded from the accessible memory of the worker’s execution sandbox.
The next step is to consider how to manage secrets across different environments (e.g., development, staging, production) and how to rotate them regularly.