Cloudflare operates one of the world’s largest networks, providing network and cloud services to improve website and application security and performance. A critical security aspect of building applications and solutions integrating with Cloudflare involves the management of sensitive data, commonly known as secrets. Cloudflare has a secure mechanism for handling secrets, offering tools for storing, accessing, and managing confidential information in the cloud.
What is a Cloudflare secret?
Cloudflare secrets are sensitive information stored as encrypted environment variables for Cloudflare Workers (execution environments for serverless applications). Secrets include but are not limited to database credentials, API keys, and other confidential data. There is no need to hard-code sensitive information in plain text.
Key features
- Secure and encrypted storage: Secrets in Cloudflare are encrypted during transit and at rest, ensuring high security.
- Native application integration: Cloudflare secrets integrate directly with Cloudflare Workers, eliminating the need for complex setup. This built-in solution provides automatic retrieval and management of credentials.
- Environment variable flexibility: Cloudflare secrets are easily referenced as environment variables across Workers.
Creating Cloudflare secrets via the CLI
You can create secrets via Wrangler, the Cloudflare Workers CLI.
Prerequisites
Install Wrangler
Sign up for a free Cloudflare account
Create a new project and navigate to it’s directory:
$ npx wrangler init secrets-demo # Select "Hello World" Worker # Confirm "Yes" to using Typescript # Confirm "Yes" to using using Git # Select "No" to deploy the application $ cd secrets-demo
Login to your Cloudflare account and authorize Wrangler:
$ npx wrangler login # Confirm authorization to Wrangler
Create a secret
You can create a secret by running the command:
$ npx wrangler secret put MY_SECRET_NAME_KEY
Next, you will be prompted to input the secret’s value, type:
⛅️ wrangler 3.19.0
-------------------
? Enter a secret value: › dragons and unicorns are real
Press Enter to save the secret. You’ll see output similar to the following:
✔ Enter a secret value: … *****************************
🌀 Creating the secret for the Worker "secrets-demo"
✨ Success! Uploaded secret MY_SECRET_NAME_KEY
Verify the secret was created:
$ npx wrangler secret list
[
{
"name": "MY_SECRET_NAME_KEY",
"type": "secret_text"
}
]
Accessing the secret from a Cloudflare Worker
Now that you have created a secret, your application can access it by referencing it in the Worker code.
For example, in TypeScript you might use code that looks something like this to retrieve and return the value of the Cloudflare secret:
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
return new Response(`Secret: ${env.MY_SECRET_NAME_KEY}`);
},
};
Deploy the changes.
$ npx wrangler deploy
⛅️ wrangler 3.19.0
-------------------
Total Upload: 0.21 KiB / gzip: 0.18 KiB
Uploaded secrets-demo (0.92 sec)
Published secrets-demo (3.61 sec)
https://secrets-demo.diana-247.workers.dev
Current Deployment ID: e7c2b8e7-e13a-4a11-9667-024eed3cce05
Here’s an example of using curl
against a Cloudflare Worker serverless application using the code above to retrieve and return a Cloudflare secret value:
$ curl https://secrets-demo.diana-247.workers.dev
Secret: dragons and unicorns are real
Best practices
- Rotate secrets regularly: Implement a routine for periodically rotating secrets to enhance security.
- Provide least-privilege access: Employ policies for granular access control to secrets.
- Audit and monitor secret access: Use monitoring tools to track access and modifications to your secrets.
Challenges and considerations
Using Cloudflare secrets comes with particular challenges and considerations:
- Management of secrets overhead: As the number of secrets and contexts grows, managing them can become challenging. Teams must actively track and monitor the usage of secrets, identifying where and by whom they are employed.
- Access control complexity: Setting up fine-grained access controls is crucial but can become complex as teams and projects scale. Defining and maintaining access permissions for different roles and responsibilities can be challenging. Clearly define roles and duties to determine who needs access to specific secrets. Use role-based access control (RBAC) principles to simplify and organize permissions.
- Integration with external secret management systems: Organizations may already have established processes for secrets management using external tools, and integrating these with Cloudflare secrets can be complex. Evaluate whether integrating with an external secrets management system is necessary for your organization. If required, explore solutions that integrate with Cloudflare and provide a unified approach to secrets management. Ensure that the chosen solution aligns with your security and compliance requirements. Two popular secret management systems include AWS Secrets Manager and Google Cloud Secret Manager.
Addressing these challenges and considerations requires a thoughtful approach to secrets management, clear communication within the development team, and a commitment to maintaining security best practices. A beta product to facilitate secrets management and tackle the above challenges is available for Cloudflare as the Cloudflare Secrets Store.
Conclusion
Following security best practices for Cloudflare secrets are crucial in managing sensitive information in your solutions, applications, and cloud environments.
Now that you know Cloudflare secrets, take your cloud infrastructure management to the next level with Pulumi:
- Streamlined infrastructure management with Infrastructure as Code (IaC): Learn about other Cloudflare resources using Pulumi’s IaC capabilities. Pulumi lets you define and provision your cloud infrastructure using familiar programming languages, directly integrating secrets management into your workflows. Discover how to integrate Cloudflare secrets into your broader cloud infrastructure with Pulumi by exploring the Cloudflare Provider documentation. Below are some examples of how to create a Cloudflare secret in several supported programming languages:
$ pulumi config set secrets-demo --secret
value: ****
import * as pulumi from "@pulumi/pulumi";
import * as cloudflare from "@pulumi/cloudflare";
import * as fs from "fs";
const config = new pulumi.Config();
const accountId = config.require("accountId");
const secret = config.require("secrets-demo"); // mark as required
const myScript = new cloudflare.WorkerScript("myScript", {
accountId: accountId,
name: "script_1",
content: fs.readFileSync("script.js", "utf8"),
secretTextBindings: [{
name: "MY_SECRET_NAME_KEY", // secret key
text: secret, // secret value
}],
});
"""A Python Pulumi program"""
import pulumi
import pulumi_cloudflare as cloudflare
config = pulumi.Config()
account_id = config.require("accountId")
secret = config.require("secrets-demo")
# Sets the script with the name "script_1"
my_script = cloudflare.WorkerScript("myScript",
account_id=account_id,
name="script_1",
content=(lambda path: open(path).read())("script.js"),
secret_text_bindings=[cloudflare.WorkerScriptSecretTextBindingArgs(
name="MY_SECRET_NAME_KEY",
text=secret,
)],
)
package main
import (
"os"
"github.com/pulumi/pulumi-cloudflare/sdk/v5/go/cloudflare"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)
func readFileOrPanic(path string) pulumi.StringInput {
data, err := os.ReadFile(path)
if err != nil {
panic(err.Error())
}
return pulumi.String(string(data))
}
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
conf := config.New(ctx, "")
accountId := conf.Require("accountId")
secret := conf.Require("secrets-demo")
_, err := cloudflare.NewWorkerScript(ctx, "myScript", &cloudflare.WorkerScriptArgs{
AccountId: pulumi.String(accountId),
Name: pulumi.String("script_1"),
Content: readFileOrPanic("script.js"),
SecretTextBindings: cloudflare.WorkerScriptSecretTextBindingArray{
&cloudflare.WorkerScriptSecretTextBindingArgs{
Name: pulumi.String("MY_SECRET_NAME_KEY"),
Text: pulumi.String(secret),
},
},
})
if err != nil {
return err
}
return nil
})
}
- Get started tutorial: Follow a simple tutorial to deploy a Hello World web application using Cloudflare Workers and Pulumi
- Advanced secrets management: For organizations that use more than one secrets manager or store configuration data in multiple locations, Pulumi ESC (Environments, Secrets, and Configurations) offers a centralized solution for managing secrets and configurations across various environments. Moreover, Pulumi ESC integrates with OIDC to allow the dynamic generation of credentials, elevating its utility in scenarios where secrets need to be frequently rotated or updated. Dive deeper into how Pulumi ESC can streamline your secrets management workflows by visiting the Pulumi ESC documentation for the Pulumi ESC documentation for the AWS Secrets provider.
Our community on Slack is always open for discussions, questions, and sharing experiences. Join us there and become part of our growing community of cloud professionals!
Get started today
Get started today
Pulumi is open source and free to get started. Deploy your first stack today.