logredact

package
v0.17.1 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package logredact 日志/审计载荷凭据脱敏:连接串/URL/头中的凭据在落日志前模式化打码。 与 fence(Markdown/HTML 注入卫生)正交——本包打码凭据。

规则表是**公开且可组合**的:Rules() 给出内置表副本,RedactWith / NewRedactor 接受调用方自己的扩展规则。下游各家的凭据形态不一样(厂商前缀族、裸 hex、 任意 scheme 的 URL…),把表关在包内就等于逼下游**重写一整份脱敏器**, 或在后面串第二道——两道顺序敏感、掩码风格还不一致。

Index

Constants

View Source
const DefaultHintKeep = 4

DefaultHintKeep 保定位线索掩码默认保留位数(首尾各)。

View Source
const HintMinLenRatio = 4

HintMinLenRatio 被掩值长度不足 keep*该倍数 时**全量打码**。

阈值的作用是「留了也别等于没留」:9 字符的 secret 留首尾 4 个 = 8 个字符, 换个字符就复原了——那不是定位线索,是泄露。保留的字符数必须远小于被藏起的 字符数,掩码才真的不可逆。

Variables

This section is empty.

Functions

func MaskHint added in v0.6.0

func MaskHint(s string) string

MaskHint 保留首尾各 DefaultHintKeep 字符的不可逆掩码。

输出形如 "sk-a****mnop":长度**固定**(与原值长度无关), 保留位**封顶**(与原值长度无关),中间恒为固定长度的星号。

长度不足时返回全量打码 "****"(理由见 HintMinLenRatio)。 空串返回空串。

func MaskHintWith added in v0.6.0

func MaskHintWith(s string, keep int) string

MaskHintWith 保留首尾各 keep 字符的不可逆掩码。

keep<=0 取 DefaultHintKeep。被掩值长度不足 keep*HintMinLenRatio 时全量打码。 空串返回空串。

func NewPayloadRedactor added in v0.17.0

func NewPayloadRedactor(fields []string, extra []Rule) func(string) string

NewPayloadRedactor 返回可复用的「载荷裁剪 + 形状脱敏」函数(字段集与规则表 在构造时**快照**一次)。

与 NewRedactor 同构:高频路径(日志热路径、每条 tool_call 都过一遍)用它, 别每次调用现编正则。返回的函数是并发安全的(只读快照,不改共享状态)。

func NewRedactor added in v0.6.0

func NewRedactor(extra []Rule) func(string) string

NewRedactor 返回一个可复用的脱敏函数(内置规则 + 扩展规则)。

规则表在构造时**快照**一次:调用方之后改自己的切片,不影响已构造的脱敏器。 返回的函数是并发安全的(只读规则表,不改共享状态)。

高频路径(日志热路径、每条 tool_call 都过一遍)用这个,别每次重建规则表。

func Redact

func Redact(s string) string

Redact 返回打码后的文本(无命中原样返回)。

等价于 RedactWith(s, nil):只跑内置规则。

func RedactPayloadValue added in v0.17.0

func RedactPayloadValue(v any, fields ...string) any

RedactPayloadValue 结构化形态:递归把 fields 指定的字段裁剪成「只记长度」的标记, 其余字符串按 RedactValue 的口径做形状脱敏。

与 RedactPayloads 语义一致(同一份判定表),差别只在形态:它吃已解码的值、 吐已解码的值,可用于「按字段名裁剪后再落库」的结构化载荷管道。

裁剪只作用于**字符串形态**的字段值;非字符串形态(对象/数组/数字)的值 原样保留,只递归下探——被裁掉的是「载荷」,不是「字段所在的那个对象」。

func RedactPayloads added in v0.17.0

func RedactPayloads(s string, fields ...string) string

RedactPayloads 把 fields 指定的载荷字段裁剪成「只记长度」的标记,再做形状脱敏。

**顺序由本函数保证**:载荷裁剪先于形状规则(见 payloadMarkerFormat 的说明)。 这正是 issue 里说的「「先裁剪再脱敏」应当由函数内部保证,而不是由调用点的 书写顺序保证」——顺序写反不报错,只是报出来的大小是错的。

fields 是**字段名白名单**(如 "content" / "content_base64" / "body"): 只裁剪这些字段的值,其余原样。刻意不给默认表——「哪些字段算载荷」是 调用方的口径,库里替它猜就等于替它决定什么会落盘。

裁剪只作用于**字符串形态**的字段值(载荷就是字符串:一段 base64、一份内容)。 对象/数组形态的值本函数不动它(那是结构化入口 RedactPayloadValue 的射程)。

高频路径(日志热路径、每条 tool_call 都过一遍)用 NewPayloadRedactor, 别每次重建正则。

func RedactPayloadsWith added in v0.17.0

func RedactPayloadsWith(s string, fields []string, extra []Rule) string

RedactPayloadsWith = RedactPayloads + 扩展规则。

扩展规则仍然排在**最后**(与 RedactWith 的口径一致:先内建、后扩展); 载荷裁剪仍在最前。三段的顺序是:载荷裁剪 → 内建规则 → 扩展规则。

func RedactSecrets

func RedactSecrets(s string, secrets ...string) string

RedactSecrets 抹除调用方已知的确切秘密(clone URL 内嵌 token、动态签发的临时 凭据等):与模式化 Redact 互补——Redact 靠规则打码未知形态的凭据,本函数抹除 已知值。与 Masker 相反,高敏感秘密不做令牌、不回填(Masker 只收低敏感拓扑标识)。 长秘密优先替换(防短串是长串前缀时留下尾段泄漏),空串忽略。

