Codex Security TypeScript SDK

Chạy các lượt quét Codex Security từ TypeScript, chọn mục tiêu và nhà cung cấp, kiểm tra kết quả và quản lý vòng đời quét.

Sử dụng Codex Security TypeScript SDK để chạy quét bảo mật trên các kho lưu trữ và thay đổi mã nguồn từ ứng dụng hoặc công cụ dành cho nhà phát triển của bạn. SDK trả về các phát hiện có kiểu, chi tiết phạm vi bao phủ và đường dẫn tới tệp kết quả quét. Đối với các lượt quét dài hơn, SDK hỗ trợ kiểm tra trước, giới hạn chi phí, callback tiến trình và hủy bỏ.

SDK sử dụng ECMAScript modules (ESM) và chạy phía máy chủ với Node.js 24 hoặc 26, hoặc Node.js 22 từ phiên bản 22.13.0. Việc quét cũng yêu cầu Python 3.10 trở lên. Python 3.10 còn yêu cầu gói tomli.

Thiết lập SDK

Cài đặt SDK:

npm install @openai/codex-security

Trước khi bắt đầu quét, hãy đặt OPENAI_API_KEY hoặc CODEX_API_KEY, sử dụng một phiên đăng nhập Codex hiện có được lưu trong tệp hoặc cấu hình một nhà cung cấp khác. Amazon Bedrock sử dụng thông tin xác thực AWS; OpenRouter và Fireworks sử dụng API key cùng cấu hình riêng của nhà cung cấp.

Để có kết quả tốt nhất, sử dụng tài khoản đã được xác minh cho Trusted Access for Cyber. Việc đăng nhập hoặc cung cấp API key không cấp Trusted Access.

Chạy một lượt quét

SDK chạy với quyền hệ điều hành cục bộ của bạn và không tạm dừng để chờ phê duyệt. Các tiến trình quét có thể kế thừa môi trường của bạn, vì vậy hãy xóa thông tin xác thực không liên quan trước khi bắt đầu. Xem Quyền quét cục bộ.

Lưu ví dụ này thành scan.mjs. Thay các đường dẫn, chạy lượt quét kho mã tiêu chuẩn và đóng client khi công việc hoàn tất. Truyền outputDir để chọn thư mục kết quả riêng tư nằm ngoài cây làm việc Git chứa kho mã.

Nếu bạn bỏ qua outputDir, Codex Security lưu kết quả trong thư mục trạng thái bền vững riêng của nó. Kết quả có thể bao gồm các đoạn mã nguồn và thông tin chi tiết về lỗ hổng. Hãy thiết lập ai có thể đọc chúng và thời gian lưu giữ.



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

Chạy bằng Node.js:

node scan.mjs

Ví dụ này in ra đường dẫn báo cáo, trạng thái quét và số lượng phát hiện. Mở báo cáo để xem xét bằng chứng. Số lượng thay đổi tùy theo kho mã và lượt quét, vì vậy đừng dùng một số lượng kỳ vọng để kiểm tra xem việc tích hợp có hoạt động hay không.

run xác thực các tệp kết quả đã lưu và trả về một ScanResult khi result.manifest.scan.status là "completed". Kiểm tra result.coverage để biết các phần đã được rà soát, các phần bị loại trừ và công việc bị hoãn. Lượt quét đã hoàn tất vẫn có thể có khoảng trống trong phạm vi bao phủ. Lỗi thời gian chạy, đầu vào hoặc tính toàn vẹn của kết quả có thể phát sinh lỗi.

Trong các ví dụ sau, tái sử dụng client security đang mở và giữ close() trong finally để giải phóng môi trường thực thi. Thêm mọi câu lệnh import bổ sung ở đầu scan.mjs.

Kiểm tra đầu vào bằng bước kiểm tra trước

Dùng preflight để kiểm tra kho lưu trữ, mục tiêu, chế độ, tài liệu cơ sở tri thức, vị trí đầu ra và cấu hình Codex trước khi bắt đầu quét:

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

Bước kiểm tra trước xác minh đầu vào cục bộ mà không khởi động Codex, tải thông tin xác thực hay kiểm tra tính sẵn có của Python và plugin. Bước kiểm tra trước thành công không chứng minh rằng lượt quét có thể xác thực hoặc bắt đầu.

Để xem trước việc lưu trữ cho một thư mục kết quả hiện có, hãy đặt archiveExisting: true:

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

console.log(plan.archiveDir);

archiveDir được trả về cho biết trước cách đặt tên bản lưu trữ. Đường dẫn cuối cùng có thể khác vì run tự tạo một đích duy nhất. Thu thập đường dẫn bản lưu trữ thực tế bằng onOutputArchived:

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

