On DenkOps an environment variable is write-only. You save it once, it is stored encrypted, and after that nothing can read the value back through the platform: not the dashboard, not the CLI, and not the AI agent that built and deployed the app. The only place the value exists in plain text is inside your running process, injected at run.
Why does write-only matter more when an agent does the deploying?
Because the deployer is no longer only you. The whole point of shipping a backend from Claude Code is that the agent writes the code, deploys it, and iterates. That agent operates with your permissions, and everything it observes lands in its context: transcripts, logs, whatever tooling wraps it. If the platform could echo a secret back, any agent with deploy access could pull your CRM key into that context by accident, and from there it goes wherever the context goes.
Write-only closes the loop. The agent can create the variable, reference it by name, wire it into code, deploy, and debug, all without ever observing the value. You paste the value exactly once, and the interesting failure mode, "the agent leaked a secret it read from the platform", stops being possible because the read does not exist.
How does my code use a secret it cannot read back?
The same way it always has: process.env at run time. Here is an MCP tool handler an agent might write, calling a CRM with a key it knows only by name:
import { z } from "zod";
import { defineMcp } from "@denkopsai/sdk/mcp";
export default defineMcp({
name: "crm-tools",
version: "1.0.0",
tools: {
create_contact: {
description: "Create a contact in the CRM by email address.",
input: z.object({ email: z.string().email() }),
handler: async ({ email }) => {
const res = await fetch("https://api.example-crm.com/contacts", {
method: "POST",
headers: {
authorization: `Bearer ${process.env.CRM_API_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({ email }),
});
if (!res.ok) throw new Error(`CRM answered ${res.status}`);
return res.json();
},
},
},
});Every line of that file can be written, reviewed, and redeployed by an agent. CRM_API_KEY appears only as a name. When the MCP server starts, the platform decrypts the value and injects it into the process environment, and the handler works.
What is the lifecycle of a secret on DenkOps?
Three moments. At save time, the value is encrypted and becomes write-only; the dashboard will confirm the variable exists but never show its content again. At run time, it is injected into your process's environment, and nowhere else. At rotation time, you overwrite the variable with a new value and the next run of the app picks it up; the old value was never readable, so there is nothing to clean out of histories or agent transcripts.
One guardrail pairs well with this. Even code that holds a secret in memory can only send it where you allow: outbound traffic from a DenkOps app is limited to an egress allowlist you control. A prompt-injected agent that rewrites your handler to POST the key elsewhere still hits a wall, because "elsewhere" is not on the list.