redact

package
v0.705.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package redact provides key- and value-based scrubbing of secrets (API keys, tokens, passwords, cookies, credentials...) from configuration trees, HTTP headers, log attributes and free-form text. It has no dependencies beyond the standard library, so any package — including ones that must not import internal/config or internal/logging — can use it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsSecretKey

func IsSecretKey(key string) bool

IsSecretKey reports whether key names a value that must never be logged or shipped in the clear: an API key, access token, password, cookie, authorization header or generic credential. Matching is case-insensitive and suffix-based, so "apiKey", "api_key", "API-KEY", "oauthAccessToken" and "Authorization" all match, while plural counters such as "promptTokens" or unrelated words such as "tokenOptimization" do not (neither ends in the singular "token" suffix).

func Path

func Path(s string) string

Path replaces every occurrence of the current user's home directory anywhere in s with "~", so file paths embedded in log messages, stack traces or attributes never leak the local username. The home directory is resolved once (via os.UserHomeDir) and cached for the process lifetime.

func String

func String(s string) string

String scrubs known secret patterns out of free-form text:

  • "Bearer <token>" / "Basic <token>" authorization values (full value, including compound tokens with embedded "=", ";" or ":"),
  • common provider key/token prefixes (OpenAI/Anthropic/OpenRouter "sk-...", GitHub "ghp_.../github_pat_...", Slack "xox?-...", age "AGE-SECRET-KEY-1...", AWS "AKIA...", Google "AIza...", Groq "gsk_...", xAI "xai-...", HuggingFace "hf_...", Stripe-style "rk_live_.../ pk_live_..."),
  • JWTs (three dot-separated base64url segments starting "eyJ"),
  • URL userinfo ("scheme://user:pass@" becomes "scheme://[REDACTED]@"),
  • "key=value", `"key":"value"` (plain or backslash-escaped) and "key: value" (YAML/header colon form, quoted or not) pairs whose key looks like a secret, per IsSecretKey — including URL query parameters such as "?key=...", "?api_key=...", "?access_token=...", "?sig=...", "?signature=...".

Every match is replaced with "[REDACTED]" (the value only; the key and surrounding punctuation are preserved so the shape of the original text — JSON, a query string, a header dump — stays recognizable). Text that matches none of the patterns is returned unchanged.

func Truncate

func Truncate(s string, max int) string

Truncate cuts s to at most max bytes, taking care not to split a multi-byte rune, and appends a "…[truncated]" marker when it actually cut something. max <= 0 always returns "".

func Value

func Value(key string, v any) any

Value redacts v for safe logging/shipping and returns a JSON-safe result (map[string]any, []any, string, or a scalar).

v may be an already-decoded JSON tree (map[string]any/[]any/scalars, e.g. from json.Unmarshal into `any`) — those are walked directly, preserving their original scalar types (so an int stays an int, not a float64) — or any other Go value: a struct, a pointer, a typed map (map[string]string, http.Header, ...), a typed slice ([]string, ...), []byte, an error or a fmt.Stringer. Anything not natively recognized is converted to the same generic map[string]any/[]any/scalar shape via a round trip through encoding/json (falling back to fmt.Sprint for a value json.Marshal rejects, e.g. a channel or a function), and then walked the same way.

Redaction rules, applied recursively:

  • any value found under a key that looks like a secret (IsSecretKey) becomes "[REDACTED]", whole — including a nested array/object, not just a scalar (so `{"api_keys":["a","b"]}` redacts to `{"api_keys":"[REDACTED]"}`, not a partially-redacted array);
  • every remaining string has known secret patterns scrubbed (String) and the user's home directory rewritten to "~" (Path);
  • []byte becomes "[N bytes]" — its content is never shown, not even base64-encoded, since JSON's default []byte encoding is base64 and would otherwise round-trip a redacted-looking value straight back into recoverable bytes;
  • a []string (or []any of strings) shaped like a CLI argument list ("--token", "X", "--api-key=Y", ...) has the value following a secret-named flag redacted, inline or as the next element;
  • other scalars (numbers, bools, nil) pass through unchanged.

key is the field name v was found under; pass "" for the root of a tree or for slice/array elements, which have no key of their own.

Types

This section is empty.

Jump to

Keyboard shortcuts

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