中文

Codex Security TypeScript SDK

从 TypeScript 运行 Codex Security 扫描,选择目标和提供商,检查结果并管理扫描生命周期。

使用 Codex Security TypeScript SDK,可从你的应用程序或开发者工具中对仓库和 代码更改运行安全扫描。SDK 会返回类型化的 发现、覆盖范围详情和扫描工件路径。对于耗时较长的扫描,它 支持预检、成本限制、进度回调和取消操作。

SDK 使用 ECMAScript 模块(ESM),在 Node.js 22 (22.13.0 或更高版本)、24 或 26 的服务端环境中运行。扫描还需要 Python 3.10 或更高版本。 Python 3.10 还需要 tomli 软件包。

设置 SDK

安装 SDK:

npm install @openai/codex-security

开始扫描前,请设置 OPENAI_API_KEYCODEX_API_KEY、使用 现有的文件型 Codex 登录信息,或配置其他 提供商。Amazon Bedrock 使用 AWS 凭据;OpenRouter 和 Fireworks 使用提供商专用的 API key 和 配置。

为获得最佳结果,请使用已通过 Trusted Access for Cyber 验证的账户。登录或提供 API key 并不会 授予 Trusted Access。

运行扫描

仅扫描你信任且有权评估的仓库。SDK 使用 本地操作系统权限运行,且绝不会暂停以等待批准。 扫描进程可能继承你的环境,因此请在开始前移除无关凭据。请参阅本地扫描 权限

创建一个 CodexSecurity 客户端,运行标准仓库扫描,并在 工作完成后关闭客户端。传入 outputDir,以选择位于外围 Git 工作树 之外的私有结果目录。

如果省略 outputDir,Codex Security 会将结果保存在其自身的持久化 状态目录中。结果可能包含源代码摘录和漏洞 详情,因此请选择适当的权限和保留策略。



const security = new CodexSecurity();

try {
  const result = await security.run("/path/to/repository", {
    outputDir: "/path/outside/repository/results",
  });

  console.log(result.reportPath);
  console.log(result.coverage.completeness);
  console.log(result.findings.findings.length);
} finally {
  await security.close();
}

run 会启动扫描、等待扫描完成、验证已封存的工件, 并返回 ScanResultclose 会释放隔离的运行时,并支持 重复调用。

使用预检检查输入

使用 preflight 可在开始扫描前检查仓库、目标、模式、知识库文档、 输出位置和 Codex 配置:

const plan = await security.preflight("/path/to/repository", {
  target: ["services/billing", "packages/auth"],
  knowledgeBasePaths: ["/path/to/architecture.md"],
  outputDir: "/path/outside/repository/results",
});

console.log(plan.repository);
console.log(plan.target.kind);
console.log(plan.mode);
console.log(plan.outputDir);

预检不会改动 Codex 运行时和凭据。它还会将 插件和 Python 的发现留到扫描本身执行。因此,预检适合 在运行耗时较长或需要凭据的操作前检查用户输入。

若要预览现有结果目录的归档操作,请设置 archiveExisting: true

const plan = await security.preflight("/path/to/repository", {
  outputDir: "/path/outside/repository/results",
  archiveExisting: true,
});

console.log(plan.archiveDir);

返回的 archiveDir 会预览归档名称。最终路径可能 不同,因为 run 会生成自己的唯一目标位置。使用 onOutputArchived 获取实际归档路径:

await security.run("/path/to/repository", {
  outputDir: "/path/outside/repository/results",
  archiveExisting: true,
  onOutputArchived(archiveDir) {
    console.log("Archived results:", archiveDir);
  },
});

扫描会归档先前的结果,并从空的输出 目录开始。

选择扫描目标

SDK 支持仓库、路径、已提交差异和工作树目标。 默认目标是完整仓库。

扫描选定路径

传入仓库内的路径数组:

const result = await security.run("/path/to/repository", {
  target: ["services/billing", "packages/auth"],
});

路径可以指向文件或目录。SDK 会解析仓库内的每条路径并 移除重复项。

