Redaction rewrites outbound text right before it is sent to the LLM provider. It runs on user input and tool results. Assistant output and the system prompt are left untouched: the model has already seen its own prior responses, and the system prompt is authored by you.

The original messages remain in the session's stored history. Each turn re runs the redactor on the messages that are about to be sent, so secrets never leave the BEAM process.

Default redactor

Condukt.Redactors.Regex covers common high precision patterns:

  • Emails
  • JWTs
  • PEM private keys
  • Anthropic, OpenAI, GitHub, Google, AWS, Slack tokens

Matches are replaced with [REDACTED:KIND] placeholders that the LLM can still reason about ("an email was here") without learning the value.

{:ok, agent} =
  MyApp.CodingAgent.start_link(redactor: Condukt.Redactors.Regex)

Adding patterns

Pass :extra_patterns to extend the defaults:

{:ok, agent} =
  MyApp.CodingAgent.start_link(
    redactor:
      {Condukt.Redactors.Regex,
       extra_patterns: [{~r/cust_[a-z0-9]+/, "CUSTOMER"}]}
  )

Each entry is {regex, label}. Matches are replaced with [REDACTED:LABEL].

Custom redactors

Implement Condukt.Redactor to plug in anything you want, including NER based PII detection or a call to an internal service:

defmodule MyApp.Redactor do
  @behaviour Condukt.Redactor

  @impl true
  def redact(text, _opts) do
    MyApp.PiiScanner.scrub(text)
  end
end

MyApp.CodingAgent.start_link(redactor: MyApp.Redactor)

redact/2 receives the raw outbound text and the keyword options that were passed alongside the module in a {module, opts} tuple (or [] if none).

Tool result redaction

Tool results that are not strings (maps, lists) are JSON encoded before the redactor runs, so secrets embedded in structured output are still caught. The result the model sees is the redacted JSON.

Session secrets

Session secrets configured through :secrets are converted into a Condukt.Redactors.Secrets redactor and composed ahead of the configured :redactor. This keeps resolved provider secrets in the same outbound redaction pipeline as regex or custom redactors.

Unlike general outbound redactors, session secret values are also exact-match redacted from tool results before they are stored in session history. This prevents resolved session credentials from being persisted if a command prints them.

What is not redacted

  • The system prompt
  • Assistant output
  • Project instructions (AGENTS.md, CLAUDE.md, skills)

Treat the system prompt and project instructions as developer authored content. If you need redaction there, scrub them before passing them in.