Lượt quét lưu trữ kết quả trước đó và bắt đầu với một thư mục đầu ra trống.

Chọn mục tiêu quét

SDK hỗ trợ các mục tiêu là kho lưu trữ, đường dẫn, phần thay đổi đã commit và cây làm việc. Mục tiêu mặc định là toàn bộ kho lưu trữ.

Quét các đường dẫn đã chọn

Truyền một mảng đường dẫn bên trong kho lưu trữ:

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

Đường dẫn có thể xác định tệp hoặc thư mục. SDK phân giải từng đường dẫn bên trong kho lưu trữ và loại bỏ mục trùng lặp.

Quét các thay đổi đã commit

Dùng DiffTarget.refs để quét các thay đổi đã commit giữa hai bản sửa đổi Git có sẵn cục bộ:



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

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

Head mặc định là HEAD. Mục tiêu phần thay đổi yêu cầu đối số kho lưu trữ là thư mục gốc của Git worktree.

Quét cây làm việc

Dùng DiffTarget.workingTree để quét các thay đổi đã và chưa đưa vào vùng chờ so với một bản sửa đổi base:

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

Base mặc định là HEAD. Hãy tìm nạp các bản sửa đổi đã chọn trước khi bắt đầu quét phần thay đổi hoặc cây làm việc.

Chọn chế độ quét sâu

Đặt mode: "deep" cho một lượt quét kho lưu trữ hoặc đường dẫn cần xem xét rộng hơn:

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

Chế độ quét sâu hỗ trợ mục tiêu kho lưu trữ và đường dẫn. Hãy dùng chế độ tiêu chuẩn cho lượt quét phần thay đổi và cây làm việc. Các cài đặt tùy chọn kiểm soát số worker quét tiêu chuẩn độc lập chạy đồng thời, số tác nhân phụ trên mỗi worker, số lượt quét worker hoàn tất liên tiếp mà không có phát hiện mới, cũng như tổng số lượng và thời lượng chạy của worker. Chúng yêu cầu mode: "deep".

maxTimeHours có giá trị mặc định là 96 và chấp nhận số dương không vượt quá 96, kể cả số giờ lẻ. Khi hết thời hạn, Codex Security dừng các worker chưa hoàn tất, giữ lại kết quả quét đã hoàn tất và tổng hợp chúng vào báo cáo cuối cùng. Xem result.coverage để biết công việc bị hoãn và các câu hỏi còn bỏ ngỏ.

Thêm cơ sở tri thức bảo mật

Truyền tài liệu kiến trúc, mô hình mối đe dọa hoặc chính sách bảo mật qua knowledgeBasePaths:

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

SDK chấp nhận tệp hoặc thư mục và tìm kiếm đệ quy trong các thư mục. Các định dạng tài liệu được hỗ trợ là .md, .markdown, .txt, .pdf và .docx. SDK từ chối đường dẫn đầu vào là liên kết, bỏ qua các mục thư mục là liên kết và giữ nội dung tài liệu đã trích xuất bên ngoài kết quả quét đã lưu.

Thêm hướng dẫn quét và theo dõi

Dùng scanPrompt để định hướng lượt quét và postScanPrompt để yêu cầu một bước theo dõi:

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

Nếu bước theo dõi thất bại, SDK giữ lại lượt quét đã hoàn tất và báo cáo lỗi qua onWarning. SDK khôi phục mọi tệp kết quả quét đã hoàn tất mà bước theo dõi đã thay đổi.

Đặt ngân sách quét

Đặt maxCostUsd để dừng một lượt quét khi chi phí mô hình ước tính vượt quá giới hạn. Dùng onCost để theo dõi chi phí trong khi lượt quét đang chạy:

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

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

Giới hạn này ước tính chi tiêu nhưng không phải mức trần cứng, vì vậy các yêu cầu đang xử lý có thể hoàn tất với chi phí vượt nhẹ giới hạn. Nếu lượt quét sâu chạm giới hạn sau khi Codex Security tổng hợp kết quả của các worker đã hoàn tất, run có thể trả về kết quả với manifest.scan.status được đặt thành "completed" và thông báo cảnh báo ngân sách qua onWarning. Kiểm tra result.coverage để biết công việc còn chưa hoàn tất.

Nếu lượt quét không thể tạo kết quả hoàn chỉnh hợp lệ, run phát sinh ScanCostLimitExceededError và giữ lại mọi đầu ra hiện có.

Làm việc với kết quả quét

ScanResult cung cấp các tài liệu có cấu trúc, siêu dữ liệu quét và đường dẫn tệp kết quả:

