redact

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package redact strips known secret values from text before it leaves the runtime. Used as defense-in-depth over agentloop's own event/span payloads and eval judge prompts — the primitive contract is that a capability substituting a secret into a request (say, ext.SecretPack's secret(name) into an Authorization header) should never itself emit that value in a RunEvent, a span, or an eval transcript. This package is the second line of defense for the times that contract leaks — a script that does log(secret("KEY")), or a fetch() response that happens to echo a credential back.

A Redactor holds a small ordered list of (value, placeholder) pairs. Apply (strings) and ApplyBytes ([]byte) replace every occurrence of each value with its placeholder, longest value first so a value that's a substring of another registered value can't carve into the longer one's placeholder after it's already been substituted.

This does not parse JSON or know anything about event structure — it operates on raw bytes/text. A caller redacting a structured payload (e.g. RunEvent.Args) marshals it to JSON, calls ApplyBytes, and unmarshals the result — which is exactly how agentloop's own Config wires this in (see redactEvent in the root package's tracing.go).

Pure library — no external dependencies, safe to construct once per session and reuse across many calls.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Redactor

type Redactor struct {
	// contains filtered or unexported fields
}

Redactor replaces pre-loaded secret values with placeholder strings. A nil *Redactor is a safe no-op pass-through on every method, so "no redaction configured" needs no special-casing at call sites.

func FromSecrets

func FromSecrets(secrets map[string]string) *Redactor

FromSecrets is the canonical constructor for redacting a named set of secret values — e.g. every value an ext.SecretPack-backed require("secret") getter could return this session. Each entry produces a redaction of the form:

value -> [redacted:secret.<key>]

Returns nil when secrets is empty, so the caller's nil-Redactor path (already a no-op) needs no per-event allocation for the common case of a session with nothing to redact.

func New

func New(values, placeholders []string) *Redactor

New returns a Redactor that replaces each values[i] with placeholders[i] in any text or bytes processed. The two slices must be the same length — a mismatch degrades to an empty (no-op) Redactor rather than panicking, since this is typically wired up at runtime and a construction bug shouldn't crash an agent run. Empty values are skipped, so a value that happens to be "" can't turn into "replace every byte."

Entries are sorted longest-first: an overlap between two registered values (say "app" and "apple") would otherwise let the shorter one match first and carve into text that the longer, more specific value should have claimed.

func (*Redactor) Apply

func (r *Redactor) Apply(s string) string

Apply is the string equivalent of ApplyBytes.

func (*Redactor) ApplyBytes

func (r *Redactor) ApplyBytes(b []byte) []byte

ApplyBytes returns b with every loaded value replaced by its placeholder. A nil receiver (or one with nothing registered) returns b unchanged.

The trade-off of operating on raw bytes rather than a decoded structure: over-redaction if a registered value happens to appear inside unrelated text. Registered values are credential material, so that collision is rare enough in practice to accept in exchange for catching a secret at any nesting depth without walking the payload field by field.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL