Codex Security TypeScript SDK

Jalankan pemindaian Codex Security dari TypeScript, pilih target dan penyedia, periksa hasil, dan kelola siklus hidup pemindaian.

Gunakan Codex Security TypeScript SDK untuk menjalankan pemindaian keamanan pada repositori dan perubahan kode dari aplikasi atau alat pengembang Anda. SDK mengembalikan temuan bertipe, detail cakupan, dan path menuju artefak pemindaian. Untuk pemindaian yang lebih lama, SDK mendukung pemeriksaan preflight, batas biaya, callback progres, dan pembatalan.

SDK menggunakan modul ECMAScript (ESM) dan berjalan di sisi server dengan Node.js 24 atau 26, atau Node.js 22 mulai dari 22.13.0. Pemindaian juga memerlukan Python 3.10 atau yang lebih baru. Python 3.10 juga memerlukan paket tomli.

Menyiapkan SDK

Instal SDK:

npm install @openai/codex-security

Sebelum memulai pemindaian, tetapkan OPENAI_API_KEY atau CODEX_API_KEY, gunakan login Codex berbasis file yang sudah ada, atau konfigurasikan penyedia lain. Amazon Bedrock menggunakan kredensial AWS; OpenRouter dan Fireworks menggunakan API key serta konfigurasi khusus penyedia.

Untuk hasil terbaik, gunakan akun yang telah diverifikasi untuk Trusted Access for Cyber. Masuk atau memberikan API key tidak memberikan Trusted Access.

Menjalankan pemindaian

SDK berjalan dengan izin sistem operasi lokal Anda dan tidak berhenti untuk meminta persetujuan. Proses pemindaian dapat mewarisi lingkungan Anda, jadi hapus kredensial yang tidak terkait sebelum memulai. Lihat Izin pemindaian lokal.

Simpan contoh ini sebagai scan.mjs. Ganti path, jalankan pemindaian repositori standar, dan tutup klien setelah pekerjaan selesai. Berikan outputDir untuk memilih direktori hasil privat di luar worktree Git yang menaunginya.

Jika Anda tidak menyertakan outputDir, Codex Security menyimpan hasil di direktori status persistennya sendiri. Hasil dapat mencakup cuplikan kode sumber dan detail kerentanan. Tentukan siapa yang dapat membacanya dan berapa lama hasil disimpan.



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.manifest.scan.status);
  console.log(result.findings.findings.length);
} finally {
  await security.close();
}

Jalankan dengan Node.js:

node scan.mjs

Contoh ini mencetak path laporan, status pemindaian, dan jumlah temuan. Buka laporan untuk meninjau buktinya. Jumlah temuan bervariasi menurut repositori dan pemindaian, jadi jangan gunakan jumlah yang diharapkan untuk memeriksa apakah integrasi berfungsi.

run memvalidasi artefak yang tersimpan dan mengembalikan ScanResult ketika result.manifest.scan.status bernilai "completed". Periksa result.coverage untuk mengetahui area yang ditinjau, pengecualian, dan pekerjaan yang ditunda. Pemindaian yang selesai masih dapat memiliki kesenjangan cakupan. Kegagalan runtime, input, atau integritas hasil dapat memicu error.

Dalam contoh berikutnya, gunakan kembali klien security yang masih terbuka dan pertahankan close() di dalam finally untuk melepaskan runtime. Tambahkan impor tambahan di bagian atas scan.mjs.

Memeriksa input dengan preflight

Gunakan preflight untuk memeriksa repositori, target, mode, dokumen basis pengetahuan, lokasi output, dan konfigurasi Codex sebelum memulai pemindaian:

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);

Preflight memeriksa input lokal tanpa memulai Codex, memuat kredensial, atau memeriksa ketersediaan Python dan plugin. Preflight yang berhasil tidak membuktikan bahwa pemindaian dapat melakukan autentikasi atau dimulai.

Untuk melihat pratinjau pengarsipan bagi direktori hasil yang sudah ada, tetapkan archiveExisting: true:

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

console.log(plan.archiveDir);

archiveDir yang dikembalikan menampilkan pratinjau penamaan arsip. Path akhir dapat berbeda karena run menghasilkan tujuannya sendiri yang unik. Rekam path arsip aktual dengan onOutputArchived:

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

Pemindaian mengarsipkan hasil sebelumnya dan memulai dengan direktori output kosong.

Memilih target pemindaian

SDK mendukung target repositori, path, diff yang telah di-commit, dan working tree. Target default adalah seluruh repositori.

Memindai path yang dipilih

Teruskan array path di dalam repositori:

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

Path dapat mengidentifikasi file atau direktori. SDK me-resolve setiap path di dalam repositori dan menghapus duplikat.

Memindai perubahan yang telah di-commit

Gunakan DiffTarget.refs untuk memindai perubahan yang telah di-commit di antara dua revisi Git yang tersedia secara lokal:



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

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

Head secara default adalah HEAD. Target diff mengharuskan argumen repositori berupa root worktree Git.

Memindai working tree

Gunakan DiffTarget.workingTree untuk memindai perubahan staged dan unstaged terhadap revisi base:

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

Base secara default adalah HEAD. Ambil revisi yang dipilih sebelum memulai pemindaian diff atau working tree.

Memilih mode mendalam

Tetapkan mode: "deep" untuk pemindaian repositori atau path yang memerlukan peninjauan lebih luas:

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 mendalam mendukung target repositori dan path. Gunakan mode standar untuk pemindaian diff dan working tree. Pengaturan opsional mengontrol worker pemindaian standar independen yang berjalan bersamaan, subagen per worker, jumlah pemindaian worker selesai berturut-turut tanpa temuan baru, serta jumlah total dan durasi proses worker. Pengaturan tersebut memerlukan mode: "deep".

maxTimeHours memiliki nilai default 96 dan menerima angka positif hingga 96, termasuk pecahan jam. Saat batas waktu tercapai, Codex Security menghentikan worker yang belum selesai, mempertahankan hasil pemindaian yang telah selesai, dan menggabungkannya ke dalam laporan akhir. Tinjau result.coverage untuk mengetahui pekerjaan yang ditunda dan pertanyaan yang belum terjawab.

Menambahkan basis pengetahuan keamanan

Teruskan dokumen arsitektur, model ancaman, atau kebijakan keamanan melalui knowledgeBasePaths:

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

SDK menerima file atau direktori dan menelusuri direktori secara rekursif. Format dokumen yang didukung adalah .md, .markdown, .txt, .pdf, dan .docx. SDK menolak path input tertaut, melewati entri direktori tertaut, dan menyimpan konten dokumen yang diekstrak di luar hasil pemindaian tersimpan.

Menambahkan instruksi pemindaian dan tindak lanjut

Gunakan scanPrompt untuk memfokuskan pemindaian dan postScanPrompt untuk meminta tindak lanjut:

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.",
});

Jika tindak lanjut gagal, SDK mempertahankan pemindaian yang telah selesai dan melaporkan kesalahan melalui onWarning. SDK memulihkan setiap artefak pemindaian selesai yang diubah oleh tindak lanjut.

Menetapkan anggaran pemindaian

Tetapkan maxCostUsd untuk menghentikan pemindaian ketika perkiraan biaya modelnya melampaui batas. Gunakan onCost untuk melacak biaya selama pemindaian berjalan:

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

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

Batas ini memperkirakan pengeluaran tetapi bukan batas mutlak, sehingga permintaan yang sudah berjalan dapat selesai dengan biaya yang sedikit melampauinya. Jika pemindaian mendalam mencapai batas setelah Codex Security menggabungkan hasil worker yang telah selesai, run dapat mengembalikan hasil dengan manifest.scan.status diatur ke "completed" dan melaporkan peringatan anggaran melalui onWarning. Periksa result.coverage untuk mengetahui pekerjaan yang belum selesai.

Jika pemindaian tidak dapat menghasilkan hasil selesai yang valid, run memicu ScanCostLimitExceededError dan mempertahankan semua keluaran yang tersedia.

Menggunakan hasil pemindaian

ScanResult mengekspos dokumen terstruktur, metadata pemindaian, dan path artefak:

Properti Isi
manifest Manifes pemindaian yang telah disegel, termasuk target, cakupan, pembuat, dan catatan artefak.
findings Temuan dari pemindaian saat ini. Baca objek temuan dari findings.findings.
repositoryFindings Temuan terbuka dari berbagai pemindaian repositori, jika riwayat pemindaian tersedia.
coverage Area yang ditinjau, pengecualian, pekerjaan yang ditunda, dan pertanyaan yang belum terjawab.
scanDir Direktori pemindaian.
threadId Pengidentifikasi thread Codex untuk pemindaian.
turnResult Status giliran, respons, dan metadata penggunaan yang tersedia.
cost Estimasi biaya model dan token, atau null jika tidak tersedia.
reportPath Path ke report.md.
manifestPath Path ke scan-manifest.json.
findingsPath Path ke findings.json.
coveragePath Path ke coverage.json.
artifactsDir Direktori artefak pendukung.
sarifPath Path SARIF yang dihasilkan, atau null jika SARIF tidak ada.
pluginVersion Versi yang dicatat oleh pembuat pemindaian.

Untuk mewajibkan plugin yang sama bagi pemindaian berikutnya, teruskan expectedPluginVersion: result.pluginVersion. SDK menolak pemindaian jika versi plugin yang terinstal berbeda.

Gunakan temuan terstruktur dan cakupan secara langsung:

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);
}

Temuan dapat menyertakan bidang opsional codeEvidence, rootCause, validation, attackPath, remediationTests, dan preventiveControls.

Untuk temuan di seluruh repositori, confirmedInLatestScan membedakan temuan yang terlihat dalam pemindaian terbaru dari temuan sebelumnya yang masih terbuka:

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

Hasil baru tidak menyertakan coverage.completeness. Gunakan manifest.scan.status untuk mengetahui status eksekusi, serta tinjau area yang ditunda, pengecualian, dan pertanyaan yang belum terjawab di coverage untuk memahami apa yang ditinjau oleh pemindaian.

result.toJSON() mengembalikan manifes, temuan repositori dan pemindaian saat ini, cakupan, pengidentifikasi pemindaian dan thread, reportPath, artifactsDir, sarifPath, biaya, serta metadata giliran dalam satu objek yang siap untuk JSON.

Melacak atau membatalkan pemindaian

Teruskan callback ScanOptions untuk melaporkan dimulainya pemindaian, progres worker, dan percobaan ulang koneksi:

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);

Berikan AbortSignal dari pengontrol permintaan atau tugas Anda untuk membatalkan pemindaian. Jika pemindaian masih berjalan setelah 30 menit, contoh ini menghentikannya dan mencetak direktori yang berisi keluaran yang telah disimpan:



try {
  await security.run("/path/to/repository", {
    outputDir: "/path/outside/repository/results",
    signal: AbortSignal.timeout(30 * 60 * 1000),
  });
} catch (error) {
  if (error instanceof ScanInterruptedError) {
    console.error(error.scanDir);
  } else {
    throw error;
  }
}

Pemindaian yang diinterupsi dapat meninggalkan output parsial di scanDir. Pertahankan direktori tersebut jika hasilnya perlu diselidiki.

Aplikasi yang menampilkan progres penyiapan pemindaian juga dapat menggunakan callback siklus hidup ScanOptions:

Callback Dipanggil ketika
onAuthentication(authentication) Pemindaian memilih metode autentikasinya.
onOutputArchived(archiveDir) Hasil yang sudah ada dipindahkan ke direktori arsip.
onOutputDirReady(scanDir) Direktori pemindaian privat siap digunakan.
onScanStarted() Penyiapan pemindaian selesai dan eksekusi dimulai.
onTrustedAccessStatus(status) Status Trusted Access tersedia.
onReconnect(attempt, maxAttempts) SDK mencoba kembali aliran pemindaian yang terputus.
onActivity(activity) Perintah, alat, langkah penalaran, atau pesan diperbarui.
onProgress(progress) Fase pemindaian atau jumlah file yang ditinjau berubah.
onWorkerStatus(status) Status preflight atau dispatch worker berubah.
onSessionEvent(session) Sesi pemindaian atau worker menghasilkan peristiwa.
onCost(cost) Perkiraan biaya pemindaian terbaru tersedia.
onWarning(warning) Pemindaian melaporkan peringatan.
onObserverError(observer, error) Callback siklus hidup pemindaian lain memunculkan kesalahan.

Status Trusted Access adalah granted, not_granted, atau unknown. Akses yang tidak ada atau tidak diketahui juga memicu onWarning.

