Skip to main content

Privacy and Credentials

An agent works with real data: asked for a customer’s email, it has to be able to give it. What the runtime keeps about a run is another matter. By default, personal data (emails, phone numbers, Social Security numbers, card numbers) is redacted from the trace, and every trajectory and export made from it. The credentials the agent holds, such as its model key, are removed from everything a tool returns before the model sees it, and from everything the trace records. By the end of this page you will have watched one fake email pass through a tool (real for the model and the answer, redacted in the stored trace) and a key printed by a tool arrive as [REDACTED:credential], and you will know which boundary to turn on when your deployment needs more.
Every output on this page is what the code printed when it was run. The model’s wording will differ on your run; what is redacted where will not.

One email, two views

The model read the real values and the answer carries them. The conversation memory kept them as written, so a later turn can use them. The trace, which holds the model’s prompts, the tool results and the answer, holds neither: the trace file on disk (workspace/telemetry/traces.jsonl by default) has the markers and not the address.

How it works

Each place data leaves the run’s working context is a boundary, with its own switch in agent_config["privacy_config"]: enabled: False turns every boundary off. The effective policy is fingerprinted in each trace’s metadata as privacy_config_version, so a trace shows which policy produced it.

Why working state is not redacted by default

Memory and the workspace are the agent’s own work, not a record of it. Redacted, they corrupt that work: the agent writes a pyproject.toml whose author email has become [REDACTED_EMAIL], or a run resumed after an approval rebuilds its call from redacted history and sends the marker instead of the address. Both happened before these defaults were chosen. Turn them on only where the stored state must hold no personal data at rest, knowing that the agent will then work from the redacted text. The stream and the answer are your application’s own output, so they carry real values unless you say otherwise.

Turning a boundary on

The same program, with one line added to the agent, agent_config={"privacy_config": {"redact_public": True, "redact_memory": True}}:
The model still saw the real values; the answer was redacted on its way out, and the history was redacted when it was stored.

Keep personal data from the model provider

redact_model_io redacts what is sent to the provider on every model call (turns and summaries). The model then works with the placeholders, so it cannot use the real values, and neither can anything it writes:
Applied from the release after 0.4.1. In 0.4.1 the setting is accepted but has no effect.

What counts as personal data

categories chooses among four, all on by default:
The first line is the telemetry boundary, on by default; the second is the public boundary, off by default, so nothing changed. Dates, decimals, UUIDs and identifier fields (trace_id, run_id, tool_call_id and the like) are never rewritten, so a redacted trace can still be followed.

The telemetry side

What a trace records at all is set by telemetry_config, separately from what is redacted in it. A trace records the full trajectory by default, so that a run can be read from request to answer, evaluated, or reused:
A redact_keys list you pass replaces the default one, so keep the defaults you still want. Every setting is in the telemetry settings reference, and reading traces is covered in Observability.

Credentials

When an agent is built, the runtime remembers the credentials it holds:
  • every value in model_config or the mcp_tools configuration under a key named like a credential (api_key, token, secret, password, access_key, private_key, credential, at any depth), and the token of an Authorization header;
  • every environment variable named like one (LLM_API_KEY, GITHUB_TOKEN, …) whose value looks like a key: at least 12 characters, one word, not a path or a number.
Wherever one of these values appears literally, it becomes [REDACTED:credential]: in every tool result before the model sees it (and so before it reaches memory, the workspace or the trace), in everything telemetry records, and in model error messages. The list is process-wide: a key one agent holds is removed from what every agent in the process hands a model.
The tool printed the key; the model never received it, so it could not repeat it.

Kept out of commands and scripts

Removing a key from output cannot stop a command from sending it somewhere. So the runtime also keeps keys out of the environments that commands run in: A command on the host can still read files your user can, including a .env file. If that matters, run commands in a sandbox: see Execution and sandbox providers.

Options

agent_config["privacy_config"]: agent_config["skill_script_env"] (default []) names the environment variables a host skill script may receive. Every agent setting is in the agent settings reference.

When things go wrong

redact_workspace is on, so the agent’s own writes were redacted. Turn it off unless the workspace must hold no personal data at rest; the trace is redacted either way.
The value is registered as a credential: it sits under a credential-named key in model_config or mcp_tools, or in an environment variable named like one (..._TOKEN, ..._SECRET, ..._API_KEY). Give non-secret settings names that do not look like credentials.
Only 10 to 15 digits count as a phone number, so a local number like 555-0100 is kept. Numbers with fewer digits than that are not matched.
Only these four categories exist.
A key that is not a setting, or a value that is not a bool:
To record less, use "default" or set the record_* settings one by one.

Next

Guardrails

The prompt-injection screen on requests and tool results.

Security model

What each layer protects against, and what it does not.

Execution

Where commands run, and what a sandbox isolates.

Sandbox providers

Docker, E2B, Daytona, Modal and more.