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 スキャンが上限に達した場合、run は
coverage.completeness が "partial" に設定された結果を返し、
onWarning を通じて予算に関する警告を報告します。
スキャンで完了済みの部分結果を生成できない場合、run は
ScanCostLimitExceededError を 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);
}検出結果には、オプションの codeEvidence、rootCause、validation、
attackPath、remediationTests、preventiveControls フィールドが含まれる場合があります。
リポジトリ全体の検出結果では、confirmedInLatestScan によって、
最新のスキャンで検出されたものと、以前から未解決のまま残っているものを区別できます。
for (const finding of result.repositoryFindings ?? []) {
console.log(finding.title, finding.confirmedInLatestScan);
}カバレッジの完全性は、complete、partial、unknown のいずれかです。スキャンを
セキュリティ判断の証拠として使用する前に、保留領域、除外項目、未解決の質問を確認してください。
result.toJSON() は、マニフェスト、リポジトリおよび現在のスキャンの検出結果、
カバレッジ、スキャンとスレッドの識別子、reportPath、artifactsDir、
sarifPath、コスト、ターンメタデータを、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 のステータスは、granted、not_granted、unknown のいずれかです。アクセスがない場合や
不明な場合にも、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 を使用するには、codexOverrides で
model と model_reasoning_effort を設定します。Amazon
Bedrock を使用するには、
codexOverrides で model_provider と model を設定します。
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() |
分離された認証をクリアします。 |
ログインハンドルは waitForInstructions、authUrl、verificationUrl、
userCode、wait、cancel を提供するため、アプリケーションで選択した
サインインフローを表示し、完了できます。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 リファレンスを参照してください。