扫描已提交的更改

使用 DiffTarget.refs 扫描两个本地可用 Git 修订版本之间已提交的更改:



const target = DiffTarget.refs({
  base: "origin/main",
  head: "HEAD",
});

const result = await security.run("/path/to/repository", { target });

头部默认为 HEAD。差异目标要求仓库参数 为 Git 工作树根目录。

扫描工作树

使用 DiffTarget.workingTree 扫描相对于基准 修订版本的暂存和未暂存更改:

const target = DiffTarget.workingTree({ base: "HEAD" });
const result = await security.run("/path/to/repository", { target });

基准默认为 HEAD。开始差异或工作树扫描前,请获取选定的修订版本。

选择深度模式

对于需要更广泛审查的仓库或路径扫描,请设置 mode: "deep"

const result = await security.run("/path/to/repository", {
  target: ["services/billing"],
  mode: "deep",
  workers: 2,
  subagents: 0,
  stopAfterNoNew: 3,
  maxDiscoveryRuns: 10,
  maxTimeHours: 1.5,
});

深度模式支持仓库和路径目标。差异和 工作树扫描请使用标准模式。可选设置用于控制并发的独立 标准扫描工作进程、每个工作进程的子智能体数量、连续完成但 没有新发现的工作进程扫描次数,以及工作进程运行的总次数和时长。这些设置 需要 mode: "deep"

maxTimeHours 默认为 96,可接受不超过 96 的正数, 包括小数小时。到达截止时间时,Codex Security 会停止未完成的 工作进程,保留已完成的扫描结果,并将其汇总到最终 报告中。在将限时扫描视为完整覆盖范围的证据前,请审查 result.coverage.completeness

添加安全知识库

通过 knowledgeBasePaths 传入架构文档、威胁模型或安全策略:

const result = await security.run("/path/to/repository", {
  knowledgeBasePaths: [
    "/path/to/architecture.md",
    "/path/to/security-policies",
  ],
});

SDK 接受文件或目录,并会递归搜索目录。 支持的文档格式为 .md.markdown.txt.pdf.docx。 SDK 会拒绝链接形式的输入路径、跳过链接形式的目录条目,并将 提取的文档内容保存在扫描结果之外。

添加扫描和后续指令

使用 scanPrompt 聚焦扫描,并使用 postScanPrompt 请求后续操作:

const result = await security.run("/path/to/repository", {
  scanPrompt: "Focus on tenant isolation and authorization checks.",
  postScanPrompt: "Write confirmed findings to post-scan-summary.md.",
});

如果后续操作失败,SDK 会保留已完成的扫描,并通过 onWarning 报告错误。它还会恢复被后续操作更改的所有已完成扫描工件。

设置扫描预算

设置 maxCostUsd,在扫描的估算模型成本超过限制时停止扫描。 使用 onCost 可在扫描运行期间跟踪成本:

const result = await security.run("/path/to/repository", {
  maxCostUsd: 5,
  onCost(cost) {
    console.log(cost.estimatedUsd);
  },
});

console.log(result.cost?.estimatedUsd);

该限制用于估算支出,但不是严格上限,因此已在进行中的 请求可能会在略微超出限制后完成。如果深度扫描在 Codex Security 汇总已完成的工作进程结果后达到限制,run 会返回一个 结果,其中 coverage.completeness 被设置为 "partial",并通过 onWarning 报告预算警告。

如果扫描无法生成已完成的部分结果,run 会抛出 ScanCostLimitExceededError 并保留所有可用输出。

使用扫描结果

ScanResult 会提供结构化文档、扫描元数据和工件 路径:

