runverdict/sf-security-review-toolkit
GitHub: runverdict/sf-security-review-toolkit
一款 Salesforce AppExchange / AgentExchange 端到端安全审查工具包,通过多 Agent 自主审计与多维度扫描,帮助 ISV 合作伙伴完成从代码审计到就绪状态判定的全过程。
Stars: 2 | Forks: 0
# [](https://github.com/runverdict/sf-security-review-toolkit)
[](CHANGELOG.md) [](LICENSE) [](acceptance/test-ci-hygiene.mjs)
[](https://github.com/runverdict/sf-security-review-toolkit/actions/workflows/test.yml)
**对 AppExchange / AgentExchange 进行端到端的安全审查,从审计到真实的就绪状态判定。**
Claude Code 技能带领 ISV 合作伙伴**端到端完成 AppExchange / AgentExchange
安全审查准备工作**:根据审查实际测试的内容,对你自己的代码库进行自主的
多 Agent 审计,生成每一个可以被生成的提交工件,
编排所需的扫描,并为只有人类才能完成的部分提供分步操作手册,
最终得出一个真实的就绪状态判定:*你拥有什么,缺少什么,以及在提交之前*
确切需要做什么。*
## 目录
- [为什么开发它](#why-it-exists)
- [流程](#the-journey)
- [安装](#install)
- [用法](#usage)
- [技能](#the-skills)
- [扫描](#the-scans)
- [时效性模型](#currency-model)
- [输出结果示例](#what-the-output-looks-like)
- [为什么你可以信任输出](#why-you-can-trust-the-output)
- [供应链](#supply-chain)
- [如何进行验证](#how-it-was-validated)
- [文档](#documentation)
- [成熟度与注意事项](#maturity--caveats)
- [贡献](#contributing)
- [License](#license)
## 为什么开发它
安全审查是合作伙伴旅程中最艰难的关卡,而大多数首次失败都是可以预防的:
缺少 CRUD/FLS 强制实施(对象级别的 Create/Read/Update/Delete 权限和
Field-Level Security,即 Apex 默认跳过除非你手动编写的访问检查)、
无法测试的审查环境、不完整的工件、遗漏了身份端点的 DAST 报告,
以及含有未解释的 N/A 答案的问卷。本工具包将作者在准备自己的
AppExchange 提交过程中开发的方法论(包括多轮多 Agent 审计,
以及对每一个发现进行对抗性验证)进行了封装,并将由此产生的
工件格式、扫描工具组件和操作手册打包在一起。
## 流程
只需说出类似于 *“run the security review”* 的话(或者直接调用 orchestrator),
它就会接管一切:
```
/sf-security-review-toolkit:security-review-journey ← say "run the security review"
│ PREFLIGHT: a seconds-long read-only scan detects your architecture and senses
│ existing `sf` auth, then reports — ✓ what it found · ⚠ what it actually needs ·
│ ✦ optional power-ups (the Dev Hub auto-resolve and the deployed-package deep
│ audit are opt-in offers, never work the preflight does unprompted). In
│ FULL-AUTO it then asks for everything on exactly TWO screens — the run-mode +
│ depth election, then ONE batched consent screen — and runs to the finished
│ package, pausing only on a genuinely audit-blocking gap (source not findable,
│ a detection ambiguity); guided mode keeps every per-gate stop.
│ (The list below is the journey's DRIVE ORDER; the `Phase N` tag is each
│ skill's own phase identity. The static scans run BEFORE the audit, so the
│ audit ingests real scanner findings on its first pass instead of leaving
│ those families pending.)
│
├─ scope-submission Phase 0 · what are you listing? which requirements apply?
├─ run-scans Phase 3 · static substrate — Code Analyzer · deps · secrets · ext SAST/SCA/IaC (host-independent)
├─ audit-codebase Phase 1 · autonomous find → verify → synthesize audit, seeded by the substrate
├─ generate-artifacts Phase 2 · authn/authz flow, data flow, tools list, policy pack, …
├─ run-scans Phase 3 · live/conditional tail — DAST · TLS · portal prediction · whatever stayed pending
├─ (opt-in, `sf`-authed) the deployed-package deep audit — the six-step chain below
├─ reviewer-simulation what Salesforce Product Security will see, ranked by attack priority
└─ compile-submission Phase 5 · questionnaire, checklist, SCI verdict, wizard-slot package
companion skills you invoke directly (not driven by the orchestrator):
prepare-test-environment Phase 4 · reviewer-facing test org, agent + utterance evidence, test users
stay-listed post-approval · re-review cadence, release gates, incident duties
the opt-in deep audit — audit the package AS THE REVIEWER WILL (installed in a throwaway org):
bootstrap-cli-auth → teardown-mcp-registration (clean baseline) → build-managed-package
(only if no released version exists) → install-and-verify-package → audit-deployed-package
→ teardown-mcp-registration (zero residue)
```
orchestrator 是一个自主驱动程序,而不仅仅是一个路由器:
它会检测你的代码库进度(状态保存在 `.security-review/` 中,工件保存在
`docs/security-review/` 中),并从该处恢复,一直运行直到生成一个完整的、
可下载的提交包,并且只在其真正需要你介入时才会停止:遇到阻碍审计的输入
或同意关卡。整个流程对你的源代码是**只读的**(公开且受同意关卡控制的例外情况是:
深度审计中针对无发布版本的打包后备方案,以及可选的 Dev Hub 自动解析
metadata 检索),任何超出本地只读工作的操作都依赖于经过记录且失败即终止(fail-closed)
的同意行为(完整的同意模型和权限设置详见[无人值守运行](docs/permissions.md)),
并且其最强的判定永远只是*“在我们能够验证的范围内没有已知的阻碍;
Salesforce 仍会进行渗透测试,”* 而绝不是*“你一定会通过。”*
## 安装
这是一个 **Claude Code 插件**:它在 [Claude Code](https://claude.com/claude-code) 内部运行,而不是作为独立的 CLI 运行。你需要:
1. **Claude Code**(CLI 或 IDE 扩展),工具包在其中运行。
2. **Node.js 18+**。`harness/` 下的确定性引擎仅使用 Node 内置模块:不需要 `npm install`,没有依赖树。超越你本机范围的代码路径是受同意关卡控制的执行器(参见[供应链](#supply-chain)),以及针对你已授权的 org 执行的一小部分只读 `sf` CLI 读取操作(org、package-version 和 namespace 查找,其只读类别与[无人值守运行](docs/permissions.md)中的允许列表相同)。
3. *可选:* 已授权给你的 Dev Hub 的 **Salesforce CLI**,仅用于受 `sf` 关卡控制的已部署包深度审计。
在 Claude Code 内部,添加并安装该插件(这些是 Claude Code 的斜杠命令,而不是终端命令):
```
/plugin marketplace add runverdict/plugins
/plugin install sf-security-review-toolkit@runverdict-plugins
```
[`runverdict/plugins`](https://github.com/runverdict/plugins) 是每一个 Verdict
工具包的目录:只需一个市场,因此安装第二个工具包永远不会干扰这一个。
## 用法
然后只需说 **“run the security review.”** orchestrator 会驱动整个
流程;你也可以直接调用任何单个技能,包含自动化级别的完整列表见
[技能目录](docs/skills.md)。你永远不需要自己运行
`harness/*.mjs` 文件;它们是技能调用的内部引擎。
(要运行常驻测试套件:`for t in acceptance/test-*.mjs; do node "$t" || exit 1; done`。)
要在没有逐步权限提示的情况下进行无人值守运行,并阅读该插件提供的两个公开的强制执行钩子,请参见
[无人值守运行](docs/permissions.md)。任何超出本地只读工作的操作
(扫描器安装、一次性的 DAST 镜像、已部署 org 的深度审计,
任何实时端点探测)始终需要明确的、有记录的许可;没有
允许列表或自动接受机制可以绕过这些关卡。
## 技能
14 个技能:自主的 `security-review-journey` orchestrator 以及它驱动的阶段技能
(`scope-submission`、`audit-codebase`(跨越 19 个威胁维度的多 Agent 审计)、
`generate-artifacts`、`run-scans`、
`reviewer-simulation`、`compile-submission`),可直接调用的伴侣技能
`prepare-test-environment` 和 `stay-listed`,以及由 5 个技能组成、受 `sf` CLI 关卡控制的
**已部署包深度审计**链,该链会将你的包安装到一个临时的 org 中,并完全按照审查者的方式进行审计。
完整的目录、每个技能、其功能及其自主化程度详见
[技能目录](docs/skills.md)。
## 扫描
安全审查要求的大部分内容都是*扫描证据*。在有记录且失败即终止(fail-closed)的
同意关卡之后,工具包会将最多 17 个 OSS 扫描器(SHA-256 锁定的原始下载文件)
安装到临时目录中,运行其自带的五个零安装
Salesforce-metadata 扫描器,为你运行 Code Analyzer,
为真正的 ZAP DAST 建立一个一次性且仅限本地回环的后端镜像,
将索引后的证据写入 `.security-review/evidence/`,
然后移除工具并拆除镜像,**只保留证据**。真正保留给你的是:
Checkmarx 门户上传和实时生产环境经过身份验证的 DAST,为此它
会为你提供确切的步骤和预测的发现结果。
完整的机制(每一个扫描器、锁定规则、镜像的来源围栏)详见
[扫描](docs/scans.md)。
## 时效性模型
截至该工具包最初在 2026 年 6 月进行的源码扫描(条目此后持续重新验证;
参见每个条目的 `last_verified`),Salesforce 在过去的十八个月中已经三次更改此流程:
Chimera DAST 扫描器退役(2025 年 5 月宣布)、
Code Analyzer v5 强制要求以及 AgentExchange 发布,
每项都在 [`baseline/SOURCES.md`](baseline/SOURCES.md) 中提供了来源。
因此,所有的需求事实都以数据的形式存在于
[`baseline/requirements-baseline.yaml`](baseline/requirements-baseline.yaml)
中:每个条目都包含其来源、验证状态和最后验证日期。
当技能所依赖的条目过期时,技能会发出警告,并且具有冲突来源的
条目会被标记为“请与您的 Partner Account Manager 确认”,而不是被默默地忽略。
截至最新的源码扫描,**166 个基线条目中有 123 个是 `verified_primary`**(已根据官方 Salesforce 文档或受合作伙伴控制的主要来源确认),**42 个仍为 `web_research_unverified`** 等待主要来源确认,1 个为 `conflicting`(请通过您的 Partner Account Manager 解决,而不是在此 repo 中解决)。验证状态在 YAML 文件中是按条目划分的,因此请检查你所依赖的条目,而不是整体状态。
带有主要来源引用、更新基线的 PR 是
你能做出的最有价值的贡献。
## 输出结果示例
工具包的最终工件是一个就绪状态判定:你拥有什么,缺少什么,以及在提交之前确切需要做什么:
```
SUBMISSION READINESS — BLOCKED
Submission Completeness Index: 34% (not a pass prediction — 1 open blocker)
BLOCKERS (must clear before submit)
✗ apex-exposed-surface AccountController.getDetails — SOQL read without CRUD/FLS (CRITICAL)
→ enforce WITH USER_MODE on the read
FIX OR DOCUMENT BEFORE SUBMISSION
✗ admin-surface viewAllRecords on a sensitive custom object (HIGH)
→ drop viewAllRecords; grant per-record via sharing
ARTIFACTS 14/17 · AuthN/AuthZ flow WITHHELD (open authz blocker)
SCANS Code Analyzer ✓ · DAST pending · TLS A · secrets ✓
FINDING STABILITY (3-run consensus)
reliably recurring Controller-FLS — all 3 runs
contestable band: 1 — a human must adjudicate, run by run
PATH TO GREEN → 1 blocker → 1 high → 3 minor (path-to-green.md)
```
*展示格式用。通过的运行绝不意味着“你一定会通过”;Salesforce 仍会进行渗透测试。*
## 为什么你可以信任输出
模型负责发现;确定性代码负责把关。较弱的
模型产生的发现较弱,它不会使关卡崩溃:
- **两种来源、一个账本,引擎的优先级高于模型。**
- **确定性边界是一个优先召回的工作清单,而不是判定。**
- **`harness/` 中的确定性引擎负责执行对诚实度至关重要的属性,而不是靠模型的善意。**
- **报告永远无法超越账本。**
- **每一次反驳都需要代码证据,且每一次处置都是有界限的。**
- **工具包将自己视为不受信任。**
- **它对自身的能力上限很诚实:**参见[`docs/ceiling-test.md`](docs/ceiling-test.md)。
每个声明的完整机制,包括执行引擎和保护它的常驻测试,
都在[为什么你可以信任输出](docs/trust.md)中进行了详细说明,并映射到
[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) 中的代码摘录。
## 供应链
一个安全工具本身应该能在几分钟内完成审查,因此该工具包将其自身的攻击面保持在最低水平:
- **零运行时 npm 依赖。**此仓库没有 `package.json`:没有 lockfile,没有 `npm install`,没有传递依赖树。`harness/` 中的每个引擎以及 `hooks/` 中的两个执行钩子都只导入 Node 标准库(`node:fs`、`node:crypto` 等)和此仓库中的文件;扫描器输出解析(SARIF/JSON、Salesforce metadata XML、纯文本)是在仓库内实现的。你 clone 的代码就是运行的完整测试工具。
- **锁定并经过摘要验证的扫描器安装。**唯一一个在主机上下载第三方二进制文件的引擎(`harness/install-scanners.mjs`)采用失败即终止(fail-closed)策略:原始二进制文件下载已锁定版本,并在任何文件被设为可执行或解压之前,根据作者锁定的校验和进行 SHA-256 验证;如果摘要不匹配,则中止该工具,而不是执行未经验证的二进制文件;没有锁定的工具/平台会被跳过,绝对不会在未经验证的情况下安装。包管理器安装(pip/npm/git)没有针对单个文件的锁定,而是依赖于管理器自身的完整性层(PyPI / npm / Git-over-TLS)。其余涉及网络的代码路径是受同意关卡控制的实时执行器(经过摘要锁定的 ZAP 镜像拉取、docker 启动、scratch-org 生命周期、org 捕获),每一个都会验证其记录的同意令牌,如果没有令牌则失败即终止(fail-closed),此外还有一小部分只读的 `sf` 层级(可选的 Dev Hub 自动解析、org-list 探测、agent-test 归一化程序),它仅通过你已授权的 CLI 访问 Salesforce,并受技能级别的可选开启限制,而不是受记录的令牌限制。
这两个属性都由常驻检查锁定:[`acceptance/test-ci-hygiene.mjs`](acceptance/test-ci-hygiene.mjs) 中的 `SC-*` 检查会在发现被追踪的 `package.json` 或 `harness/`/`hooks/` 中存在第三方导入时导致构建失败,并断言本节本身的声明是存在的,从而使文档和防护机制不会偏离,而锁定安装行为(先验证后执行、不匹配则失败即终止、未锁定则跳过)由 [`acceptance/test-install-scanners.mjs`](acceptance/test-install-scanners.mjs) 针对本地 `file://` 工件进行锁定。机器可读的自我 SBOM 是未来计划添加的候选功能;目前尚未提供。
## 如何进行验证
方法论和测试工具是从一个实际 AppExchange 准备过程中,对生产级多租户 SaaS 代码库进行的真实多轮审计中提取出来的。在空的账本冷启动运行,审计重新发现了每一个已知公开的发现结果,用代码证据反驳了错误的候选结果,并且生成的工件包与手工构建的参考相匹配。在每一次更改中,常驻验收套件都会针对夹具派生的证据锁定确定性引擎和钩子,完全密封:没有网络,没有 `sf`,没有模型。针对合成夹具(一个灾难召回夹具和一个大部分符合规定的中间带判断夹具)进行的完整冷运行是每个版本的验证活动,根据预先提交的通过条件进行评分,并且一次顺利通过即可为发布标签把关。**诚实的上限:**这是作者自己的代码和自行编写的测试夹具,因此只有第三方包或真正的 Salesforce 审查才能测试其泛化能力。
## 文档
- [技能目录](docs/skills.md):每个技能、深度审计链、自动化级别。
- [扫描](docs/scans.md):8 个扫描家族、17 + 5 个扫描器、锁定机制、DAST 镜像。
- [无人值守运行](docs/permissions.md):只读允许列表、同意关卡、两个执行钩子。
- [为什么你可以信任输出](docs/trust.md):完整的防护机制。
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md):映射到引擎、测试和代码摘录的每一个强制执行属性。
- [`docs/ceiling-test.md`](docs/ceiling-test.md) · [`docs/recurrence-confidence.md`](docs/recurrence-confidence.md):衡量它能够和不能证明什么。
- [`docs/INDEX.md`](docs/INDEX.md):完整的文档索引。
- [`CHANGELOG.md`](CHANGELOG.md):版本历史。
## 成熟度与注意事项
**14 个技能 · 19 个审计维度 · 8 个扫描家族 · 最多 17 个受同意控制的 OSS 扫描器 + Code Analyzer + 5 个零安装 Salesforce-metadata 扫描器 · 一个 19 适配器的确定性发现带 · 一个确定性的提交完整性指数 + 一条通往绿灯的排序路径 · `harness/` 中由常驻测试套件(89 个文件中的 1,388 项检查)守护的核心确定性引擎**,如果重构破坏了强制关卡或其确定性,则会导致构建失败。
诚实的 beta 阶段(参见本 README 顶部):确定性边界是可靠的
且字节可复现;存在争议的严重性边界需要多次运行
加上人工裁定,并且这是在作者自己的代码和自行编写的
测试夹具上验证的,因此只有第三方包或真正的 Salesforce
审查才能测试其泛化能力。通过的运行绝不意味着“你一定会通过”;Salesforce
仍会进行渗透测试。当前的版本和发布说明请参见 [`CHANGELOG.md`](CHANGELOG.md)。
## 贡献
阅读 [`CONTRIBUTING.md`](CONTRIBUTING.md) 了解工作流程,
阅读 [`CONVENTIONS.md`](CONVENTIONS.md) 了解具有约束力的规则。更新
[`baseline/requirements-baseline.yaml`](baseline/requirements-baseline.yaml)
并提供主要来源引用,或者填补召回空白的贡献,是你能做出的
最有价值的 PR。参与即表示你同意
[行为准则](CODE_OF_CONDUCT.md)。
## License
Apache-2.0。参见 [LICENSE](LICENSE)。
标签:AI智能体, MITM代理, Salesforce, 自定义脚本