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
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 inagent_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 apyproject.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}}:
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:
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 bytelemetry_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:
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_configor themcp_toolsconfiguration under a key named like a credential (api_key,token,secret,password,access_key,private_key,credential, at any depth), and the token of anAuthorizationheader; - 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.
[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.
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
A file the agent wrote says [REDACTED_EMAIL]
A file the agent wrote says [REDACTED_EMAIL]
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.A value the agent needs shows as [REDACTED:credential]
A value the agent needs shows as [REDACTED:credential]
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.A phone number was not redacted
A phone number was not redacted
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.ValueError: categories[0] must be one of: credit_card, email, phone, ssn
ValueError: categories[0] must be one of: credit_card, email, phone, ssn
TypeError: PrivacyConfig.init() got an unexpected keyword argument
TypeError: PrivacyConfig.init() got an unexpected keyword argument
A key that is not a setting, or a value that is not a bool:
ValueError: telemetry capture must be one of: default, full
ValueError: telemetry capture must be one of: default, full
"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.