Secret
A Cloudflare Secret represents an individual secret stored in a Secrets Store.
Use this resource to add individual secrets to an existing SecretsStore, providing fine-grained control over secret management.
Basic Usage
Add a secret to an existing secrets store:
ts
import { SecretsStore, Secret } from "alchemy/cloudflare";
import alchemy from "alchemy";
// Create a secrets store first
const store = await SecretsStore("my-store", {
name: "production-secrets",
});
// Add individual secrets to the store
const apiKey = await Secret("api-key", {
store: store,
value: alchemy.secret(process.env.API_KEY),
});
const dbUrl = await Secret("database-url", {
store: store,
value: process.env.DATABASE_URL,
});
Multiple Secrets
Add multiple secrets to the same store:
ts
import { SecretsStore, Secret } from "alchemy/cloudflare";
const store = await SecretsStore("shared-store", {
name: "shared-secrets",
});
// Add various secrets incrementally
await Secret("oauth-client-id", {
store: store,
value: alchemy.secret(process.env.OAUTH_CLIENT_ID),
});
await Secret("oauth-client-secret", {
store: store,
value: alchemy.secret(process.env.OAUTH_CLIENT_SECRET),
});
await Secret("webhook-secret", {
store: store,
value: alchemy.secret(process.env.WEBHOOK_SECRET),
});
await Secret("encryption-key", {
store: store,
value: alchemy.secret(process.env.ENCRYPTION_KEY),
});
Preserve Secret on Destroy
When removing from Alchemy state, keep the secret in Cloudflare:
ts
import { Secret } from "alchemy/cloudflare";
const preservedSecret = await Secret("preserve-secret", {
store: myStore,
value: "preserved-value",
delete: false,
});
Access in Worker
Once secrets are added to a store, access them in your Worker code:
ts
import { SecretsStore, Secret, Worker } from "alchemy/cloudflare";
const store = await SecretsStore("app-secrets", {
name: "app-secrets",
});
// Add secrets using the Secret resource
await Secret("stripe-secret-key", {
store: store,
value: alchemy.secret(process.env.STRIPE_SECRET_KEY),
});
await Secret("sendgrid-api-key", {
store: store,
value: alchemy.secret(process.env.SENDGRID_API_KEY),
});
const worker = await Worker("api-worker", {
bindings: {
SECRETS: store,
},
code: `
export default {
async fetch(request, env) {
const stripeKey = await env.SECRETS.get("stripe-secret-key");
const sendgridKey = await env.SECRETS.get("sendgrid-api-key");
// Use secrets in your application
return new Response("Secrets loaded successfully");
}
}
`,
});
Combined with SecretsStore
You can combine both approaches - define some secrets in the SecretsStore and add others individually:
ts
import { SecretsStore, Secret } from "alchemy/cloudflare";
// Create store with some initial secrets
const store = await SecretsStore("mixed-secrets", {
name: "mixed-secrets",
secrets: {
API_KEY: alchemy.secret(process.env.API_KEY),
DATABASE_URL: alchemy.secret(process.env.DATABASE_URL),
},
});
// Add additional secrets individually
await Secret("third-party-token", {
store: store,
value: alchemy.secret(process.env.THIRD_PARTY_TOKEN),
});
await Secret("webhook-signing-secret", {
store: store,
value: alchemy.secret(process.env.WEBHOOK_SIGNING_SECRET),
});
Use Cases
The Secret resource is particularly useful for:
- Conditional secrets: Adding secrets based on environment or configuration
- Dynamic secret management: Adding secrets in response to other resource creation
- Modular configuration: Organizing secrets across different parts of your application
- Secret rotation: Updating individual secrets without affecting others
Notes
- Secrets are stored securely in Cloudflare's encrypted storage
- Secret names must be unique within each Secrets Store
- Secret values are encrypted at rest and in transit
- Use
alchemy.secret()
for proper secret handling and encryption