func RedactValue

func RedactValue(v any) any

RedactValue 递归脱敏任意 JSON 形态值:map/slice 逐字段下探,字符串过 Redact,其余原样。 事件载荷入库前的统一出口——tool_call 参数与 tool_result 文本常含连接串、webhook key、Bearer 头。

func RedactWith added in v0.6.0

func RedactWith(s string, extra []Rule) string

RedactWith 用内置规则 + 扩展规则脱敏。

**应用顺序:先内置、后扩展**(每组内部按声明顺序)。

为什么是这个顺序:内置规则的打码**保留结构**("$1://$2:****@" —— scheme 与 用户名留着,只有凭据体被替换),它对同一段文本的定位比扩展规则精确。 先跑内置,扩展规则面对的就是「已经打过码」的文本,既不会把内置已处理的凭据 再脱一次(幂等),也不会让扩展的粗规则先吃掉内置能精确定位的那部分。

扩展规则里 Re 为 nil 的会被跳过(不 panic)——扩展表是调用方给的, 一条写错的规则不该让整条脱敏链路崩掉。

Types

type MaskStyle added in v0.6.0

type MaskStyle int

MaskStyle 命中后的替换方式。

const (
	// MaskStyleLiteral 按 Repl 字面替换(支持 $1 引用)。内置规则用它**保留结构**:
	// scheme、用户名、键名留着,只有凭据体变成 ****——处置后的文本仍能看出
	// 「是哪一条凭据」。这是默认档。
	MaskStyleLiteral MaskStyle = iota
	// MaskStyleHint 保定位线索的不可逆掩码:保留首尾各 Keep 个字符。
	// 用于「全量打码会让人认不出是哪一条凭据」的场景。
	//
	// 与 MaskStyleLiteral 是**不同档**,不是替代关系:前者给的是「认不出」,
	// 后者给的是「认得出但不还原」。
	MaskStyleHint
)

type Masker

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

Masker 低敏感掩码+令牌回填器(K8sGPT anonymize 形态,bianque spec 2026-09-14-aiops-uplift-design §3):把目标机拓扑标识(IPv4 + 调用方注册的精确串) 在进 LLM 前替换为 «Tn» 令牌,在最终展示面 Restore 回填原名——LLM 解释里引用的 「主机 «T1»」在报告中还原为真名,可读性与隐私兼得。

分级纪律:高敏感(密码/密钥/连接串/Bearer)不走本机制——那是 Redact 的领域, 删除后永不回填;Masker 只收低敏感拓扑标识,且回填只发生在展示面、不回灌二次 LLM 输入(防掩码词表被 prompt 注入探测绕过)。令牌用全角书名号+序号,难以仿造; Restore 对未知令牌原样保留(不猜、不误回填)。

func NewMasker

func NewMasker() *Masker

NewMasker 构造(零值不可用,一律经本构造)。

func (*Masker) AddSecret

func (m *Masker) AddSecret(v string) string

AddSecret 注册精确串(会话主机名、实例名等调用方已知标识),返回其令牌。空串忽略。

func (*Masker) Count

func (m *Masker) Count() int

Count 已签发令牌数(测试/观测用)。

func (*Masker) Mask

func (m *Masker) Mask(s string) string

Mask 掩码文本:先精确注册串,再 IPv4 模式(动态注册,同址恒同令牌)。

func (*Masker) Restore

func (m *Masker) Restore(s string) string

Restore 回填令牌为原文(展示面专用;未知令牌原样保留)。

type Rule added in v0.6.0

type Rule struct {
	// Name 规则名(诊断用:扩展规则出错时要能指出是哪一条)。
	Name string
	// Re 命中模式。nil 的规则会被跳过(不 panic)。
	Re *regexp.Regexp
	// Repl 字面替换串,支持 $1 引用。Style=MaskStyleHint 时被忽略。
	Repl string
	// Style 替换方式,默认 MaskStyleLiteral。
	Style MaskStyle
	// Keep Style=MaskStyleHint 时保留的首尾字符数(<=0 取 DefaultHintKeep)。
	Keep int
	// Group Style=MaskStyleHint 时,掩码作用在**第几个捕获组**(1 起);0 = 整段匹配。
	//
	// 默认 0(整段)有个陷阱:规则的匹配范围里若含上下文(如 "password=xxx"),
	// 整段掩码保留的尾部 4 个字符**就是凭据的一部分**——那不是定位线索,是泄露。
	// 所以凭据类规则应当用捕获组圈出凭据本体,再把 Group 指过去。
	Group int
}

Rule 一条脱敏规则。

命中后按 Style 替换:

MaskStyleLiteral —— 整段替换为 Repl(字面,支持 $1/$2 引用);
MaskStyleHint    —— 整段替换为保留首尾各 Keep 字符的不可逆掩码(Repl 被忽略)。

规则表按声明顺序应用;**同一条规则内的多个匹配**由 regexp 一次性替换。

func Rules added in v0.6.0

func Rules() []Rule

Rules 返回内置规则表的**副本**。

返回副本而不是共享切片:调用方要能自由改自己的表(追加规则、改顺序), 共享切片的话改到一半就污染了全进程的内置规则——而这份表是所有日志出口共用的。 规则里的 *regexp.Regexp 是不可变的,共享指针是安全的。

Jump to

Keyboard shortcuts

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