日本語

Codex Security TypeScript SDK

TypeScript から Codex Security スキャンを実行し、対象とプロバイダーを選択して結果を確認し、スキャンのライフサイクルを管理します。

Codex Security TypeScript SDK を使用すると、アプリケーションや開発者向けツールから リポジトリやコード変更に対するセキュリティスキャンを実行できます。SDK は、型付けされた 検出結果、カバレッジの詳細、スキャンアーティファクトへのパスを返します。長時間のスキャン向けに、 事前チェック、コスト制限、進行状況コールバック、キャンセルもサポートしています。

SDK は ECMAScript modules (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_KEY または CODEX_API_KEY を設定するか、 既存のファイルベースの Codex サインインを使用するか、別の プロバイダーを設定します。Amazon Bedrock は AWS の 認証情報を使用します。OpenRouter と Fireworks は、プロバイダー固有の API key と 設定を使用します。

最良の結果を得るには、Trusted Access for Cyber の確認済みアカウントを使用してください。サインインまたは API key の指定だけでは、 Trusted Access は付与されません。

スキャンを実行する

信頼でき、評価する権限があるリポジトリのみをスキャンしてください。SDK は ローカル OS の権限で動作し、承認のために一時停止することはありません。 スキャンプロセスは環境を継承できるため、開始前に無関係な認証情報を 削除してください。ローカルスキャンの 権限を参照してください。

CodexSecurity クライアントを 1 つ作成し、標準のリポジトリスキャンを実行して、 処理が完了したらクライアントを閉じます。対象の Git worktree の外部にある非公開の 結果ディレクトリを選択するには、outputDir を渡します。

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 はスキャンを開始し、完了を待機して封印済みのアーティファクトを検証し、 ScanResult を返します。close は分離されたランタイムを解放し、 繰り返し呼び出すことができます。

事前チェックで入力を確認する

スキャンを開始する前に、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 は、リポジトリ、パス、commit 済みの差分、working tree を対象としてサポートします。 デフォルトの対象はリポジトリ全体です。

選択したパスをスキャンする

リポジトリ内のパスを配列として渡します。

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

パスにはファイルまたはディレクトリを指定できます。SDK は各パスをリポジトリ内で解決し、 重複を削除します。

commit 済みの変更をスキャンする

ローカルで利用できる 2 つの Git リビジョン間の commit 済み変更をスキャンするには、 DiffTarget.refs を使用します。



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

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

head のデフォルトは HEAD です。差分を対象とする場合は、リポジトリ引数に Git worktree のルートを指定する必要があります。

working tree をスキャンする

base リビジョンを基準に、staged および unstaged の変更をスキャンするには、 DiffTarget.workingTree を使用します。

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

base のデフォルトは HEAD です。差分または working tree のスキャンを開始する前に、 選択したリビジョンを取得してください。

deep モードを選択する

より広範なレビューが必要なリポジトリまたはパスのスキャンでは、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,
});

deep モードはリポジトリとパスを対象としてサポートします。差分および working tree のスキャンでは standard モードを使用してください。オプション設定では、同時に実行する独立した standard スキャンワーカー数、ワーカーごとのサブエージェント数、新しい検出結果がない状態で 連続して完了できるワーカースキャン数、ワーカー実行の合計回数と実行時間を制御します。これらには 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 が完了済みのワーカー結果を 集約した後に deep スキャンが上限に達した場合、runcoverage.completeness"partial" に設定された結果を返し、 onWarning を通じて予算に関する警告を報告します。

スキャンで完了済みの部分結果を生成できない場合、runScanCostLimitExceededError を throw し、利用可能な出力を保持します。

スキャン結果を操作する

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() は、マニフェスト、リポジトリおよび現在のスキャンの検出結果、 カバレッジ、スキャンとスレッドの識別子、reportPathartifactsDirsarifPath、コスト、ターンメタデータを、JSON に変換できる 1 つのオブジェクトとして返します。

スキャンを追跡またはキャンセルする

スキャンの開始、ワーカーの進行状況、接続の再試行を報告するには、 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 設定にマージします。スキャンでは、デフォルトで extra-high の推論 effort を指定した gpt-5.6-sol を使用します。別のモデルまたは推論 effort を使用するには、codexOverridesmodelmodel_reasoning_effort を設定します。Amazon Bedrock を使用するには、 codexOverridesmodel_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 に変更し、nameFireworks AI に、env_keyFIREWORKS_API_KEY に設定します。また、 https://api.fireworks.ai/inference/v1base_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",
});

環境変数の API key を必須にするには、auth: "api-key" を設定します。preflight は 同じ auth オプションを受け付けます。

スキャンエラーを処理する

アプリケーションで実行可能な対応に合った、エクスポート済みのエラークラスを catch します。

エラー 意味
AuthenticationRequiredError スキャンにサポート対象の認証情報が必要です。
ConfigurationError Codex 設定またはオーバーライドが適切ではありません。
InvalidTargetError リポジトリ、パス、モード、または Git の対象が適切ではありません。
OutputDirectoryError 出力先またはその権限が適切ではありません。
OutputInsideProtectedRootError 出力ディレクトリがスキャン対象のリポジトリまたは worktree 内にあります。
PluginPythonUnavailableError 使用可能な Python インタープリターがありません。
PluginBootstrapError プラグインランタイムを起動できませんでした。
ScanCostLimitExceededError スキャンが推定コスト上限を超えました。
IncompleteScanError 必要な結果を生成する前にスキャンが終了しました。
ContractValidationError 完了したスキャンが構造化契約エラーを返しました。
ScanInterruptedError 中断によってスキャンが停止し、部分的な出力が残っている可能性があります。

続いて、CLI クイックスタートCI ガイド、または CLI リファレンスを参照してください。