属性 内容
manifest 已封存的扫描清单,包括目标、作用域、生成方和工件记录。
findings 当前扫描的发现。从 findings.findings 读取发现对象。
repositoryFindings 当扫描历史记录可用时,仓库各次扫描中尚未解决的发现。
coverage 已审查区域、排除项、推迟处理的工作、未决问题和完整性。
scanDir 扫描目录。
threadId 扫描的 Codex 线程标识符。
turnResult 轮次状态、响应和可用的用量元数据。
cost 估算的模型和令牌成本;不可用时为 null
reportPath report.md 的路径。
manifestPath scan-manifest.json 的路径。
findingsPath findings.json 的路径。
coveragePath coverage.json 的路径。
artifactsDir 支持工件目录。
sarifPath 生成的 SARIF 路径;没有 SARIF 时为 null
pluginVersion 扫描生成方记录的版本。

若要要求后续扫描使用相同插件,请传入 expectedPluginVersion: result.pluginVersion。如果 已安装的插件版本不同,SDK 会拒绝扫描。

直接使用结构化发现和覆盖范围:

for (const finding of result.findings.findings) {
  const location = finding.locations[0];
  if (location === undefined) continue;

  console.log(
    finding.severity.level,
    `${location.path}:${location.startLine}`,
    finding.title
  );
}

for (const deferred of result.coverage.deferred) {
  console.log(deferred.id, deferred.reason);
}

发现可以包含可选的 codeEvidencerootCausevalidationattackPathremediationTestspreventiveControls 字段。

对于仓库范围的发现,confirmedInLatestScan 会区分 最新扫描中发现的问题与先前扫描中仍未解决的问题:

for (const finding of result.repositoryFindings ?? []) {
  console.log(finding.title, finding.confirmedInLatestScan);
}

覆盖完整性为 completepartialunknown。在将扫描用作 安全决策的证据前,请审查推迟处理的区域、排除项和未决问题。

result.toJSON() 会在一个可直接转换为 JSON 的对象中返回清单、仓库和当前扫描的发现、 覆盖范围、扫描和线程标识符、reportPathartifactsDirsarifPath、成本以及轮次元数据。

跟踪或取消扫描

传入 ScanOptions 回调,以报告扫描启动、工作进程进度和 连接重试:

const result = await security.run("/path/to/repository", {
  outputDir: "/path/outside/repository/results",
  onScanStarted() {
    console.log("Scan started");
  },
  onProgress(progress) {
    console.log(progress.phase, progress.filesCompleted, progress.filesTotal);
  },
  onWorkerStatus(status) {
    console.log(status.kind, status);
  },
  onSessionEvent(session) {
    console.log(session.threadId, session.worker, session.event["type"]);
  },
  onReconnect(attempt, maxAttempts) {
    console.log(`Reconnect attempt ${attempt} of ${maxAttempts}`);
  },
  onObserverError(observer, error) {
    console.error(`${observer} failed`, error);
  },
});

console.log(result.reportPath);

当取消请求来自请求、作业控制器或超时时,请传入 AbortSignal



const controller = new AbortController();

try {
  const scan = security.run("/path/to/repository", {
    outputDir: "/path/outside/repository/results",
    signal: controller.signal,
  });

  controller.abort();
  await scan;
} catch (error) {
  if (error instanceof ScanInterruptedError) {
    console.error(error.scanDir);
  } else {
    throw error;
  }
}

中断的扫描可能会在 scanDir 中留下部分输出。当需要调查 结果时,请保留该目录。

显示扫描设置进度的应用程序还可以使用 ScanOptions 生命周期回调:

回调 调用时机
onAuthentication(authentication) 扫描选择身份验证方法时。
onOutputArchived(archiveDir) 现有结果移动到归档目录时。
onOutputDirReady(scanDir) 私有扫描目录准备就绪时。
onScanStarted() 扫描设置完成并开始执行时。
onTrustedAccessStatus(status) Trusted Access 状态变为可用时。
onReconnect(attempt, maxAttempts) SDK 重试已断开的扫描流时。
onActivity(activity) 命令、工具、推理步骤或消息更新时。
onProgress(progress) 扫描阶段或已审查文件数发生变化时。
onWorkerStatus(status) 工作进程预检或分派状态发生变化时。
onSessionEvent(session) 扫描或工作进程会话发出事件时。
onCost(cost) 有更新后的扫描成本估算值可用时。
onWarning(warning) 扫描报告警告时。
onObserverError(observer, error) 其他扫描生命周期回调引发错误时。