onSessionEvent menerima peristiwa yang tidak disamarkan dan dapat berisi kode sumber atau kredensial. Filter peristiwa tersebut sebelum mengirimkannya ke log bersama atau layanan lain.

Mengonfigurasi runtime dan kredensial

Berikan konfigurasi runtime saat Anda memerlukan plugin, interpreter, atau pengaturan Codex tertentu. Pilih model yang dapat diakses dengan kredensial Anda. Jika Anda masuk melalui ChatGPT, periksa ketersediaan GPT-6.1 Sol sebelum menggunakan contoh ini:

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

pluginPath menerima direktori plugin atau ZIP. pythonPath memilih interpreter plugin. codexOverrides menggabungkan nilai yang didukung ke dalam konfigurasi Codex terisolasi. Secara default, pemindaian menggunakan gpt-5.6-sol dengan upaya penalaran extra-high. Tetapkan model dan model_reasoning_effort dalam codexOverrides untuk menggunakan model atau upaya penalaran yang berbeda. Untuk menggunakan Amazon Bedrock, tetapkan model_provider dan model dalam codexOverrides.

codexOverrides tidak dapat membatasi akses sistem file pemindaian atau mengubah kebijakan persetujuannya. Lihat Izin pemindaian lokal.

Untuk OpenRouter atau Fireworks, berikan juga API key yang sesuai dan konfigurasi penyedia lengkap dalam codexOverrides. Misalnya, tetapkan OPENROUTER_API_KEY dan konfigurasikan 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",
      },
    },
  },
});

Untuk Fireworks, ubah kedua key openrouter menjadi fireworks, tetapkan name ke Fireworks AI, tetapkan env_key ke FIREWORKS_API_KEY, gunakan https://api.fireworks.ai/inference/v1 sebagai base_url, dan pilih model Fireworks.

Klien juga mengekspos metode autentikasi yang didukung:

Metode Tujuan
loginApiKey(apiKey) Mengautentikasi runtime terisolasi dengan API key.
loginChatGPT() Memulai alur login browser dan mengembalikan handle login.
loginChatGPTDeviceCode() Memulai alur login kode perangkat dan mengembalikan handle login.
account() Mengembalikan status autentikasi saat ini.
logout() Menghapus autentikasi terisolasi.

Handle login menyediakan waitForInstructions, authUrl, verificationUrl, userCode, wait, dan cancel agar aplikasi dapat menampilkan dan menyelesaikan alur masuk yang dipilih. SDK dapat menggunakan kembali sesi masuk Codex yang tersimpan dalam file. Gunakan API key untuk CI dan otomatisasi sisi server.

Jika API key dan login tersimpan sama-sama tersedia, SDK menggunakan API key secara default. Untuk menggunakan login ChatGPT Anda, pilih login tersebut untuk pemindaian:

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

Tetapkan auth: "api-key" untuk mewajibkan API key dari lingkungan. preflight menerima opsi auth yang sama.

Menangani kesalahan pemindaian

Tangkap kelas kesalahan yang diekspor dan sesuai dengan tindakan yang dapat dilakukan aplikasi Anda:

Kesalahan Arti
AuthenticationRequiredError Pemindaian memerlukan kredensial yang didukung.
ConfigurationError Konfigurasi Codex atau override tidak sesuai.
InvalidTargetError Repositori, path, mode, atau target Git tidak sesuai.
OutputDirectoryError Lokasi output atau izinnya tidak sesuai.
OutputInsideProtectedRootError Direktori output berada di dalam repositori atau worktree yang dipindai.
PluginPythonUnavailableError Interpreter Python yang dapat digunakan tidak tersedia.
PluginBootstrapError Runtime plugin tidak dapat dimulai.
ScanCostLimitExceededError Pemindaian melampaui batas perkiraan biayanya.
IncompleteScanError Pemindaian berakhir sebelum menghasilkan hasil yang diperlukan.
ContractValidationError Pemindaian yang selesai mengembalikan kesalahan kontrak terstruktur.
ScanInterruptedError Interupsi menghentikan pemindaian dan mungkin meninggalkan output parsial.

Lanjutkan dengan panduan mulai cepat CLI, panduan CI, atau referensi CLI.