Thuộc tính Nội dung
manifest Bản kê lượt quét đã được niêm phong, bao gồm mục tiêu, phạm vi, bên tạo và các bản ghi tệp kết quả.
findings Các phát hiện từ lượt quét hiện tại. Đọc các đối tượng phát hiện từ findings.findings.
repositoryFindings Các phát hiện chưa đóng qua các lượt quét kho mã, khi có lịch sử quét.
coverage Các phần đã được rà soát, các phần bị loại trừ, công việc bị hoãn và các câu hỏi còn bỏ ngỏ.
scanDir Thư mục quét.
threadId Mã định danh luồng Codex của lượt quét.
turnResult Trạng thái lượt, phản hồi và siêu dữ liệu sử dụng hiện có.
cost Chi phí mô hình và token ước tính, hoặc null khi không có.
reportPath Đường dẫn đến report.md.
manifestPath Đường dẫn đến scan-manifest.json.
findingsPath Đường dẫn đến findings.json.
coveragePath Đường dẫn đến coverage.json.
artifactsDir Thư mục chứa các tệp hỗ trợ.
sarifPath Đường dẫn SARIF được tạo, hoặc null khi không có SARIF.
pluginVersion Phiên bản do bên tạo lượt quét ghi lại.

Để yêu cầu cùng một plugin cho lượt quét sau, hãy truyền expectedPluginVersion: result.pluginVersion. SDK từ chối lượt quét nếu phiên bản plugin đã cài đặt khác đi.

Sử dụng trực tiếp các phát hiện có cấu trúc và dữ liệu phạm vi bao phủ:

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

Các phát hiện có thể bao gồm các trường tùy chọn codeEvidence, rootCause, validation, attackPath, remediationTests và preventiveControls.

Đối với các phát hiện trên toàn kho lưu trữ, confirmedInLatestScan phân biệt các phát hiện được thấy trong lượt quét mới nhất với những phát hiện trước đó vẫn còn mở:

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

Kết quả mới không có coverage.completeness. Sử dụng manifest.scan.status để biết trạng thái thực thi và xem các phần hoãn rà soát, các phần bị loại trừ cùng các câu hỏi còn bỏ ngỏ trong coverage để hiểu lượt quét đã rà soát những gì.

result.toJSON() trả về manifest, các phát hiện của kho lưu trữ và lượt quét hiện tại, phạm vi bao phủ, mã định danh lượt quét và luồng, reportPath, artifactsDir, sarifPath, chi phí và siêu dữ liệu lượt trong một đối tượng sẵn sàng cho JSON.

Theo dõi hoặc hủy một lượt quét

Truyền các callback ScanOptions để báo cáo lúc bắt đầu quét, tiến trình worker và các lần thử kết nối lại:

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

Truyền một AbortSignal từ bộ điều khiển yêu cầu hoặc tác vụ để hủy lượt quét. Nếu lượt quét vẫn chạy sau 30 phút, ví dụ này sẽ ngắt lượt quét và in ra thư mục chứa mọi đầu ra đã lưu:



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

Một lượt quét bị gián đoạn có thể để lại đầu ra một phần trong scanDir. Hãy lưu giữ thư mục đó khi cần điều tra kết quả.

Các ứng dụng hiển thị tiến trình thiết lập quét cũng có thể dùng các callback vòng đời ScanOptions:

Callback Được gọi khi
onAuthentication(authentication) Lượt quét chọn phương thức xác thực.
onOutputArchived(archiveDir) Kết quả hiện có được chuyển vào thư mục lưu trữ.
onOutputDirReady(scanDir) Thư mục quét riêng tư đã sẵn sàng.
onScanStarted() Quá trình thiết lập quét hoàn tất và bắt đầu thực thi.
onTrustedAccessStatus(status) Trạng thái Trusted Access trở nên khả dụng.
onReconnect(attempt, maxAttempts) SDK thử lại một luồng quét đã ngắt kết nối.
onActivity(activity) Một lệnh, công cụ, bước suy luận hoặc thông báo được cập nhật.
onProgress(progress) Giai đoạn quét hoặc số lượng tệp đã xem xét thay đổi.
onWorkerStatus(status) Trạng thái kiểm tra trước hoặc điều phối của worker thay đổi.
onSessionEvent(session) Một phiên quét hoặc worker phát ra sự kiện.
onCost(cost) Có bản ước tính chi phí quét mới.
onWarning(warning) Lượt quét báo cáo cảnh báo.
onObserverError(observer, error) Một callback vòng đời quét khác phát sinh lỗi.

Trạng thái Trusted Access là granted, not_granted hoặc unknown. Quyền truy cập bị thiếu hoặc không xác định cũng kích hoạt onWarning.

