← 返回列表
未验证
在让一个 Skill 读取你的机器之前,先读懂它。
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/30 · 已提供中文文档
针对 Agent Skills 的静态、本地、可解释的安装前安全审计。扫描 SKILL.md/脚本/配置,以发现破坏性命令、隐藏网络调用、密钥读取、混淆、提示注入、持久化。CLI + 36 个测试夹具 + GitHub Actions。
综合分
28.1
GitHub 分
28.1
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add whaojie797-design/skill-sentry该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/17(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
在让一个 Skill 读取你的机器之前,先读懂它。 在让一个 Agent Skill 碰你的电脑之前,先读懂它。 License: MIT Python Tests Dependencies Topics skill-sentry 是面向 AI Agent 的信任层:一个本地、静态、离线的工具, 覆盖第三方 Agent Skill 的整个生命周期。 skill-sentry 是面向 AI Agent 的信任层:一个本地、静态、离线的工具,覆盖第三方 Agent Skill 的整个生命周期。 | 阶段 / 阶段 | 命令 | 你得到什么 / 你得到什么 | |---|---|---| | 安装前审计 / 安装前审计 | audit | 一份带有 file:line 证据的风险报告 | | 运行前锁定 / 运行前锁定 | lock | 一个 SHA-256 证据基线(skill-sentry.lock.json) | | 交接时可验证 / 交接时可验证 | verify | 针对基线的逐文件差异,每条发现都带有 path | | 改动后可追溯 / 改动后可追溯 | verify | 每个漂移条目的改动前/后哈希 | 它不会执行被扫描的 Skill、不会联网、不读环境变量、不上传任何内容。 它不会执行被扫描的 Skill、不会联网、不读环境变量、不上传任何内容。 3 分钟快速开始 / 3 分钟快速开始 git clone https://github.com/whaojie797-design/skill-sentry cd skill-sentry python --version # 3.9 或更新 / 需要 3.9 及以上 无需安装任何依赖——零第三方依赖,纯 Python 标准库。 无需安装任何依赖——零第三方依赖,纯 Python 标准库。 1) 审计一个你正准备安装的 Skill / 审计一个你正准备安装的 Skill python scripts/skill_sentry.py audit ./some-skill 2) 觉得没问题就锁定基线 / 觉得没问题就锁定基线 python scripts/skill_sentry.py lock ./some-skill 3) 交接后、更新后、一周后再校验 / 交接后、更新后、一周后再校验 python scripts/skill_sentry.py verify ./some-skill audit 输出到 SKILL_AUDIT.md / skill-sbom.json / policy-result.json。 lock 写入 skill-sentry.lock.json。verify 写入 VERIFY_REPORT.md 和 verify-report.json,并将同一份报告打印到 stdout。 旧版 v0.1.0 入口点的行为与之前完全一致: python scripts/audit_skill.py ./some-skill # 行为不变 / 行为不变 真实示例 / 真实示例 以下命令在一份 4 文件的 demo Skill 上真实执行 (SKILL.md、scripts/run.py、scripts/helper.sh、assets/logo.png), 并带有一个 skill 内的 policy.yml。下面的输出为逐字捕获, 不是编造的示例。 以下命令在一份 4 文件的 demo Skill 上真实执行(SKILL.md、scripts/run.py、 scripts/helper.sh、assets/logo.png + skill 内的 policy.yml)。输出为逐字捕获, 不是编造的示例。 捕获说明:输出来自 Windows(/tmp 对应本机的 C:\temp)。 在 Linux / macOS 上,只有路径分隔符与路径不同,其余内容一致。 lock $ python scripts/skill_sentry.py lock demo-skill --policy demo-skill/policy.yml skill-sentry 0.2.0 - lock ======================================================================== Lock file : C:\temp\demo-skill\skill-sentry.lock.json Skill : demo-skill Files : 4 (text=3 binary=1 unknown=0 symlink=0) Rule-scanned : 3 Empty dirs : 0 Warnings : 0 Policy : source=explicit present=True external=False Audit : policy_passed=True max_level=INFO findings=0 Integrity : sha256 files_hash=cceb3b2961f160df65453a277dcbbc7902280daddd4e93a3eb82df9fb65e60a6 Limits : max_file_size=26214400 follow_symlinks=False This lock file is a baseline, NOT a safety guarantee. 该锁文件是基线证据,不是安全保证。 Commit it with the skill, or store it outside the skill directory. 请与 skill 一起提交进 Git,或用 --lock-out 保存到 skill 目录之外。 ======================================================================== echo $? 0 lock 即使基线不完整也会写入文件,因此 verify 始终有可比较的对象。对未改动的 Skill 连续运行两次 lock,除 generated_at 外会产生字节完全一致的输出。 即使基线不完整,lock 也会落盘(这样 verify 永远有可比对象)。对未改动的 Skill 连续执行两次 lock,除 generated_at 外字节完全一致。 verify — 未改动 $ python scripts/skill_sentry.py verify demo-skill skill-sentry 0.2.0 - verify ======================================================================== Result : OK (exit 0) / 与基线一致(退出码 0) Lock file : C:\temp\demo-skill\skill-sentry.lock.json Skill dir : demo-skill Findings : error=0 review=0 info=0 unverifiable=0 fatal=0 What "verify passed" means / "verify 通过"到底意味着什么 verify PASS = "this skill still matches the recorded baseline". verify PASS != "this skill is safe". If any entry is UNVERIFIABLE, it is NOT counted as unchanged. verify 通过 = 「与锁定时的记录一致」。 verify 通过 ≠ 「这个 Skill 是安全的」。 若有条目无法判定(UNVERIFIABLE),本报告不会把它算作「未漂移」。 Findings / 发现(0 条) No findings: this skill matches the recorded baseline. 未发现差异:当前内容与锁定基线一致。 ======================================================================== wrote: C:\temp\demo-skill\VERIFY_REPORT.md wrote: C:\temp\demo-skill\verify-report.json echo $? 0 verify — 有人改了一个文件之后 将 scripts/run.py 中的 total = sum(range(10)) 改为 sum(range(11)): $ python scripts/skill_sentry.py verify demo-skill --no-write skill-sentry 0.2.0 - verify ======================================================================== Result : DRIFT (exit 1) / 检测到漂移(退出码 1) Lock file : C:\temp\demo-skill\skill-sentry.lock.json Skill dir : C:/temp/demo-skill Findings : error=1 review=0 info=0 unverifiable=0 fatal=0 What "verify passed" means / "verify 通过"到底意味着什么 verify PASS = "this skill still matches the recorded baseline". verify PASS != "this skill is safe". 若任一条目为 UNVERIFIABLE,则不计入「未变更」。 verify 通过 = 「与锁定时的记录一致」。 verify 通过 ≠ 「这个 Skill 是安全的」。 若有条目无法判定(UNVERIFIABLE),本报告不会把它算作「未漂移」。 Findings / 发现(1 条) [ERROR] FILE_MODIFIED scripts/run.py content differs from the locked baseline expected: 24b1ff2afa92d9bbcd0b6c43399aa5463d49600b59895e40dc7180b94e15ca72 actual: 1ebcbc3173f3a41516833b37ccd41a7079abea772de71a909452ed1dfa34ea5f Every finding above carries a path so it can be located in the diff. 上面每一条发现都带有 path,可在 diff 中直接定位。 ======================================================================== echo $? 1 Exit codes / 退出码 每条命令都使用相同的四个退出码。任何非零退出码都应视为「不要信任这个 Skill」。 | 退出码 | Meaning / 含义 | 触发条件 | |---|---|---| | 0 | OK | 无漂移,且全部可判定 / no drift, everything judged | | 1 | DRIFT | 确认漂移,或配合 --fail-on-policy 时的策略失败 | | 2 | ERROR | 无法完成:目录缺失、锁文件不可读/损坏/不兼容、IO 失败 | | 3 | UNVERIFIABLE | 无漂移,但部分条目无法判定 | 优先级恒为 2 > 1 > 3 > 0。退出码 3 存在的意义是:「判不出来」绝不能被报成「没变」。 What audit checks / audit 检查什么 | 领域 | 规则 | 捕获内容 | |--------|-------|---------| | Destructive | DEST | rm -rf /、清空 home、fork bomb、磁盘覆写 | | Network | NET | 出站请求、下载并执行的管道(curl … \| sh) | | Secrets | SECRET | SSH 目录、私钥、AWS 凭据、token 模式、环境变量收集 | | Obfuscation | OBF | Base64 解码、动态求值、反射 | | Injection | INJ | 「忽略之前的指令」、「绕过安全机制」、「不要告诉用户」 | | Persistence | PERSIST | shell 启动文件、cron、launch agents、systemd | | Filesystem | FS | 写入 /etc、/System、个人目录 | | Domains | DOMAIN | 引用的每个外部主机(SBOM) | 每次命中都会报告 file:line、rule_id、原因、置信度和级别 (INFO / REVIEW / HIGH)。启发式命中不是已确认的 漏洞——HIGH 级别的命中始终需要人工复核。 Threat model summary / 威胁模型摘要 完整模型见 references/threat-model.md。 What it protects against / 能防什么 | ID | 威胁 | 方式 | |---|---|---| | T1 | 安装后被静默添加或替换的代码 | lock 记录哈希基线;verify 报告带路径的 FILE_ADDED / FILE_MODIFIED | | T2 | 通过「更新」夹带的恶意代码 | 同上,另加 --reaudit 以比较审计摘要 | | T3 | TOCTOU:被审计的版本 ≠ 实际运行的版本 | 锁文件将审计结论与文件哈希绑定在同一个产物中 | | T4 | 策略被悄悄放宽,使旧的 PASS 失效 | 记录 policy.sha256;verify 报告 POLICY_CHANGED | | T5 | 无法证明“这就是我审查过的内容” | 锁文件是可 diff、可提交的证据 | | T6 | 新的未声明网络目标 | audit.domains 被锁定;--reaudit 会比较该列表 | | T7 | 符号链接将宿主机文件拖入范围 | 默认从不跟随符号链接;记录 link_target 以供审查 | | T8 | 使用超大或二进制文件耗尽工具资源 | 流式哈希、25 MiB 规则扫描阈值,二进制文件只做哈希但不解析 | What it does NOT protect against / 不防什么(节选——请阅读完整文件) | ID | 不防护 | 原因 | 本工具之外的缓解措施 | |---|---|---|---| | N1 | 被攻陷的宿主机 | 拥有同等文件权限的攻击者可以编辑 Skill、锁文件和工具本身 | 操作系统完整性保护、只读挂载、最小权限 | | N2 | 锁文件与 Skill 一起被编辑 | 默认情况下锁文件位于 Skill 旁边,且未签名;它不是信任根 | 在 Skill 之外使用 lock --lock-out;保护 Git 分支;外部签名(v3 正在评估) | | N3 | 运行时行为 | 纯静态:无沙箱、无系统调用过滤、无网络监控 | 容器 / 沙箱 / seccomp | | N4 | 意图 | 它只能说“与基线不同”,永远不能说“此更改是恶意的” | 人工审查 diff | | N5 | 作者身份与来源 | 无签名、无证书 | Sigstore / minisign 正在为 v3 评估 | | N6 | 归档文件和二进制文件的内容 | .zip 内的载荷不可见;只有 .zip 的哈希会变化 | 手动解包并审查 | | N7 | 密码学绝对性 | SHA-256 抗碰撞性是工程假设,而且没有签名 | — | | N8 | 实时信誉 | 它无法判断某个域名现在是否恶意 | 外部威胁情报 | | N9 | 运行时注入的机密 | 它有意从不读取环境 | 单独审计运行时环境 | | N10 | 规则引擎的误报/漏报 | 命中不等于漏洞;未命中不等于安全证明 | 人工审查;参见误报处理手册 | The one sentence to remember / 务必记住的一句话 verify 通过 = 「与锁定时的记录一致」 verify 通过 ≠ 「这个 Skill 是安全的」 若有条目无法判定(UNVERIFIABLE),本报告不会把它算作「未漂移」。 每份 verify 报告每次都会以两种语言打印这句话。 Honest limitations / 诚实的局限 - It does not guarantee that any Skill is safe. / 它不保证任何 Skill 的安全性。 - It does not execute the scanned Skill. / 它不会执行被扫描的 Skill。 - It does not upload anything, ever. / 它从不上传任何内容。 - A heuristic hit is not a confirmed vulnerability. / 启发式命中不等于已确认的漏洞。 - A clean verify means "matches the baseline", not "is safe". / verify 通过只意味着「与基线一致」,不意味着「安全」。 - The lock file is not signed in v2; anyone who can edit the Skill can edit it. See N2 above. / v2 的锁文件未签名,能改 Skill 的人就能改它(见上文 N2)。 - Symlink targets are recorded but not compared, because they are environment specific (see the threat model). / 符号链接的目标会被记录但不参与比对,因为它与环境相关。 Command reference / 命令参考 python scripts/skill_sentry.py audit [--policy P] [--out DIR] python scripts/skill_sentry.py lock [--policy P] policy file to record (its SHA-256 is stored) [--lock-out PATH] lock file path (default: /skill-sentry.lock.json) [--max-file-size N] rule-scan threshold in bytes (default 26214400 = 25 MiB) [--follow-symlinks] follow symlinks that stay inside the Skill (default: off) [--no-audit] skip the audit section (audit = null) [--fail-on-policy] exit 1 when the audit fails the policy [--indent N] JSON indent (default 2; 0 = compact) [--quiet] errors only python scripts/skill_sentry.py verify [--lock PATH] lock file path (default: /skill-sentry.lock.json) [--policy PATH] policy that overrides the one recorded in the lock [--out DIR] report directory (default: the lock file's directory) [--md-out PATH] [--json-out PATH] [--no-write] print only; write nothing [--check-audit] treat audit-summary changes as drift (exit 1) [--reaudit] re-run the rule engine and compare the summary [--ignore-empty-dirs] ignore added/removed empty directories [--allow-unverifiable] record unverifiable entries but keep exit code 0 [--quiet] --follow-symlinks is documented as "only use it when you fully trust this Skill": following a symlink means hashing content that lives outside the Skill directory. The containment check (the resolved target must stay under the Skill root) still applies. --follow-symlinks 的文档说明是「仅在你能完全信任该 Skill 时使用」:跟随符号链接 意味着哈希 Skill 目录之外的内容。即使开启,仍会强制「解析后目标必须仍在 Skill 根目录内」。 Install as an Agent Skill / 作为 Agent Skill 安装 Each host installs Skills on its own / 各宿主自行安装: Claude Code git clone https://github.com/whaojie797-design/skill-sentry ~/.claude/skills/skill-sentry Cursor git clone https://github.com/whaojie797-design/skill-sentry ~/.cursor/skills/skill-sentry Codex / OpenAI git clone https://github.com/whaojie797-design/skill-sentry ~/.codex/skills/skill-sentry Gemini CLI git clone https://github.com/whaojie797-design/skill-sentry ~/.gemini/skills/skill-sentry CI / 持续集成 - name: Verify Skills have not drifted run: | python scripts/skill_sentry.py lock ./skills/my-skill --lock-out build/my-skill.lock.json python scripts/skill_sentry.py verify ./skills/my-skill --lock build/my-skill.lock.json Storing the lock file outside the Skill directory (--lock-out) is the 更强的配置:对 Skill 的改动无法静默改写它自己的基线。详见 SECURITY.md。 把锁文件存到 Skill 目录之外(--lock-out)是更强的配置:对 Skill 的改动无法顺手 改写它自己的基线。详见 SECURITY.md。 零依赖 / Zero dependencies 运行时依赖:无。仅使用 Python 标准库 (argparse、dataclasses、hashlib、json、os、sys、stat、datetime、 platform、typing),代码面向 Python 3.9+。pytest 仅为测试期依赖。 运行时依赖:无。只用标准库,目标 Python 3.9+。pytest 仅为测试期依赖。 源码由 tests/test_guards.py 守护,该文件静态断言 没有任何模块导入 socket / urllib.request / http.client / subprocess, 从不调用 eval( / exec(,也从不读取 os.environ / os.getenv。 资源 / Resources - references/lock-file-schema.md — 逐字段 schema、演进规则、兼容性承诺 - references/threat-model.md — 完整威胁模型 - references/rule-catalog.md — 每条规则 ID 及其含义 - references/false-positive-playbook.md — 如何分诊命中项 - assets/skill-sentry.lock.example.json — 一个真实的锁文件 - assets/VERIFY_REPORT.example.md — 一份真实的验证报告 - assets/policy.example.yml — 团队策略模板 - CHANGELOG.md — 发布历史 - SECURITY.md — 漏洞披露 - docs/DESIGN-v2.md — v2 设计文档 许可证 MIT — Copyright (c) 2026 whaojie797-design。
同作者(whaojie797-design)的其他插件
扫码进群