oh-my-pi 安全扫描完全指南security_scan 工具与 OMP 原生/Codex Security 云扫描实战【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pisecurity_scan是 oh-my-piOMP内置的安全审查工具它把“计划—执行—发布—验证”四段式扫描流程封装为 9 个明确动作本地native侧支持对仓库、路径子集、ref 差异和工作树进行不可变快照审查云端侧则显式对接 ChatGPT Codex Security 云控制面。读完本文你将掌握如何启用该工具、理解每个动作的参数与执行模型、使用security://只读命名空间读取扫描结果并通过源码级证据了解其指纹校验、受限会话与凭据固定的底层机制。一、工具定位与整体设计security_scan在 OMP 中被归类为exec级工具可被发现discoverable、严格 schemastrict、需要执行审批。它的核心设计是plan-then-execute先计划后执行任何扫描都以一次preflight生成**不可变计划immutable plan**为起点计划把仓库快照、模型、凭据、范围、输出策略全部钉死start才真正把计划提交为后台 OMP 任务之后用status轮询、cancel取消云端动作cloud_*与原生扫描完全独立永远不会作为原生扫描的降级回退。工具的实现入口在 packages/coding-agent/src/tools/security-scan.ts它通过switch (params.action)把 9 种动作分发到预检preflight.ts、协调器coordinator.ts和云客户端cloud.ts。面向模型的工具描述见 packages/coding-agent/src/prompts/tools/security-scan.md。二、启用与前提条件2.1 开关设置security.enabled默认值为false定义见 packages/coding-agent/src/config/settings-schema.ts#L4500-L4510UI 位于Settings → Tools → Security。禁用状态下security_scan不会出现在可用工具集中测试 gate.test.ts 验证了“禁用时 absent、启用时 present”的行为security://读取会抛出SecurityDisabledError提示开启security.enabled true直接执行工具会报错Security is disabled. Enable security.enabled before using security_scan.启用方式二选一在设置界面Settings → Tools → Security勾选或在配置中写入security.enabled true。2.2 原生扫描的前提原生preflight要求同时满足前提说明Git 仓库必须处于 Git 仓库内preflight通过vcs.git(cwd)解析仓库根目录活动模型会话必须持有活动模型计划中会记录provider/modelId模型与认证注册表协调器需要modelRegistry与authStorage见 coordinator.ts 中coordinatorForSession的校验存储的 OAuth 凭据活动模型对应 provider 必须已有OAuth凭据仅 API-key 认证不被接受2.3 凭据选择与固定凭据选择逻辑在 packages/coding-agent/src/security/auth.ts 的selectSecurityAccount中显式传credential_id正整数直接锁定该行凭据若不存在报错未传优先选active账号仅一个账号时自动选中多个账号且无活动账号报错要求显式传credential_id。一旦选中不可变计划会固定这条凭据行以及其记录的账号/工作区身份credentialId、accountId、email、orgId、orgName。执行与 token 刷新始终命中同一行createExactSecurityOAuthResolver禁止凭据轮换到其他账号身份一旦变化即报Security scan authentication identity mismatch。2.4 云动作的前提cloud_*系列动作要求存在openai-codexChatGPT OAuth 凭据。它们调用的是 ChatGPT 的 Codex Security 云控制面默认端点https://chatgpt.com/backend-api/aardvark见 cloud.ts不是公开 OpenAI API且绝不作为原生扫描的回退。三、输入参数完整参考security_scan的全部参数由 ArkType schema 定义见 security-scan.ts#L19-L43未使用的可选字段会被对应动作忽略字段类型使用动作说明actionpreflight \| start \| status \| cancel \| validate \| cloud_scans \| cloud_start \| cloud_status \| cloud_pull所有必填分发选择器plan_idstringstartpreflight返回的计划 IDoperation_idstringstatus、cancelstart返回的操作 IDtarget_kindrepository \| scoped_path \| ref_diff \| working_treepreflight默认repositoryinclude_pathsstring[]preflight仓库相对路径纳入不可变范围scoped_path必须至少一个非空值exclude_pathsstring[]preflight从范围移除的仓库相对路径排除优先于包含base_revisionstringpreflight配合ref_diff必须与head_revision同传preflight 时解析为 commithead_revisionstringpreflight配合ref_diff必须与base_revision同传preflight 时解析为 commitknowledge_base_pathsstring[]preflight相对仓库根解析、规范化按 SHA-256 与大小固定output_rootstringpreflight可选外部结果目录必须位于仓库外、规范化、非符号链接且需为空除非archive_existingtruearchive_existingbooleanpreflight默认false为true时允许执行开始时把非空输出目录改名为output_root.archive-scan-idcredential_id正整数原生preflight所有云动作固定一个 OAuth 凭据原生扫描为活动模型 provider 选择云动作为openai-codex选择scan_idstringvalidate包含目标 finding 的已存扫描finding_idstringvalidate要更新的已存 findingvalidation_statusunvalidated \| validated \| rejected \| partial \| errorvalidate新的验证状态validation_summarystringvalidate必填、非空的验证说明validation_evidence{label: string, explanation: string}[]validate可选追加为验证证据label 必须非空cloud_configuration_idstringcloud_status、cloud_pullCodex Security 云配置 IDrepository_idstringcloud_start必填云仓库标识repository_urlstringcloud_start必填云仓库 URLenvironment_idstringcloud_start必填云环境标识lookback_days正整数或allcloud_start默认30all表示无限回看四、输出与执行模型每个动作都返回一个文本内容块加结构化details含action与动作专属对象结构定义在 security-scan.ts#L47-L57。工具本身不流式输出部分参数或进度。start会立即返回排队中的操作扫描在后台以独立的 OMP 任务运行任务负责上报进度调用方通过status获取持久化的操作状态。操作快照details.operation包含operationId、planId、scanId、phase、时间戳、findingCount以及可选的jobId、sessionFile、error。操作阶段机queued → preparing → reviewing → publishing → completed终结替代状态partial、cancelled、failed。五、Action 详解5.1preflight生成不可变计划preflight解析并持久化一个不可变计划随后返回Security plan plan-id is ready. Fingerprint: fingerprint. Start it with actionstart and plan_idplan-id.details为{ action: preflight, plan: { id, fingerprint } }。计划会钉死pin以下全部要素规范化仓库根目录与归一化后的 include/exclude 范围目标快照target snapshotref_diff时解析后的 base/head 提交与 diff 摘要活动 provider/模型及可选 thinking 级别精确的 OAuth 凭据行与其账号/工作区身份知识库文件身份路径 SHA-256 大小输出策略output_root、archive_existing、目录现状安全设置快照与协调器 prompt/工作流指纹。目标摘要tree digest的构成从 preflight.ts 的digestWorkingTree可以看出repository、scoped_path、working_tree对范围内 tracked 与 untracked 文件的路径、内容、可执行位、符号链接目标做 SHA-256 逐项哈希并混入当前 HEAD无提交时为unborn最终指纹形如omp-security-tree/v1:sha256:digestref_diff对解析后的 base/head commit 及其原始树 diff 计算指纹形如omp-security-diff/v1:sha256:digest。范围路径校验normalizeRelativePath/validateScopePaths必须为仓库相对路径拒绝绝对路径、..越级、null 字节、Windows 盘符前缀必须真实存在且解析后仍在仓库内路径会被规范化、去重、排序。ref_diff中未知 ref 会报Unknown security scan base revision/head revision。输出目录策略normalizeOutput/prepareSecurityOutputDirectory省略output_root时在项目 OMP 安全状态目录下分配私有唯一目录调用方提供的目录在 preflight 时若不存在则创建mode0700其父目录必须已有规范化身份目录不能是符号链接、不能位于被扫描仓库内部非空目录必须archive_existingtrue执行开始时整目录改名为output_root.archive-scan-id。5.2start加载计划并校验新鲜度start从存储加载计划并基于当前的目标、安全设置、知识库、输出策略、工作流重新计算指纹。一旦不匹配即失败Security scan plan is stale: expected old, got new. Run security preflight again.此机制在assertSecurityScanPlanFresh中实现见 preflight.ts#L400-L409保证扫描目标与配置在计划与执行之间不被静默变更。成功则立即返回并注册后台工作Security scan scan-id started as operation-id.受限扫描会话createDefaultSecuritySession见 coordinator.ts#L227-L271具备以下特性工具白名单只有 7 个read、grep、glob、lsp、ast_grep、task、security_publishSECURITY_SESSION_TOOLS其中 LSP 为只读只允许security-reviewer类型任务 worker并关闭其 prewalk扩展发现extension discovery、MCP、IRC 全部禁用模型回退retry.modelFallback、retry.usageAwareFallback、retry.fallbackChains与账号轮换关闭会话为自动批准auto-approvespawns: security-reviewer。ref_diff执行特例执行时在 OMP 安全状态目录下targets/scan-id创建 detached 临时 worktree 并固定到 head 提交把钉死的 diff 文本注入审查会话结束后worktreeRemove清理并删除目录见prepareSecurityExecutionTarget。其他 target 类型直接审查仓库根目录。5.3status查询持久化状态需要operation_id返回Security scan scan-id: phase; count finding(s).完整操作快照在details.operation。终结操作会跨会话从项目 store 恢复#recoverInterruptedOperations。进程重启会把遗留的running/planned扫描标记为failed错误信息为Security scan was interrupted by a process restart并清理 ref-diff 目标 worktree。未知 ID 抛出Unknown security operation: id。5.4cancel协作式取消需要operation_id存在异步任务通过任务管理器取消否则中止协调器本地控制器与扫描会话。返回二选一Cancellation requested for operation-id. No running operation operation-id.details.cancelled表示请求是否被接受details.operation在操作存在时一并返回。已终结与未知操作返回false。取消是协作式的只有后台运行处理 abort 并持久化终态 bundle 后操作才进入终结态cancelled。5.5validate验证/拒绝已存 finding需要scan_id、finding_id、validation_status及非空validation_summary。更新规范存储中的 finding并可选追加验证证据记录每条证据由createSecurityEvidenceId生成kind 为validationFinding finding-id validation is now status.details.finding包含 finding ID 与验证状态。扫描/finding 缺失或必填字段缺失时直接失败而非新建 findingstore 的updateValidation还会校验所有evidenceIds必须已存在。5.6cloud_scans列出云配置列出所选 ChatGPT 账号可见的全部分页配置。每行包含配置 ID、当前步骤step、仓库 ID、环境 ID、仓库 URL。无配置时工具会明确说明。结构化配置放在details.cloudConfigurationslistAllConfigurations以 500/页滚动拉取。5.7cloud_start创建云扫描配置需要repository_id、repository_url、environment_id。创建并启用一个 Codex Security 云扫描配置同时消耗该账号独立的云扫描额度body 中state: enabled见 cloud.ts 的startScan。lookback_days默认30传all则lookback_days置null表示无限回看。Codex Security cloud scan configuration.id started for repository_url. This consumes cloud scan allowance.details.cloudScan为{ id, repositoryUrl }。5.8cloud_status云扫描进度需要cloud_configuration_id。报告当前步骤与已完成/待处理提交数Codex Security cloud scan id: step; finished finished commit(s), pending pending.details.cloudStats还包含失败提交数、按严重级别统计的 finding 数critical/high/medium/low/informational、最近扫描提交与时间戳服务可用时。5.9cloud_pull导入云结果需要cloud_configuration_id。拉取配置、状态与全部归属 finding 详情转换为 OMP 规范 schema生成报告与 SARIF并持久化为一个completed 的导入扫描target.kind: importedproducer 为codex-security-cloud。导入失败即关闭fail closed当前项目必须存在originremote且其归一化仓库身份与云配置 URL 匹配repositoryIdentity归一化处理.git后缀、userhost:pathscp 风格与 URL 风格assertCloudRepositoryMatchesStore校验。因为 findings API 不暴露覆盖收据导入扫描的 coverage 记为unknown。details.importedScan含新 scan ID 与 finding 数。六、原生发布与持久化6.1security_publish会话内的发布工具security_publish是内部、严格、write 级工具只在受限原生扫描会话内可用不是正常调用方动作schema 见 publication.ts。协调器要求扫描 agent 恰好调用它一次携带去重后的 findings含 rule、title、summary、severity、confidence、category、至少一个范围内的 location可选 evidence/remediation/CWE以及 validation 状态诚实完整的 coverage审查面surfaces、明确排除、延后工作deferred、开放问题open questions最终 Markdown 报告。发布约束在buildFinding与createSecurityPublicationTool中强制拒绝绝对路径、父级越级..、超出不可变范围的 finding/evidence 路径pathMatchesSecurityScope校验相同规范指纹ruleId category anchor locations的重复 finding 去重第二次成功发布调用失败Security scan scanId has already been published扫描会话结束而未发布 → 扫描持久化为partial成功发布 → 保持completed即使后续指标/输出刷新失败也降级不失效coordinator 中publishedBundle分支保证。6.2 规范存储与输出文件规范状态是私有的、按项目键控project-keyed存放在 OMP 安全状态根目录下。写入由 store.ts 的writeSecurityFileAtomic完成先写带随机后缀的临时文件flag: wx独占再rename原子落盘并用进程内写链 文件锁串行化同一 store 的读改写事务。一个完成的原生输出目录即调用方指定的output_root或私有分配目录包含文件说明scan.json公开扫描清单最后写入作为提交标记commit markerfindings.json发现列表report.mdMarkdown 报告results.sarifSARIF 导出provenance.json私有元数据已脱敏非 Windows 平台上目录加固为0700、文件为0600。七、读取结果security://只读命名空间security://命名空间不可变immutable、按项目隔离由 packages/coding-agent/src/internal-urls/security-protocol.ts 的SecurityProtocolHandler实现URL结果security://命名空间索引security://scans已存扫描列表security://scans/scan-id扫描摘要与子资源索引security://scans/scan-id/manifest公开清单 JSON含计划security://scans/scan-id/findingsfinding 列表security://scans/scan-id/findings/finding-id渲染后的 finding位置、证据、修复建议security://scans/scan-id/coveragecoverage JSONsecurity://scans/scan-id/reportMarkdown 报告存在时security://scans/scan-id/sarifSARIF JSON存在时security://scans/scan-id/provenance脱敏后的 provenance JSON变更只能通过security_scan动作或显式安全命令进行URI 读取绝不验证、导入、取消或修改任何状态。该协议还实现了 URL 补全complete可为扫描及其 6 种子资源提供候选。八、完整示例8.1 计划并启动一次全仓库扫描{action:preflight,target_kind:repository,exclude_paths:[vendor,dist]}{action:start,plan_id:secplan_id}8.2 精确版本差异扫描 外部输出目录{ action: preflight, target_kind: ref_diff, base_revision: origin/main, head_revision: HEAD, output_root: /tmp/omp-security-review }8.3 验证一条 finding{ action: validate, scan_id: secscan_id, finding_id: secfinding_id, validation_status: validated, validation_summary: Reproduced with an untrusted archive entry., validation_evidence: [ {label:Reproduction,explanation:The entry writes outside the extraction root.} ] }8.4 显式启动并导入云扫描{ action: cloud_start, repository_id: repo_id, repository_url: https://github.com/owner/repo, environment_id: env_id, lookback_days: 30, credential_id: 7 }{action:cloud_pull,cloud_configuration_id:scan_id,credential_id:7}九、错误与约束汇总每个动作首先复查security.enabled禁用时直接执行抛出Security is disabled. Enable security.enabled before using security_scan.必填字符串会 trim 并拒绝空白值ArkType 拒绝非法枚举值、非正整数credential_id/lookback_days、畸形验证证据原生扫描拒绝缺少 Git 上下文、未知 ref、越界/不存在的 scope 路径、无效知识库文件、不安全输出目录、未知/过期计划、钉死的模型不可用、OAuth 身份变化、钉死凭据不可用云请求遇到 HTTP 401 时强制刷新重试一次仍失败则失败其他非成功响应报告状态码与端点CodexSecurityCloudHttpErrorcloud_pull导入前校验仓库身份与配置归属含按configured_scan_id的二次归属复核取消是协作式的仅当后台运行处理 abort 并持久化终态 bundle 后操作才到达终结态cancelled。十、源码地图深入阅读路线工具入口与参数 schemapackages/coding-agent/src/tools/security-scan.ts模型提示词packages/coding-agent/src/prompts/tools/security-scan.md计划生成、路径规范化与指纹计算packages/coding-agent/src/security/preflight.ts后台执行、受限会话与阶段机packages/coding-agent/src/security/coordinator.ts发布工具security_publishpackages/coding-agent/src/security/publication.ts规范存储与原子写入packages/coding-agent/src/security/store.tsCodex Security 云客户端与导入映射packages/coding-agent/src/security/cloud.ts凭据选择与身份固定packages/coding-agent/src/security/auth.tssecurity://只读资源协议packages/coding-agent/src/internal-urls/security-protocol.ts开关默认值与 UI 定义packages/coding-agent/src/config/settings-schema.ts启用门控测试packages/coding-agent/test/security/gate.test.ts从这些实现可以看到oh-my-pi 的security_scan并非简单的“扫描命令”而是一套把不可变快照、精确凭据、受限最小化执行环境、原子持久化与可审计验证组合在一起的工程化安全审查管线preflight负责把所有可变输入钉死成指纹start在执行前二次校验新鲜度security_publish把结果以诚实覆盖声明写入 0700/0600 加固的规范目录最终通过只读的security://供检索与验证。对于需要在 IDE 工作流内反复执行、复核并沉淀安全审查结果的使用场景这一套“计划—执行—发布—验证”的闭环即是其可以直接借鉴的用法。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考