Summary
Apply argument redaction to ActionTrace.args for all capabilities (or make the
redaction scope configurable), and scrub driver error text before embedding it in
trace error fields. Today only memory.* capability args are redacted.
Why this matters
The trace store is the long-lived audit record. If invocation arguments routinely
contain user content, secrets passed as parameters, or PII, storing them raw makes
the TraceStore itself a sensitive data store — undermining the I-01 boundary the
firewall enforces on outputs. DriverError messages additionally embed up to 200
characters of raw HTTP response bodies into traces.
Current evidence
kernel/_invoke.py:44-55: _MEMORY_CAPABILITY_PREFIX = "memory." and _redact_args_for_trace only redacts when capability_id starts with "memory."; all other args stored raw at lines 162 and 191.
drivers/http.py:111-114: DriverError message includes exc.response.text[:200] — raw upstream body text flows into ActionTrace.error via record_failure_trace.
firewall/redaction.py has the full pattern set (email/phone/card/SSN/Bearer/JWT/API-key/connection-string) but is not applied to trace args.
External context
Audit-log hygiene guidance (e.g., OWASP logging recommendations) treats secrets and
PII in logs as a standing risk class; agent audit trails inherit the same concern.
Proposed implementation
- Run the string-pattern portion of
redact() over all trace args by default
(sensitive-field-name redaction plus inline pattern scrubbing).
- Keep the existing full-payload redaction for
memory.* unchanged.
- Scrub driver error strings through the same pattern pass in
record_failure_trace before persisting.
- Optionally allow a kernel/policy switch (
trace_args: "redacted" | "raw" | "omit")
for deployments that need full-fidelity traces.
AI-agent execution notes
Acceptance criteria
- A fake API key passed as an invocation arg never appears verbatim in any stored
ActionTrace.
- A driver failure whose HTTP body contains a fake secret produces a trace
error with the secret redacted.
memory.* behavior is unchanged and covered by existing tests.
Test plan
Add cases to tests/test_trace.py and tests/test_kernel.py with secret-bearing args
and a failing fake driver; assert redaction. Run make ci.
Documentation plan
Document trace-content guarantees in docs/security.md; CHANGELOG Security.
Migration and compatibility notes
Trace consumers will see redacted args where they previously saw raw values; the
optional "raw" switch preserves old behavior where explicitly chosen.
Risks and tradeoffs
Redacted traces are less useful for debugging; the configuration switch and stable
[REDACTED] sentinel mitigate this. Small per-invocation CPU cost.
Suggested labels
security, reliability, architecture
Summary
Apply argument redaction to
ActionTrace.argsfor all capabilities (or make theredaction scope configurable), and scrub driver error text before embedding it in
trace
errorfields. Today onlymemory.*capability args are redacted.Why this matters
The trace store is the long-lived audit record. If invocation arguments routinely
contain user content, secrets passed as parameters, or PII, storing them raw makes
the TraceStore itself a sensitive data store — undermining the I-01 boundary the
firewall enforces on outputs.
DriverErrormessages additionally embed up to 200characters of raw HTTP response bodies into traces.
Current evidence
kernel/_invoke.py:44-55:_MEMORY_CAPABILITY_PREFIX = "memory."and_redact_args_for_traceonly redacts whencapability_idstarts with"memory."; all other args stored raw at lines 162 and 191.drivers/http.py:111-114:DriverErrormessage includesexc.response.text[:200]— raw upstream body text flows intoActionTrace.errorviarecord_failure_trace.firewall/redaction.pyhas the full pattern set (email/phone/card/SSN/Bearer/JWT/API-key/connection-string) but is not applied to trace args.External context
Audit-log hygiene guidance (e.g., OWASP logging recommendations) treats secrets and
PII in logs as a standing risk class; agent audit trails inherit the same concern.
Proposed implementation
redact()over all trace args by default(sensitive-field-name redaction plus inline pattern scrubbing).
memory.*unchanged.record_failure_tracebefore persisting.trace_args: "redacted" | "raw" | "omit")for deployments that need full-fidelity traces.
AI-agent execution notes
kernel/_invoke.py(_redact_args_for_trace,record_failure_trace),firewall/redaction.py,trace.py,tests/test_kernel.py,tests/test_trace.py.memory.*behavior.ActionTracefield names — downstream consumers (Export ActionTrace to OpenTelemetry / LangWatch-compatible trace format #125, Interop: export action traces for downstream lesson extraction #94) read them.Acceptance criteria
ActionTrace.errorwith the secret redacted.memory.*behavior is unchanged and covered by existing tests.Test plan
Add cases to
tests/test_trace.pyandtests/test_kernel.pywith secret-bearing argsand a failing fake driver; assert redaction. Run
make ci.Documentation plan
Document trace-content guarantees in
docs/security.md; CHANGELOGSecurity.Migration and compatibility notes
Trace consumers will see redacted args where they previously saw raw values; the
optional
"raw"switch preserves old behavior where explicitly chosen.Risks and tradeoffs
Redacted traces are less useful for debugging; the configuration switch and stable
[REDACTED]sentinel mitigate this. Small per-invocation CPU cost.Suggested labels
security, reliability, architecture