Values And Versioning
Secret values are read through the Secret product object. The product supports plain current values and versioned values stored inside one Cloudflare secret.
Static Values
Section titled “Static Values”Use secret.static() when the operator supplies the value:
const stripeSecret = secret.static({ name: "stripe-secret", namespace: "billing",})
app.use(stripeSecret)Read the current value:
const apiKey = await stripeSecret.current().text()You can parse structured values when the secret contains JSON:
const credentials = await stripeSecret.current().json<{ clientId: string clientSecret: string}>()Random Values
Section titled “Random Values”Use secret.random() for generated keys:
const sessionKey = secret.random({ name: "session-key", namespace: "auth", bytes: 32,})
app.use(sessionKey)bytes defaults to 32. It must be an integer from 16 to 1024.
Generated Values
Section titled “Generated Values”Use secret.generated() when a product-owned apply flow owns value generation
outside application code:
const apiSigningKey = secret.generated({ name: "api-signing-key", namespace: "auth", bytes: 32,})
app.use(apiSigningKey)secret.generated() stores generated-value intent in the app spec and resource
graph. Direct Cloudflare deploys bind an already configured Secrets Store
value. Product-specific provider apply steps can write generated values when
they own the generation flow, such as Storage R2 API token credentials.
Scheduled rotation runs through layer secret rotate.
Versioned Values
Section titled “Versioned Values”Use versioned values when old data, signatures, cookies, or tokens may still need old keys.
const encryptionKey = secret.random({ name: "encryption-key", namespace: "storage", rotation: { everyDays: 90, retain: { mode: "retain_forever", }, },})
app.use(encryptionKey)Read the latest value:
const currentKey = await encryptionKey.current().bytes()Read a specific version:
const oldKey = await encryptionKey.version("v2").bytes()Read the value active at a known time:
const key = await encryptionKey.at(record.encryptedAt).bytes()Read all values active at a time. This is useful during signing-key overlap windows:
const activeKeys = await sessionKey.active({ at: "2026-05-25T00:00:00.000Z",})
for (const key of activeKeys) { const value = await key.text()}Stored Value Formats
Section titled “Stored Value Formats”Plain values are treated as the current version:
sk_test_xxxJSON version format:
{ "current": "v3", "versions": { "v2": { "value": "old-secret-value", "activeFrom": "2026-05-01T00:00:00.000Z", "expiresAt": "2026-06-01T00:00:00.000Z" }, "v3": { "value": "new-secret-value", "activeFrom": "2026-05-25T00:00:00.000Z" } }}Compact key-value format:
current=v3;v2=old-secret-value;v2_expires=2026-06-01T00:00:00.000Z;v3=new-secret-valueThe runtime chooses the current version in this order:
- The version marked by
current. - The last version in the parsed value.
- The plain text value.
Address And Binding Name
Section titled “Address And Binding Name”Every Secret has a product address:
$SECRET.<namespace>.<name>For namespace: "auth" and name: "session-key", the default address is:
$SECRET.auth.session-keyThe runtime binding name is generated from the same declaration:
LAYERON_SECRET_AUTH_SESSION_KEY