TypeScript SDK для Codex Security

Запускайте сканирование Codex Security из TypeScript, выбирайте цели и поставщиков, изучайте результаты и управляйте жизненным циклом сканирования.

Используйте TypeScript SDK для Codex Security, чтобы запускать из своего приложения или инструмента разработчика сканирование безопасности репозиториев и изменений кода. SDK возвращает типизированные данные об обнаруженных проблемах, сведения о покрытии и пути к артефактам сканирования. Для продолжительного сканирования он поддерживает предварительные проверки, ограничения стоимости, обратные вызовы для отслеживания хода выполнения и отмену.

SDK использует модули ECMAScript (ESM) и работает на стороне сервера с Node.js 24 или 26 либо с Node.js 22 начиная с версии 22.13.0. Для сканирования также требуется 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 работает с вашими локальными разрешениями операционной системы и не приостанавливается для получения одобрения. Процессы сканирования могут наследовать ваше окружение, поэтому удалите не относящиеся к задаче учётные данные перед началом. См. раздел Разрешения локального сканирования.

Сохраните этот пример как scan.mjs. Замените пути, запустите стандартное сканирование репозитория и закройте клиент после завершения работы. Передайте 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.manifest.scan.status);
  console.log(result.findings.findings.length);
} finally {
  await security.close();
}

Запустите его с помощью Node.js:

node scan.mjs

Пример выводит путь к отчёту, статус сканирования и количество обнаруженных проблем. Откройте отчёт, чтобы изучить доказательства. Количество зависит от репозитория и сканирования, поэтому не используйте ожидаемое количество для проверки работоспособности интеграции.

run проверяет сохранённые артефакты и возвращает ScanResult, когда result.manifest.scan.status имеет значение "completed". Изучите result.coverage, чтобы узнать о проверенных областях, исключениях и отложенной работе. Даже завершённое сканирование может иметь пробелы в охвате. Сбои среды выполнения, ошибки входных данных или нарушения целостности результатов могут вызвать ошибку.

В следующих примерах повторно используйте открытый клиент security и оставьте close() в finally, чтобы освободить среду выполнения. Добавляйте все дополнительные импорты в начало scan.mjs.

Проверка входных данных с помощью предварительной проверки

Используйте 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, чтобы узнать об отложенной работе и открытых вопросах.

Добавление базы знаний по безопасности

Передайте архитектурные документы, модели угроз или политики безопасности через 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 может вернуть результат, в котором manifest.scan.status имеет значение "completed", и передать предупреждение о бюджете через onWarning. Проверьте result.coverage, чтобы узнать, какая работа осталась незавершённой.

Если сканирование не может сформировать корректный завершённый результат, 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 или null, если SARIF отсутствует.
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);
}

Новые результаты не содержат coverage.completeness. Используйте manifest.scan.status, чтобы узнать статус выполнения, и изучите отложенные области, исключения и открытые вопросы в coverage, чтобы понять, что проверило сканирование.

result.toJSON() возвращает в одном готовом для JSON объекте манифест, проблемы репозитория и текущего сканирования, покрытие, идентификаторы сканирования и потока, reportPath, artifactsDir, sarifPath, стоимость и метаданные хода.

Отслеживание или отмена сканирования

Передайте обратные вызовы 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 из контроллера запроса или задания, чтобы отменить сканирование. Если через 30 минут сканирование всё ещё выполняется, этот пример прерывает его и выводит каталог со всеми сохранёнными выходными данными:



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

Прерванное сканирование может оставить частичный вывод в 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. Выбирайте модель, доступную с вашими учётными данными. Если вы входите через ChatGPT, проверьте доступность GPT-6.1 Sol, прежде чем использовать этот пример:

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 принимает каталог плагина или ZIP. pythonPath выбирает интерпретатор плагина. codexOverrides объединяет поддерживаемые значения с изолированной конфигурацией Codex. По умолчанию при сканировании используется gpt-5.6-sol с особо высоким уровнем усилий рассуждения. Задайте model и model_reasoning_effort в codexOverrides, чтобы использовать другую модель или уровень усилий рассуждения. Чтобы использовать Amazon Bedrock, задайте model_provider и model в codexOverrides.

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

Задайте auth: "api-key", чтобы потребовать API key из окружения. preflight принимает тот же параметр auth.

Обработка ошибок сканирования

Перехватывайте экспортируемый класс ошибки, соответствующий действию, которое может выполнить ваше приложение:

Ошибка Значение
AuthenticationRequiredError Для сканирования требуются поддерживаемые учетные данные.
ConfigurationError Конфигурация Codex или переопределение не подходят.
InvalidTargetError Репозиторий, путь, режим или цель Git не подходят.
OutputDirectoryError Расположение вывода или его разрешения не подходят.
OutputInsideProtectedRootError Каталог вывода находится внутри сканируемого репозитория или рабочего дерева.
PluginPythonUnavailableError Подходящий интерпретатор Python недоступен.
PluginBootstrapError Не удалось запустить среду выполнения плагина.
ScanCostLimitExceededError Сканирование превысило предполагаемый лимит стоимости.
IncompleteScanError Сканирование завершилось до получения требуемого результата.
ContractValidationError Завершенное сканирование вернуло ошибку структурированного контракта.
ScanInterruptedError Прерывание остановило сканирование и могло оставить частичный вывод.

Перейдите к краткому руководству по CLI, руководству по CI или справочнику по CLI.