onSessionEvent nhận các sự kiện chưa được che thông tin và có thể chứa mã nguồn hoặc thông tin xác thực. Hãy lọc chúng trước khi gửi tới nhật ký dùng chung hoặc dịch vụ khác.

Cấu hình môi trường thực thi và thông tin xác thực

Truyền cấu hình môi trường thực thi khi bạn cần một plugin, trình thông dịch hoặc thiết lập Codex cụ thể. Chọn mô hình mà thông tin xác thực của bạn có thể truy cập. Nếu đăng nhập bằng ChatGPT, hãy kiểm tra tính khả dụng của GPT-6.1 Sol trước khi sử dụng ví dụ này:

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 chấp nhận một thư mục plugin hoặc tệp ZIP. pythonPath chọn trình thông dịch plugin. codexOverrides hợp nhất các giá trị được hỗ trợ vào cấu hình Codex cô lập. Theo mặc định, các lượt quét sử dụng gpt-5.6-sol với mức nỗ lực suy luận rất cao. Đặt model và model_reasoning_effort trong codexOverrides để dùng mô hình hoặc mức nỗ lực suy luận khác. Để dùng Amazon Bedrock, hãy đặt model_provider và model trong codexOverrides.

codexOverrides không thể hạn chế quyền truy cập hệ thống tệp của lượt quét hoặc thay đổi chính sách phê duyệt. Xem Quyền quét cục bộ.

Đối với OpenRouter hoặc Fireworks, hãy cung cấp thêm API key tương ứng và cấu hình nhà cung cấp đầy đủ trong codexOverrides. Ví dụ, đặt OPENROUTER_API_KEY và cấu hình 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",
      },
    },
  },
});

Đối với Fireworks, hãy đổi cả hai khóa openrouter thành fireworks, đặt name thành Fireworks AI, đặt env_key thành FIREWORKS_API_KEY, dùng https://api.fireworks.ai/inference/v1 làm base_url và chọn một mô hình Fireworks.

Client cũng cung cấp các phương thức xác thực được hỗ trợ:

Phương thức Mục đích
loginApiKey(apiKey) Xác thực môi trường thực thi cô lập bằng API key.
loginChatGPT() Bắt đầu luồng đăng nhập trên trình duyệt và trả về một login handle.
loginChatGPTDeviceCode() Bắt đầu luồng đăng nhập bằng mã thiết bị và trả về một login handle.
account() Trả về trạng thái xác thực hiện tại.
logout() Xóa trạng thái xác thực cô lập.

Đối tượng xử lý đăng nhập cung cấp waitForInstructions, authUrl, verificationUrl, userCode, wait và cancel để ứng dụng có thể hiển thị và hoàn tất quy trình đăng nhập đã chọn. SDK có thể tái sử dụng phiên đăng nhập Codex được lưu trong tệp. Sử dụng API key cho CI và tự động hóa phía máy chủ.

Khi có cả API key và phiên đăng nhập đã lưu, SDK mặc định sử dụng API key. Để thay vào đó sử dụng phiên đăng nhập ChatGPT, hãy chọn phiên đó cho lượt quét:

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

Đặt auth: "api-key" để yêu cầu API key từ môi trường. preflight chấp nhận cùng tùy chọn auth.

Xử lý lỗi quét

Bắt lớp lỗi được xuất tương ứng với hành động mà ứng dụng của bạn có thể thực hiện:

Lỗi Ý nghĩa
AuthenticationRequiredError Một lượt quét cần thông tin xác thực được hỗ trợ.
ConfigurationError Cấu hình Codex hoặc một giá trị ghi đè không phù hợp.
InvalidTargetError Kho lưu trữ, đường dẫn, chế độ hoặc mục tiêu Git không phù hợp.
OutputDirectoryError Vị trí đầu ra hoặc quyền của vị trí đó không phù hợp.
OutputInsideProtectedRootError Thư mục đầu ra nằm trong kho lưu trữ hoặc worktree được quét.
PluginPythonUnavailableError Không có trình thông dịch Python sử dụng được.
PluginBootstrapError Không thể khởi động môi trường thực thi plugin.
ScanCostLimitExceededError Lượt quét đã vượt quá giới hạn chi phí ước tính.
IncompleteScanError Lượt quét kết thúc trước khi tạo ra kết quả bắt buộc.
ContractValidationError Một lượt quét đã hoàn tất trả về lỗi hợp đồng có cấu trúc.
ScanInterruptedError Một sự gián đoạn đã dừng lượt quét và có thể để lại đầu ra một phần.

Tiếp tục với hướng dẫn bắt đầu nhanh với CLI, hướng dẫn CI hoặc tài liệu tham chiếu CLI.