Trusted Access 状态为 grantednot_grantedunknown。缺失或 未知的访问权限也会触发 onWarning

onSessionEvent 接收未经脱敏的事件,其中可能包含源 代码或凭据。请先过滤这些事件,再将其发送到共享日志或其他 服务。

配置运行时和凭据

当你需要特定插件、解释器或 Codex 设置时,请传入运行时配置:

const security = new CodexSecurity({
  pluginPath: "/path/to/codex-security-plugin",
  pythonPath: "/path/to/python",
  codexOverrides: {
    model: "gpt-5.6-terra",
    model_reasoning_effort: "high",
  },
});

pluginPath 接受插件目录或 ZIP。pythonPath 选择 插件解释器。codexOverrides 会将支持的值合并到隔离的 Codex 配置中。扫描默认使用 gpt-5.6-sol 和超高推理强度。 在 codexOverrides 中设置 modelmodel_reasoning_effort,可使用 其他模型或推理强度。若要使用 Amazon Bedrock,请在 codexOverrides 中设置 model_providermodel

codexOverrides 无法限制扫描的文件系统访问权限或更改其 批准策略。请参阅本地扫描 权限

对于 OpenRouter 或 Fireworks,还需提供相应的 API key,并在 codexOverrides 中提供完整的提供商配置。例如,设置 OPENROUTER_API_KEY 并配置 OpenRouter:

const security = new CodexSecurity({
  codexOverrides: {
    model: "anthropic/claude-sonnet-4.5",
    model_provider: "openrouter",
    model_providers: {
      openrouter: {
        name: "OpenRouter",
        base_url: "https://openrouter.ai/api/v1",
        env_key: "OPENROUTER_API_KEY",
        wire_api: "responses",
      },
    },
  },
});

对于 Fireworks,请将两个 openrouter 键都改为 fireworks,将 name 设置为 Fireworks AI,将 env_key 设置为 FIREWORKS_API_KEY,使用 https://api.fireworks.ai/inference/v1 作为 base_url,并选择一个 Fireworks 模型。

客户端还提供受支持的身份验证方法:

方法 用途
loginApiKey(apiKey) 使用 API key 对隔离的运行时进行身份验证。
loginChatGPT() 启动浏览器登录流程并返回登录句柄。
loginChatGPTDeviceCode() 启动设备代码登录流程并返回登录句柄。
account() 返回当前身份验证状态。
logout() 清除隔离环境中的身份验证信息。

登录句柄提供 waitForInstructionsauthUrlverificationUrluserCodewaitcancel,使应用程序能够展示并完成 所选登录流程。SDK 可以复用文件型 Codex 登录信息。API key 非常适合 CI 和服务端自动化。

当 API key 和已存储的登录信息同时可用时,SDK 默认使用 API key。若要改用你的 ChatGPT 登录信息,请为扫描选择该信息:

const result = await security.run("/path/to/repository", {
  auth: "chatgpt",
});

设置 auth: "api-key" 可要求使用环境中的 API key。preflight 接受 相同的 auth 选项。

处理扫描错误

捕获与应用程序可采取操作相对应的导出错误类:

错误 含义
AuthenticationRequiredError 扫描需要受支持的凭据。
ConfigurationError Codex 配置或覆盖值不适用。
InvalidTargetError 仓库、路径、模式或 Git 目标不适用。
OutputDirectoryError 输出位置或其权限不适用。
OutputInsideProtectedRootError 输出目录位于被扫描的仓库或工作树内。
PluginPythonUnavailableError 没有可用的 Python 解释器。
PluginBootstrapError 插件运行时无法启动。
ScanCostLimitExceededError 扫描超出其估算成本限制。
IncompleteScanError 扫描在生成所需结果前结束。
ContractValidationError 已完成的扫描返回了结构化契约错误。
ScanInterruptedError 中断停止了扫描,并且可能留下部分输出。

接下来可参阅 CLI 快速入门CI 指南CLI 参考