Skip to main content

lib/agent_sea/guardrail/pii_redactor.ex

defmodule AgentSea.Guardrail.PIIRedactor do
  @moduledoc """
  Redacts personally-identifiable information by rewriting the content (a
  `{:transform, _}` outcome). Redacts emails, US SSNs, and phone numbers by
  default; configure with `:types` (any of `:email`, `:ssn`, `:phone`).
  """
  @behaviour AgentSea.Guardrail

  @patterns %{
    email: ~r/[\w.+-]+@[\w-]+\.[\w.-]+/,
    ssn: ~r/\b\d{3}-\d{2}-\d{4}\b/,
    phone: ~r/\b\d{3}[-.\s]\d{3}[-.\s]\d{4}\b/
  }

  @default_types [:email, :ssn, :phone]

  @impl true
  def name, do: "pii_redactor"

  @impl true
  def check(content, opts) do
    types = Keyword.get(opts, :types, @default_types)

    redacted =
      Enum.reduce(types, content, fn type, acc ->
        Regex.replace(@patterns[type], acc, "[#{String.upcase(to_string(type))}]")
      end)

    if redacted == content, do: :ok, else: {:transform, redacted}
  end
end