Skip to main content
Agent transcripts are durable and frequently leave your infrastructure — they are stored, replayed, and sent to third-party model providers. Repost redacts credentials from event payloads by default, but redaction is a credential scrubber, not a privacy control. The boundary between the two is the single most important thing to understand before copying any payload into a transcript.
Redaction does not remove PII. Names, email addresses, phone numbers, postal addresses, card numbers, bank details, national IDs, IP addresses, and customer identifiers pass through verbatim. Detection is by credential key/header name only — it has no concept of personal data. Never treat a payload as safe to paste, log, or forward just because it came back “redacted.”

What redaction covers

Redaction is applied server-side, by default, on exactly two commands — events get and events diff — the only commands that return full headers and bodies. The CLI never receives the unredacted form unless you explicitly opt out (see below). Each response also lists the exact paths it touched in a redactions array. Headers are redacted by name:
authorization   proxy-authorization   cookie   set-cookie   x-api-key   x-api-token
stripe-signature   x-hub-signature   x-hub-signature-256   x-slack-signature
svix-signature   webhook-signature   x-signature
Signature headers keep their plain metadata (t, ts, timestamp) in clear text and tag only the signature itself, so you can still reason about timing:
"stripe-signature": ["t=1718061000,v1=[redacted:hmac:9f2a1c4d8b07]"]
JSON-object body keys are redacted by name — password, token, secret, api_key / apikey, access_token, refresh_token, client_secret, and any key whose name contains secret or token. Redaction recurses into nested objects. Each redacted value becomes a deterministic tag:
[redacted:hmac:9f2a1c4d8b07]
The tag is the first 12 hex characters of an org-scoped HMAC of the value. It is stable for the same value within an organization — identical secrets produce identical tags — so you can correlate “same credential” across events without ever seeing the secret. It is not reversible and differs across organizations.
Every response names the exact paths it touched in a redactions array, so you can audit what was removed:
"redactions": ["request.headers.authorization", "request.headers.stripe-signature"]

What redaction does not cover

The mechanism is a name-based credential filter. Everything outside that definition is returned in full. Assume each of these is present and act accordingly.
GapWhy it leaksExample
All PIINo value-based or personal-data detection exists."email": "ada@example.com" is returned as-is.
Secrets under innocuous keysOnly sensitive key names match.{"data": "sk_live_51H..."} — key data is not sensitive, so the value stays.
Anything inside arraysRedaction descends into objects, not array elements.{"items": [{"token": "..."}]}token inside the array is not redacted.
Non-object bodiesOnly JSON objects are parsed and filtered.Form-encoded, plain-text, XML, or a top-level JSON array body is shown raw, with no redaction at all.
URLs and pathsNot in scope.Query strings and path segments are never redacted.
The two highest-risk gaps are arrays and non-object bodies. A webhook that sends a JSON array, a form post, or secrets nested in a list receives no body redaction. Inspect the redactions array: if it is empty for a body you expected to be scrubbed, the payload was not an object — treat the whole body as sensitive.

Opting out: the secrets scope

events get --reveal-secrets and events get --as-fixture disable redaction and return full cleartext. Both require a token with the secrets scope; without it the CLI fails with forbidden_scope (exit 3) and emits nothing.
Reserve secrets for a narrow, deliberate need — reproducing a signature locally, building a fixture — and direct that output only to a trusted destination. Adding --reveal-secrets to “make debugging easier” routes raw credentials straight into the transcript. See Authentication & scopes.

Operating rules

1

Default to redacted, always

Never add --reveal-secrets or --as-fixture for convenience. If a token does not carry secrets, you cannot leak credentials through events get — keep it that way.
2

Assume every body contains PII

Redaction will not catch it. Before a payload crosses a trust boundary (a logged transcript, a model provider, a ticket), summarize it — “a payment_intent.succeeded for in_123” — instead of pasting it.
3

Prefer IDs and metadata over bodies

event_id, forward_id, status, latency, and response code are almost always enough to drive a decision and carry far less risk than a full body.
4

Read the redactions array, but don't trust its absence

redactions tells you what was removed. An empty or short list means little was matched — often because the data was PII or lived in an array, not because the payload was clean.
5

Scrub what you must keep

If a body has to enter the transcript, remove PII yourself before writing it. Redaction is the floor, not the ceiling.

Continue

Authentication & scopes

Why secrets should almost always be absent.

Diagnose webhooks

Where redacted payloads appear in an investigation.

Output & errors

The forbidden_scope error you get without secrets.