RuView PII Detector Agent:构建多智能体安全体系中的敏感信息与凭据泄漏扫描器
本文以 RuView 仓库中的智能体定义文件 .claude/agents/v3/pii-detector.md 为主体,完整讲解这个专用 PII(个人身份信息)检测 Agent 的检测目标、正则扫描模式、修复建议与 Swarm 上报机制,并结合仓库中 security-scanner.sh、redact-secrets.py 等配套实现,说明该 Agent 如何落地到一条可验证的数据合规防线。读完本篇,你可以掌握一个「检测目标定义 → 正则模式库 → 修复建议 → 合规上下文 → 蜂群集成」的完整安全 Agent 设计范式,并能在自己的仓库中复刻同类扫描能力。
PII Detector Agent 的定位与声明式配置
RuView 采用 claude-flow 多智能体(Swarm)工作流组织开发过程,安全类 Agent 集中在 .claude/agents/v3/ 目录下。其中的 pii-detector 是一个专职的敏感信息扫描器:它的职责不是查漏洞,而是识别代码、数据文件和 Agent 通信中泄漏的个人敏感信息与凭据,并在命中时给出分类与修复建议。
该 Agent 采用 YAML frontmatter + Markdown 正文的声明式定义,frontmatter 中的每一项字段都有明确的运行时含义:
| 字段 | 取值 | 含义 |
|---|---|---|
name |
pii-detector |
Agent 唯一标识 |
type |
security |
安全类 Agent,与同目录的 aidefence-guardian、security-auditor 等同属安全域 |
color |
#FF5722 |
Swarm 可视化中的显示色 |
description |
扫描代码与数据中的敏感信息泄漏 | Agent 职责的一句话摘要 |
capabilities |
pii_detection / credential_scanning / secret_detection / data_classification / compliance_checking |
能力标签,供编排器按能力路由任务 |
priority |
high |
调度优先级 |
requires.packages |
@claude-flow/aidefence |
声明式依赖的检测库 |
hooks.pre / hooks.post |
扫描开始/结束提示 | 生命周期钩子,扫描前后输出状态日志 |
从源码结构看,requires.packages 声明了该 Agent 的能力依托外部 npm 包 @claude-flow/aidefence 提供(该包在 Agent 文件中以 createAIDefence() 工厂函数暴露 API);capabilities 与 priority 则服务于 Swarm 编排器——编排器可以基于能力标签把"扫描某目录的敏感数据"这一类任务分派给本 Agent。hooks 中的 pre/post 是 shell 片段,分别用于标记一次扫描会话的开始与结束,保证扫描过程在会话日志中可追踪。
三大检测目标类别
Agent 文档将检测目标划分为三个正交类别,这个划分直接决定了后续正则库与合规映射的组织方式:
1. 个人身份信息(PII)
- 邮箱地址(Email addresses)
- 社会安全号(SSN)
- 电话号码(Phone numbers)
- 物理地址(Physical addresses)
- 特定上下文中的姓名(Names in specific contexts)
2. 凭据与密钥(Credentials & Secrets)
- API 密钥:OpenAI、Anthropic、GitHub、AWS 等
- 密码:硬编码在代码中或写在配置文件里
- 数据库连接字符串
- 私有密钥与证书(Private keys and certificates)
- OAuth token 与 refresh token
3. 金融数据(Financial Data)
- 信用卡号
- 银行账户号
- 各类金融标识符
这个分类的意义在于:修复策略与合规映射都按类别分派。API Key 泄漏走"环境化/密钥管理器"路线,PII 走"脱敏/tokenization"路线,金融数据则直接触发 PCI-DSS 级别的处置。
检测 API 与调用示例
Agent 文档给出的标准用法基于 @claude-flow/aidefence 的 createAIDefence() 工厂,核心调用链是 detector.detect(content) → 检查 result.piiFound → 对命中类型做逐行统计与行号定位:
import { createAIDefence } from '@claude-flow/aidefence';
const detector = createAIDefence();
async function scanForPII(content: string, source: string) {
const result = await detector.detect(content);
if (result.piiFound) {
console.log(`⚠️ PII detected in ${source}`);
// Detailed PII analysis
const piiTypes = analyzePIITypes(content);
for (const pii of piiTypes) {
console.log(` - ${pii.type}: ${pii.count} instance(s)`);
if (pii.locations) {
console.log(` Lines: ${pii.locations.join(', ')}`);
}
}
return { hasPII: true, types: piiTypes };
}
return { hasPII: false, types: [] };
}
// Scan a file
const fileContent = await readFile('config.json');
const result = await scanForPII(fileContent, 'config.json');
if (result.hasPII) {
console.log('🚨 Action required: Remove or encrypt sensitive data');
}
从这段接口契约可以提炼出三点设计要点:
- 检测与分类解耦:
detect()只负责判定"是否命中"(piiFound布尔位),具体类型统计由analyzePIITypes()完成,返回{ type, count, locations }三元组——这意味着扫描结果天然可结构化为报告字段; - 定位到行:
locations是行号数组,这是安全扫描工具的关键能力——只报"有泄漏"不够,必须能指到具体行才能修复; - 动作出口明确:命中后统一输出 "Action required: Remove or encrypt sensitive data",把处置语义交给上层(Swarm 编排器或人)决策,而不是扫描器自行修改文件。
正则扫描模式库
Agent 文档内置了两组可直接复用的正则模式库,这是整份文档最具实战价值的部分。
API Key 模式
const API_KEY_PATTERNS = [
// OpenAI
/sk-[a-zA-Z0-9]{48}/g,
// Anthropic
/sk-ant-api[a-zA-Z0-9-]{90,}/g,
// GitHub
/ghp_[a-zA-Z0-9]{36}/g,
/github_pat_[a-zA-Z0-9_]{82}/g,
// AWS
/AKIA[0-9A-Z]{16}/g,
// Generic
/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,
];
逐条解读各模式的匹配语义与适用前提:
| 模式 | 厂商/用途 | 语义 |
|---|---|---|
sk-[a-zA-Z0-9]{48} |
OpenAI | sk- 前缀 + 恰好 48 位字母数字,匹配经典 API key 形态 |
sk-ant-api[a-zA-Z0-9-]{90,} |
Anthropic | sk-ant-api 前缀 + 至少 90 位字母数字连字符,前缀本身已强约束,长度用下界兜底 |
ghp_[a-zA-Z0-9]{36} |
GitHub PAT | ghp_ 前缀 + 恰好 36 位,即 classic personal access token |
github_pat_[a-zA-Z0-9_]{82} |
GitHub 细粒度 token | github_pat_ 前缀 + 恰好 82 位,即 fine-grained PAT |
AKIA[0-9A-Z]{16} |
AWS Access Key ID | AKIA 前缀 + 恰好 16 位大写字母数字,这是 AWS access key 的公开形态 |
api[_-]?key\s*[:=]\s*["'][^"']+["'] |
通用 | 键名启发式:api_key/apikey/api-key 后跟赋值与引号包裹的任意值,作为厂商模式未命中时的兜底 |
值得注意的是两条设计取舍:厂商模式依赖前缀 + 精确长度,误报率极低但只能覆盖已知厂商;通用模式依赖键名启发式,覆盖面广但依赖配置书写习惯(key、token 等变体需要自行扩展)。i 标志让键名匹配大小写不敏感,而厂商 token 模式保持大小写敏感——因为真实 token 的字母大小写是形态的一部分。
密码模式
const PASSWORD_PATTERNS = [
/password\s*[:=]\s*["'][^"']+["']/gi,
/passwd\s*[:=]\s*["'][^"']+["']/gi,
/secret\s*[:=]\s*["'][^"']+["']/gi,
/credentials\s*[:=]\s*\{[^}]+\}/gi,
];
这四条全部是键名启发式:匹配 password、passwd、secret 三个字面键以及 credentials 对象字面量,覆盖 JSON/TOML/配置文件中最常见的"明文凭据赋值"形态。credentials 一条用 \{[^}]+\} 匹配花括号对象而非引号串,说明它假设凭据常以对象形式(如 { username: "...", password: "..." })出现。
这套键名启发式与仓库中另一套 bash 级扫描器形成了互证。.claude/helpers/security-scanner.sh 的 scan_secrets() 函数使用同样的思路,但面向 shell 环境用 grep -riE 实现:
local patterns=(
"password\s*=\s*['\"][^'\"]+['\"]"
"api[_-]?key\s*=\s*['\"][^'\"]+['\"]"
"secret\s*=\s*['\"][^'\"]+['\"]"
"token\s*=\s*['\"][^'\"]+['\"]"
"private[_-]?key"
)
对照两套模式库可以看到清晰的工程分层:Agent 文档中的 TypeScript 正则库用于精确的逐行报告(带行号、类型、计数),而 bash 扫描器用于低成本的仓库级统计——它只累加命中行数并输出 secrets 总量,配合 30 分钟节流(should_run() 中 1800 秒阈值)与 clean/warning/critical 三档状态机(>10 判 critical、>0 判 warning),结果写入 .claude-flow/security/scan-results.json。两者共用同一组"键名启发式"心智模型,只是运行在不同工具层。
修复建议(Remediation)
检测到命中后,Agent 按数据类别给出四条修复路线——这是"检测 → 处置"闭环中处置端的规范:
- API Keys:改用环境变量或密钥管理器(secret managers),把明文值移出源码树;
- Passwords:放入
.env文件(并确保其被 gitignore),或接入 vault 方案; - 代码中的 PII:实施数据脱敏(masking)或 tokenization;
- 日志:在写日志之前启用 PII scrubbing,避免凭据/个人数据经由日志二次扩散。
这四条建议在 RuView 仓库中都能找到对应的落地实现,说明它们不是纸面规范:
- 日志脱敏对应 scripts/redact-secrets.py。它是 generate-witness-bundle.sh 在生成见证包(witness bundle)前串联在命令输出管道中的过滤层(
verify.py 2>&1 | python3 scripts/redact-secrets.py),用纯标准库正则把 SaaS token 前缀(sk-、ghp_、AKIA、hf_、xoxb-等)、40+ 位不透明长串、20+ 位 hex 串以及token|password|secret|api_key=...形式的赋值统一替换为[REDACTED]。这与 PII Detector 文档第 4 条"日志写入前 scrubbing"是同一条原则的具体实现; - 仓库级数据拦截对应 scripts/csi-data-policy-check.sh(见下节)。
与 Security Swarm 的集成:命中结果的结构化上报
PII Detector 不是孤立运行的——它作为 Swarm 中的一员,把发现写入共享记忆命名空间,供其他 Agent(如 Guardian、Auditor)查询与联动。文档给出的上报协议如下:
// Report PII findings to swarm
mcp__claude-flow__memory_usage({
action: "store",
namespace: "pii_findings",
key: `pii-${Date.now()}`,
value: JSON.stringify({
agent: "pii-detector",
source: fileName,
piiTypes: detectedTypes,
severity: calculateSeverity(detectedTypes),
timestamp: Date.now()
})
});
这个上报结构值得注意的三个字段:
namespace: "pii_findings":按发现类型隔离命名空间,Swarm 其他成员只查自己关心的类别,避免安全事件流混杂;severity: calculateSeverity(detectedTypes):严重度由命中的 PII 类型推导而非固定值——意味着 SSN 或私钥的严重度必然高于一个普通邮箱,这正是合规映射(下节)在数据层的体现;key: pii-${Date.now()}:以时间戳做键,天然保证并发扫描时多条发现不互相覆盖。
合规上下文(Compliance Context)
文档把检测能力映射到四个合规框架,明确了每个框架下本 Agent 回答的问题:
| 框架 | 对应检测目标 |
|---|---|
| GDPR | 个人数据识别(邮箱、SSN、电话、地址等 PII 类别) |
| HIPAA | 受保护健康信息(PHI)——对 RuView 这类做呼吸/心率等生命体征监测的项目尤其相关 |
| PCI-DSS | 支付卡数据(信用卡号、银行账户号) |
| SOC 2 | 敏感数据处理实践(凭据、密钥、日志脱敏) |
文档的收尾原则是:"Always recommend appropriate data handling based on detected PII type and applicable compliance requirements"——即处置建议必须按"PII 类型 × 适用合规要求"二维查表给出,而不是对一切命中一刀切。
仓库纵深佐证:当"个人数据"指 WiFi 信号本身
上述集成与合规章节若只看 Agent 文档,读者可能疑惑:一个 WiFi 感知项目为什么要配 PII 检测?docs/adr/ADR-299-csi-data-incident-repo-controls.md 给出了答案:原始 CSI 信道数据本身就是个人数据——它编码了人的呼吸、动作与在场信息,等价于行为生物特征。该 ADR 记录了一次真实数据事故(约 64.6 MB 原始 CSI 录音因 .gitignore 规则失效被提交进仓库),并落了两道机械化防线:
.gitignore覆盖data/recordings/、v2/data/recordings/与*.csi.jsonl/*.csi.meta.json通配;- csi-data-policy-check.sh:确定性、离线、可 pre-commit/CI 双跑的守卫脚本。它的行为契约与 PII Detector 的"检测 → 定位 → 建议"完全同构:
classify()按扩展名分类命中(*.csi.jsonl一律拦截;*.jsonl仅在超过CSI_POLICY_MAX_JSONL_BYTES(默认 5 MB)时拦截);scan_stdin()输出带文件路径的BLOCK:行(定位能力),退出码 0/1/2 区分 clean/违规/环境错误(可供 CI 门禁消费);- 合成测试 fixture 可通过 scripts/csi-data-policy.allow 白名单豁免(对应 PII Detector 修复建议中的"tokenization/脱敏后测试"原则);
- 脚本内置
--self-test,用确定性 fixture 断言"拦截 csi 流、放行小 jsonl、放行白名单"六条断言全部通过,与 ADR 的 Validation 章节逐条对应。
这套脚本证明 PII Detector 文档中"数据分类(data_classification)"能力在 RuView 中并非抽象声明:分类对象从"代码里的 API key"扩展到了"仓库里的人体传感数据文件",检测、白名单、基线豁免(CSI_POLICY_BASELINE)与 CI 门禁形成完整闭环。
同域协作:与 AIDefence Guardian 的分工
在 .claude/agents/v3/ 安全 Agent 家族中,pii-detector 与 aidefence-guardian.md 构成互补分工,两者依赖同一个 @claude-flow/aidefence 包:
- pii-detector 面向静态资产:扫代码、配置文件、数据文件与 Agent 通信内容中的敏感信息,输出"类型 + 行号 + 计数"的明细报告,优先级
high; - aidefence-guardian 面向动态通信:拦截式监控所有 Agent 输入/输出,把 PII 暴露列为六种威胁类型之一(
pii_exposure——文档原文明确列出 "Emails, SSNs, API keys, passwords"),并叠加提示注入、越狱、编码攻击等检测,拥有critical优先级与会话级统计(scans/blocked/warned)。
可以推断,这条设计意图是:Guardian 在输入侧做实时拦截(发现 pii_exposure 即告警/阻断),PII Detector 在资产侧做周期性深扫与合规报告,两者通过共享记忆命名空间(pii_findings / security_detections)交换发现,构成"拦截层 + 审计层"的双层防御。
小结:可复刻的敏感信息扫描设计清单
把 .claude/agents/v3/pii-detector.md 的设计要素与仓库配套实现对照,可以得到一份可移植到其他项目的清单:
- 声明式 Agent 定义:frontmatter 声明
capabilities、priority、requires.packages与生命周期hooks,正文给出职责与操作规范——pii-detector.md; - 三层检测目标分类:PII / 凭据密钥 / 金融数据,分类决定修复策略与合规映射;
- 双模正则库:厂商前缀 + 精确长度(低误报)与键名启发式(广覆盖)组合——
API_KEY_PATTERNS、PASSWORD_PATTERNS,bash 层的 security-scanner.sh 是其低成本孪生实现; - 四条修复路线:环境变量/密钥管理器、
.env+ vault、masking/tokenization、日志前 scrubbing——分别由 redact-secrets.py 等仓库脚本兑现; - 结构化上报:
pii_findings命名空间 + 时间戳键 + 类型推导严重度,让 Swarm 其他成员可查询、可联动; - 合规映射:GDPR/HIPAA/PCI-DSS/SOC 2 四框架按 PII 类型查表给出处置建议;
- 仓库级数据守卫:以 csi-data-policy-check.sh + ADR-299 为范本,把"个人数据不可入库"做成确定性、离线、带自测试的 CI 门禁。
整套方案的共同特点是机械可验证:正则可单测、守卫脚本离线确定、命中报告带行号与严重度、合规映射有文档依据——这使得 PII 检测从"Agent 的一次提示词指令"升级为"仓库里可复跑、可审计的工程实践"。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00