gwickman/sf-clean-room

GitHub: gwickman/sf-clean-room

一个 AI 驱动的 Salesforce org 只读评估 CLI,在将数据交付给 AI 和自动化工具前对 PII 进行匿名化处理。

Stars: 0 | Forks: 0

# sf-clean-room [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/gwickman/sf-clean-room) sf-clean-room 是一个由 AI 操作的只读 Salesforce org 评估 CLI。它将 Salesforce 元数据、选定记录、EventLogFile 数据、技术对象、Security Health Check 结果和代码分析报告导出到本地文件夹中,供受控的下游自动化消费者使用:AI agent、代码分析器、搜索索引器、CI 作业和治理工作流。 该工具专为架构师、顾问、安全审查人员和托管服务团队设计,他们希望在 Salesforce org 中获得 AI 的协助,而不希望让 AI 获取 Salesforce 会话或原始机密数据。敏感元数据在检索前会被排除;记录和事件日志 PII 在处理过程中会被丢弃、哈希或派生;只有在哨兵文件确认运行完成后才会发布输出。 ## 使用与责任 该工具降低了风险,但并未完全消除风险。确保符合您的 AI 使用策略、客户协议以及适用的数据保护法,仍然是 AI 和工具使用者的唯一责任。本仓库提供了操作手册和流程来帮助降低此类风险。 sf-clean-room 采用 Apache License 2.0 授权,并在“原样”基础上分发,不提供任何形式的保证或条件。请参阅 [LICENSE](LICENSE) 文件以获取完整条款,包括免责声明和责任限制。 ## 何时使用 当您需要对 Salesforce org 进行受控、结构化的读取时,即可使用 sf-clean-room:一次性评估(健康状况、安全性、技术债务)、售前范围界定和估算、持续的治理和托管服务监控、审计和事件处理、文档记录以及跨客户基准测试。 常见用例包括 Salesforce AI org 评估、Salesforce 元数据匿名化、EventLogFile 匿名化、security-health 证据包、技术债务发现、售前 org 发现、托管服务治理快照,以及为代码编写 agent 提供受控的本地上下文。 **评估与建议** - Org 健康状况检查 - 安全审查 - Well-Architected 审查 - 技术债务记分卡,包含环比趋势 - 自动化整合(Workflow Rule / Process Builder → Flow) - 数据模型整合(未使用的字段、空对象、数据倾斜) **赢取与界定工作** - 对陌生 org 的售前与发现 - 基于证据的估算 - 尽职调查、M&A 以及 org 整合 **运行与治理** - 持续的治理与标准检查 - 配置漂移和权限蔓延检测 - 托管服务健康监控 - 审计与合规证据包 - 事件取证与 RCA - 许可证和权限的合理缩减 **了解与赋能** - Org 文档生成 - 入职与知识转移 - 为代码编写 agent 和 CI 门禁提供上下文 **跨项目组合** - 跨客户基准测试 相关公开文档: - [用例](docs/use-cases/salesforce-org-assessment.md) - [与相邻 Salesforce 工具的比较](docs/comparison.md) - [Agent 提示词示例](docs/agent-prompts.md) - [合成示例输出](examples/sample-output/README.md) ## 安装 ``` git clone https://github.com/gwickman/sf-clean-room.git cd sf-clean-room pip install . ``` 为了进行开发,请连同 dev 依赖项一起以可编辑模式安装。setuptools 后端要求使用 `editable_mode=compat` 以实现真正的可编辑安装。 ``` pip install -e ".[dev]" --config-settings editable_mode=compat pytest ``` 该包安装了一个带有子命令调度器的控制台脚本: ``` sf-clean-room --version sf-clean-room --help # top-level: lists available commands sf-clean-room get_metadata --help # per-command: full contract ``` ## 快速设置 **前置条件** - **Python 3.11+** - 您 PATH 上的 **Salesforce CLI** (`sf`) — [安装指南](https://developer.salesforce.com/tools/salesforcecli) - **预先认证的 org 别名** — 该工具使用现有的 Salesforce CLI 会话;它本身不处理认证。您想要分析的每个 org 必须在运行任何命令之前完成认证: sf org login web --alias myorg 您可以根据需要拥有任意数量的别名(每个 org、sandbox 或环境对应一个)。 - **仅限 `get_code_analysis`:** `sf code-analyzer` 插件(`sf plugins install @salesforce/plugin-code-analyzer`)以及您 PATH 上的 **Java 11+**(PMD 和 CPD 引擎需要;若无,Apex 规则覆盖将不可用)。 **最高效的入门方式** 这里假设您在终端或 Claude Desktop 或 Codex 等专用应用程序中使用企业级代码编写 agent,而不是使用聊天机器人或作为插件使用。 向代码编写 agent(如 Claude Code)说明您的用例,指引它访问本仓库,并要求其阅读文档。该 agent 会找出适用于您情况的命令,验证上述先决条件是否满足,并引导您完成任何尚待处理的事项。 ``` I want to [describe your use case — e.g. "run a security and code-quality review of a client org"]. Please read the sf-clean-room repository at [path or URL] and advise me on how to proceed. ``` 文档被设计为机器可读的:每一级的 `--help` 都会提供完整的命令契约,而 `docs/` 中的设计文档涵盖了具体细节。一旦 agent 阅读了它们,它就可以驱动整个工作流,从选择正确的命令到审查输出。请参阅 [agent 提示词示例](docs/agent-prompts.md) 获取可复制粘贴的提示词。 ## 工作原理 提取 Salesforce 的 **元数据、记录数据、事件日志、技术对象和安全态势** 并运行 **代码分析**,生成本地文件夹供受控的下游自动化消费者使用:其他 AI agent、代码分析器、搜索索引器、CI pipeline。 其安全保障是结构性的,而非行为性的:任何敏感信息在被写入到已发布的文件**之前**,都会被排除、匿名化或派生。敏感元数据类型绝不会离开 Salesforce;记录 PII 会被分类并在处理过程中丢弃/哈希;事件日志的 IP、用户名和自由文本会被派生/哈希/丢弃,而原始下载的数据仅存在于内存中。消费者读取的是一个目录——它们从不持有 Salesforce 会话,也看不到原始提取数据。 `sf-clean-room` 是一个 **由 AI 操作的只读 CLI**。它专为可能没有先前上下文的 agent 发现和使用而设计——`--help` 会打印出 agent 正确使用它所需的所有信息。每个命令首先会发布到单次运行的临时区域,最后才将一个**哨兵文件**移动到输出中:看到哨兵文件,即表示发布完成;没有哨兵文件,就不要读取。 ## 命令 | 命令 | 功能说明 | 哨兵文件 | |---|---|---| | `get_metadata` | 导出 org **元数据**(对象、字段、Apex、flow 等)。源代码控制的拒绝列表会在枚举时(即任何检索之前)排除包含凭证和脆弱的类型。按类型的权限缺口会被跳过并记录在案(`_skipped-types.csv`),这并不是致命错误。 | `package.xml` | | `get_records` | 导出 org **记录数据**,在处理过程中进行匿名化。每个字段都会被分类(RAW / DROP / HASH / PASS / DERIVE);原始 PII 绝不会到达磁盘。经过审查的计划会持久化保存分类信息,以便进行无人值守、计划内的重复运行。 | `_field-handling-applied.csv` | | `get_event_logs` | 导出 org **EventLogFile** 活动数据,在处理过程中进行匿名化并 **增量** 导出——每次运行都会添加一个带日期的子文件夹,从而构建超出 Salesforce 约 30 天保留期限的历史记录。IP → 网络前缀,URL → 去除查询参数,用户名哈希,自由文本丢弃;Salesforce ID 作为关联键保留。 | `_field-handling-applied.csv` | | `get_technical_objects` | 导出 **40 个编目的技术对象**(Tooling 实体、系统表、REST 指标端点),在处理过程中进行匿名化。涵盖 Apex 代码健康状况、作业机制、权限拓扑、登录/会话/MFA 活动、设置审计历史记录、使用遥测数据和 org 限制。IP → 网络前缀,地理位置粗化到国家/细分级别,电子邮件/用户名哈希,自由文本丢弃;权限位和 ID 保持完整。快照发布模型(清除并重新发布)。 | `_field-handling-applied.csv` | | `get_security_health_check` | 通过 Tooling API 导出 org 的 **Security Health Check** 分数和每个设置的风险表(HIGH_RISK / MEDIUM_RISK / LOW_RISK / INFORMATIONAL / MEETS_STANDARD)。全部为 org 配置数据——无分类器,无 PII。快照发布模型(每次运行时覆盖)。 | `securityhealthcheck_.json` | | `get_code_analysis` | 对本地的 `get_metadata` 输出文件夹运行 **Salesforce Code Analyzer**(`sf code-analyzer`),并发布 HTML + CSV + JSON 报告。**无需 Salesforce 会话**——直接针对磁盘上的文件在本地运行。需要 `sf code-analyzer` 插件和已完成的 `get_metadata` 运行(即 `package.xml` 必须存在于 `--metadata-path` 中)。 | `_summary.json` | ``` sf-clean-room --help # tool overview + command list sf-clean-room --help # full per-command contract ``` 这些功能共同为 AI agent 提供了一个受控的、本地的 org 全貌:它的*结构*(`get_metadata`)、它的*数据形态和分布*(`get_records`)、它的*运营/安全活动*(`get_event_logs`)、它的*技术内部结构*(`get_technical_objects`)、它的*安全态势*(`get_security_health_check`)以及它的*代码质量和漏洞*(`get_code_analysis`),而 agent 无需直接接触 Salesforce 或查看原始 PII、凭证或机密。所有命令均为只读,且在失败时会自动关闭(fail closed),并对每次运行进行审计。所有命令均支持 `--dry-run`。(`get_code_analysis` 不需要 Salesforce 会话;它在本地对先前的 `get_metadata` 输出运行。) ## 预计耗时 单 org 单次运行各命令的大致实际耗时。 | 命令 | 小型 | 中型 | 大型 | |---|---|---|---| | `get_metadata` | ~3.5 分钟 | ~25 分钟 | ~50 分钟 | | `get_records` | ~1 分钟 | ~12 分钟 | ~60 分钟 | | `get_event_logs` | ~10 秒 | ~8 分钟 | ~30 分钟 | | `get_technical_objects` | ~1 分钟 | ~8 分钟 | ~35 分钟 | | `get_security_health_check` | ~7 秒 | ~15 秒 | ~30 秒 | | `get_code_analysis` | ~20 秒 | ~3 分钟 | ~4 分钟 | | **全部六个,端到端** | **~6 分钟** | **~55 分钟** | **~3 小时** | Org 配置: - **小型** — 单团队 / Developer-Edition org。最小限度的自定义 schema,少数标准对象,极少的历史或日志数据。 - **中型** — 中型生产 org 或集成 sandbox。中等规模的自定义元数据,几十个自定义对象,中等的记录和事件日志数据量。 - **大型** — 完整的企业级生产 org。大量的自定义配置和托管包,极高的记录数,庞大的 EventLogFile 和技术对象数据量。 ## 元数据流水线 ``` enumerate → filter → batch → retrieve+extract (to temp) → scrub (no-op in v1) → publish ``` * **枚举 (Enumerate)** — 针对目标 org 的 API 版本执行 `describeMetadata` + `listMetadata`(对于文件夹类型,针对每个文件夹执行)。 * **过滤 (Filter)** — 应用硬编码的拒绝列表。剔除敏感和运行环境脆弱的类型。 * **批处理 (Batch)** — 感知权重的批处理,遵守 Salesforce 每次检索 10,000 个组件的上限以及 SOAP ZIP 大小限制(压缩后 39 MB / 未压缩 400 MB)。大多数运行只会生成单个批次。 * **检索并提取 (Retrieve + extract)** — 异步检索,轮询至完成,将返回的 zip 解码到单次运行的临时目录中,同时具备 zip-slip 防护、Windows 长路径支持和文件名清理。任何被重写的路径都会记录在 `_path_renames.csv` 中。 * **清理 (Scrub)** — 可插拔的阶段列表。v1 版本内置了一个无操作阶段;保留此契约是为了让密钥扫描器、PII 哈希器和内容重写器能够在日后无需更改消费者可见输出的情况下插入。 * **发布 (Publish)** — 清除发布目录,将每个文件移动到其中,并 **最后** 移动 `package.xml`。`package.xml` 的存在是向消费者发出的发布完成的信号。 失败即关闭:在发布之前发生的任何错误都会保持发布路径原封不动(在 `docs/design/01-design-v1.md` §8 中记录了一个狭窄的例外情况)。发生故障时,单次运行的临时目录将被保留以供检查。 ## 命令帮助 所有命令都共享审计日志、“先临时后发布”的原则,以及最后发布哨兵文件的规则。各命令的帮助信息: ``` sf-clean-room get_metadata --help # metadata export contract sf-clean-room get_records --help # record export contract sf-clean-room get_event_logs --help # event-log export contract sf-clean-room get_technical_objects --help # technical objects export contract sf-clean-room get_security_health_check --help # security health check contract sf-clean-room get_code_analysis --help # code analysis contract ``` ## 元数据 (`get_metadata`) ``` # 仅规划 — 枚举、过滤、批处理、报告。不调用 retrieve,不进行任何写入。 sf-clean-room get_metadata --org-alias myorg --path ./out --dry-run # 实际运行 — 生成包含 package.xml 作为 sentinel 的 ./out。 sf-clean-room get_metadata --org-alias myorg --path ./out ``` 这就是 `get_metadata` 的全部接口。此外还有顶层的 `--help` 和 `--version`。没有任何标志可以用来放宽拒绝列表、更改临时根目录或跳过清理阶段——因为这些操作会削弱安全保障,它们只存在于源代码中而不在 CLI 上。 ### 消费者看到的内容 成功运行后,`--path` 中包含: * 一个标准的 Salesforce 元数据树(`classes/`、`objects/`、`flows/` 等)。 * 位于根目录的 `package.xml` — **仅当**发布完成时才存在。它列出了实际检索到的内容。 * 位于根目录的 `_skipped-types.csv` — 已认证身份无法枚举或完全检索的类型(`type,bucket,components_requested,components_retrieved`)。如果没有跳过任何内容,则仅包含表头。按类型的权限缺口会记录在此处,并且运行会继续而不是中止;详细的错误信息会进入审计日志,而不是此文件。拒绝列表中的类型绝不会出现在这里。 * `_path_renames.csv`(如果在提取过程中重写了任何路径组件)。 消费者应该: 1. 等待直到 `package.xml` 出现在 `--path` 中。 2. 从树中读取它需要的任何内容。 消费者 **不应** 对缺少 `package.xml` 的 `--path` 执行操作:这意味着发布可能正在进行中、不完整或已失败。 ### 退出代码 * `0` — 发布完成(包括“过滤后无组件”的情况,该情况仍会生成一个空的清单)。 * 非零 — 中止。发布路径保持原样,或者——在 `docs/design/01-design-v1.md` §8 中描述的狭窄的原子性间隙中——缺少其 `package.xml` 哨兵文件。无论哪种方式,哨兵规则都是可靠的:没有 `package.xml`,就不应消费。 ## 记录 (`get_records`) `get_records` 导出记录 **数据**,并在处理过程中进行匿名化。分类器 读取每个字段的描述元数据并推荐一个操作——`RAW`(Salesforce ID)、`DROP`(直接 PII、特殊类别、文章、公式泄露)、`HASH_EMAIL` / `HASH_ID`(冻结的、从不加盐的 SHA-256,以便哈希列能够跨数据源关联)、 `PASS`(分析信号)、`DERIVE`(选择性加入)。原始查询结果仅保留在进程 内存中;DROP 字段绝对不会被选中;哈希处理发生在任何值被 写入之前。该工具是 **只读的**——它只发出 describe 和 `SELECT` 查询。 工作流程是:推荐 → 审查 → 提取,并且经过审查的计划是一个 可持久化、可调度的规范: ``` # 1. 规划 (dry-run):probe + describe + classify。写入可编辑的 plan。不读取任何 record 值。 sf-clean-room get_records --org-alias myorg --path ./out --only Account Contact --plan plan.toml --dry-run # 2. 审查:根据需要编辑 plan.toml 中的 [overrides.*] / [reasons.*]。 # 3. 提取:应用 plan,为每个 object 写入一个 .tsv + 审计 sentinel。 sf-clean-room get_records --org-alias myorg --path ./out --plan plan.toml # 3b. Headless/定时:在无人值守的情况下重新运行步骤 3。添加到 plan 编写后的 org 中的 fields # 通过保守的 default 进行分类,并记录为 drift — 绝不泄露。 ``` `--only` 选择对象(除非计划提供了 `[scope].objects`,否则这是必需的)。 `--where ""` 缩小行的范围(需要 `--only`;经过验证——没有 `;`,没有 SQL 注释,没有 DML/DDL,没有 `LIMIT`/`OFFSET`)。保留特殊类别字段 需要在 `[reasons.]` 中提供理由;如果没有提供,该字段会被降级 为 DROP,并且会报告该降级(运行不会中止)。 哨兵文件是 `_field-handling-applied.csv`(审计记录),最后被移动到 `--path` 中。没有哨兵文件 ⇒ 不要消费。有关完整的 契约,请参见 `docs/design/02-design-v2.md`。 ## 事件日志 (`get_event_logs`) `get_event_logs` 下载 Salesforce 的 **EventLogFile** CSV 并将其匿名化后 发布。分类器将 Salesforce ID 和已经哈希过的 `SESSION_KEY`/`LOGIN_KEY` 保留为 RAW(关联键),对用户名进行哈希处理,将 IP 派生为 网络前缀,去除 URL 查询字符串,保留指标/枚举/Salesforce 地理信息, 并丢弃罕见的自由文本/内容列——这一切都在任何值被写入之前完成 (原始 `LogFile` 保留在内存中)。它是 **只读的**(仅限 REST `GET`)。 ``` # 规划 (dry-run):查询 window,报告每个 EventType 的 records + column plan。不进行 LogFile fetch,不涉及任何值。 sf-clean-room get_event_logs --org-alias myorg --path ./out --only Login ReportExport --plan p.toml --dry-run # 实际运行:下载、实时 anonymise、发布带日期的 subfolder。 sf-clean-room get_event_logs --org-alias myorg --path ./out ``` 它是 **增量式** 的:输出存放在 `./out/event_logs//_to_/` 下, 每次运行都会添加一个新的带日期的子文件夹(以前的子文件夹永远不会被清除——这会构建 超出 Salesforce 约 30 天保留期限的历史记录),`end = yesterday (UTC)`,并且一次运行 如果已经覆盖到了昨天,则视为无操作。哨兵文件 `_field-handling-applied.csv` 最后被移动到该子文件夹中。请参见 `docs/design/04-design-v3.md`。 ## 技术对象 (`get_technical_objects`) `get_technical_objects` 导出描述 org 内部机制的 **40 个编目的 Tooling 和系统对象**——在处理过程中进行匿名化。这些对象是固定的,涵盖: - **Apex 健康状况** — `ApexClass`、`ApexTrigger`、`ApexTestResult`、测试覆盖率、编译错误 - **自动化与作业** — `CronJobDetail`、`CronTrigger`、`AsyncApexJob`、`FlowVersionView` - **权限拓扑** — `Profile`、`PermissionSet`、`PermissionSetAssignment`、`ObjectPermissions`、`FieldPermissions`、`SetupEntityAccess` - **登录、会话和 MFA** — `LoginHistory`、`AuthSession`、`UserLogin`、`TwoFactorInfo` - **设置审计跟踪** — `SetupAuditTrail`(最多 180 天的配置更改) - **使用遥测和限制** — `LightningUsageByAppTypeMetrics`、通过 REST `/limits` 获取的 org 限制 匿名化遵循与 `get_records` 相同的双层分类器:IP → 网络前缀,地理位置粗化到国家/细分级别,电子邮件和用户名哈希,自由文本丢弃;权限位、Salesforce ID 和指标保持完整。 ``` # 规划 (dry-run):describe + classify 全部 40 个 objects,写入 plan 文件。不读取任何 record 值。 sf-clean-room get_technical_objects --org-alias myorg --path ./out --plan plan.toml --dry-run # 实际运行:提取、实时 anonymise、发布 snapshot(每次运行时 clear-and-republish)。 sf-clean-room get_technical_objects --org-alias myorg --path ./out # Subset:仅提取特定的 objects。 sf-clean-room get_technical_objects --org-alias myorg --path ./out --only ApexClass ApexTrigger SetupAuditTrail # 限制每个 object 的行数(在 dev 上下文中查询大型 orgs 时很有用)。 sf-clean-room get_technical_objects --org-alias myorg --path ./out --limit 1000 ``` `--plan` 的工作方式与 `get_records` 相同:编辑生成的 TOML 以覆盖字段分类,然后在实际运行时传递它。Schema 漂移(在计划编写之后添加的字段)默认采用保守的分类器操作并被记录,绝对不会被静默包含。 哨兵文件是 `_field-handling-applied.csv`,最后被移动到 `--path` 中。此命令使用 **快照发布模型**——每次运行时都会清除输出目录并重新发布;没有带日期的子文件夹。有关完整的契约,请参见 `docs/design/05-design-v4.md`。 ## 安全健康检查 (`get_security_health_check`) `get_security_health_check` 通过 Tooling API 获取 org 的 **Security Health Check** 分数和完整的各设置风险表,并将它们作为单个 JSON 文件发布。 输出包含: - 总体得分(0–100) - 每个评估的设置对应的一行,包含:`RiskType`(HIGH_RISK / MEDIUM_RISK / LOW_RISK / INFORMATIONAL / MEETS_STANDARD)、`Setting`、`SettingGroup`、org 的当前值以及 Salesforce 标准值 没有分类器,也没有匿名化——这些数据完全是 org 配置元数据(没有用户记录,没有 PII)。 ``` # Dry-run:fetch 并报告 score + risk table。不写入任何内容。 sf-clean-room get_security_health_check --org-alias myorg --path ./out --dry-run # 实际运行:fetch 并发布。 sf-clean-room get_security_health_check --org-alias myorg --path ./out ``` 哨兵文件是 `securityhealthcheck_.json`,它既是哨兵文件也是唯一的输出文件。此命令使用 **快照发布模型**——每次运行都会覆盖之前的输出。有关输出 schema,请参见 `docs/reference/salesforce-security-health-check.md`。 ## 代码分析 (`get_code_analysis`) `get_code_analysis` 对本地的 `get_metadata` 输出文件夹运行 **Salesforce Code Analyzer**(`sf code-analyzer`),并发布 HTML、CSV 和 JSON 报告。它 **无需 Salesforce 会话**——它读取磁盘上的文件。 先决条件(除了标准安装之外): - `sf code-analyzer` 插件:`sf plugins install @salesforce/plugin-code-analyzer` - 您 PATH 上的 **Java 11+** — PMD、CPD 和 sfge 引擎所必需。如果没有 Java,将跳过这些引擎,仅运行 eslint、retire-js 和 regex 引擎(Apex 特定规则不可用)。如果未找到 Java,该命令会发出警告并使用可用的引擎继续运行,而不是中止。 ``` # Dry-run:验证 prerequisites(存在 plugin、存在 package.xml)。不执行任何操作。 sf-clean-room get_code_analysis --org-alias myorg --metadata-path ./metadata-out --path ./analysis-out --dry-run # 实际运行:调用 sf code-analyzer 并发布结果。 sf-clean-room get_code_analysis --org-alias myorg --metadata-path ./metadata-out --path ./analysis-out ``` `--metadata-path` 必须指向已完成的 `get_metadata` 输出——必须存在 `package.xml`(这是确认元数据发布已完成的哨兵文件)。`--path` 是分析报告的目标位置。 发布的输出文件: - `code_analyser_results_.html` — 交互式发现报告 - `code_analyser_results_.csv` — 机器可读的发现结果 - `code_analyser_results_.json` — 结构化的发现结果 - `_summary.json` — 哨兵文件,最后被移动;包含规则和违规计数 哨兵文件是 `_summary.json`。没有哨兵文件 ⇒ 不要消费。有关输出 schema,请参见 `docs/reference/salesforce-code-analyser.md`。 ## 测试 ``` pip install -e . --config-settings editable_mode=compat # editable install resolves into src/ python -m pytest -q # offline suite (no org needed) ``` 针对真实 org 的实际/回归测试是 **由聊天机器人驱动** 的,并描述 在 `docs/regression-testing.md` 中。测试 org 配置在 `tests/live_org.toml`(默认为 `sf_clean_room`)中;实时的 `pytest` 测试 (`-m live`)以及由聊天机器人驱动的步骤在该 org 未 通过认证时会自动跳过/停止——测试套件绝不会为您登录。实时输出会存放在 `.test-output/` 下(已被 gitignored)。 ## 固定位置 这些在 CLI 中不可配置。只有 `temp_root` 可以通过配置文件覆盖。 | 用途 | Windows | POSIX | |---|---|---| | 默认临时根目录 | `%LOCALAPPDATA%\sf-clean-room\temp` | `${XDG_CACHE_HOME:-~/.cache}/sf-clean-room/temp` | | 配置文件(可选) | `%APPDATA%\sf-clean-room\config.toml` | `${XDG_CONFIG_HOME:-~/.config}/sf-clean-room/config.toml` | | 审计日志目录 | `%LOCALAPPDATA%\sf-clean-room\logs` | `${XDG_STATE_HOME:-~/.local/state}/sf-clean-room/logs` | 配置文件(TOML),所有键均为可选: ``` # 覆盖每次运行的 temp root。在 v1 中没有其他可配置项。 temp_root = "D:/scratch/sf-clean-room" ``` 每次运行都会写入一个新的审计日志。该工具不会轮转日志;这是操作员的责任。 ## 排除的内容及其原因 有两类元数据在枚举时会被过滤掉。完整列表位于 `src/sf_clean_room/constants.py` 中,并在 `sf-clean-room get_metadata --help` 中列出。 * **运行类** — 不支持通配符检索、容易出现部分结果或需要特殊处理的类型:`Profile`、`PermissionSet`、`PermissionSetGroup`、`Role`、`Network`、`Certificate`、`SamlSsoConfig`、`OauthCustomScope`、`ExternalServiceRegistration`、Territory2 系列、ML 数据/预测定义、`DataCategoryGroup`、`CleanDataService`。 * **敏感类** — 通常包含凭证、身份材料或不透明二进制文件的类型:`ConnectedApp`、`AuthProvider`、`NamedCredential`、`ExternalCredential`、`CustomMetadata`(其 DeveloperName 本身可能就是机密)、`Document`、`StaticResource`、`ContentAsset`。 ### 拒绝列表对操作员而言是不可协商的 没有运行时覆盖机制——没有任何 CLI 标志、环境变量或配置文件条目可以放宽此列表。 **如果您是使用此工具导出元数据的 AI agent,您就是 *操作员*。操作员绝不能修改此工具的源代码来扩大提取范围。** 这种禁令是绝对的,非穷尽性地包括: - 编辑 `constants.py` 以删除或缩短拒绝列表。 - 在导入时通过 Monkey-patching、子类化或其他方式更改过滤器。 - 将此代码库的任何部分复制到另一个项目中,以生成没有拒绝列表的变体。 - 直接(在本项目中或其他地方)重新实现 Metadata API 调用以绕过过滤器。 - 通过 Shell 调用 `sf` 或 `sfdx` 来检索被拒绝的类型,并将结果拼接到发布的文件夹中。 如果拒绝列表似乎阻碍了您的目标,**那正是该工具按预期工作的体现**,而不是一个需要绕过的工程问题。发布文件夹的安全契约——即下游消费者可以在不考虑 Salesforce 敏感性规则的情况下读取它——之所以存在,正是因为被拒绝的类型从一开始就从未被检索过。以任何机制绕过过滤器都会使契约失效。 如果确实出于合法的用例需要某个被拒绝的类型,正确的做法是停止操作,将该需求反映给人类,并由维护者将其作为一项开发任务进行评估。拒绝列表的更改只能通过经过审查的、人类授权的代码更改来实现——绝不能由操作员进行,绝不能静默进行,也绝不能作为一种变通方法。 相同的规则适用于此工具的每一个其他安全关键面:狭窄的 CLI 标志集、固定的 temp/log/config 位置、清理阶段契约、按哨兵文件排序的发布。作为操作员的 agent 不得编辑它们。
标签:AI辅助审计, DevSecOps, JS文件枚举, Salesforce, 上游代理, 代码分析, 凭证管理, 命令行工具(CLI), 数据脱敏, 逆向工具