diff --git a/README.md b/README.md index d70ee6d752..38bc4c4aaa 100644 --- a/README.md +++ b/README.md @@ -67,16 +67,8 @@ To use Codex's Daybreak toggle, pass `--codex daybreak=true`. It defaults off and requires compatible access. See [Daybreak configuration](sdk/typescript/docs/cli.md#daybreak-opt-in) for SDK and plugin usage, including Deep Scan workers. -Scans use your existing `SECURITY.md` guidance. To define or update it, -optionally [draft a policy](#generate-securitymd): - -```bash -cs policy . -``` - -The draft is saved outside your repository. Review the diff and notes, edit the -draft, then copy only `SECURITY.md` to the **Policy target** shown. You can scan -without generating a policy. +Scans use your existing `SECURITY.md` guidance. You can optionally +[draft or update a policy](#generate-securitymd) before scanning. To run without a global installation, replace `cs` in these examples with `npx @openai/codex-security`, for example: diff --git a/docker/README.md b/docker/README.md index bd1d01a01c..8f11d4beed 100644 --- a/docker/README.md +++ b/docker/README.md @@ -118,15 +118,16 @@ also requires `latest` to reference that digest. `bootstrap` and not start a findings service or implement another workflow engine. It passes commands, output, and exit codes through the existing scanner entrypoint. -Run these commands from the repository root. After the selected scanner release -is available, prepare private directories and choose the host user's UID/GID so -the runner can write its bind mounts: +Run these commands from the repository root after +[verifying an image](#image-metadata-and-verification). Keep the verified +`reference` in the same shell. Prepare private directories and choose the host +user's UID/GID so the runner can write its bind mounts: ```bash mkdir -p results state chmod 700 results state export CODEX_SECURITY_USER="$(id -u):$(id -g)" -export CODEX_SECURITY_IMAGE=ghcr.io/openai/codex-security:latest +export CODEX_SECURITY_IMAGE="$reference" docker compose -f compose.runner.yaml pull docker compose -f compose.runner.yaml run --rm codex-security login --device-auth ``` diff --git a/docs/bedrock.md b/docs/bedrock.md index f6fbbe0ec1..1442bf31d6 100644 --- a/docs/bedrock.md +++ b/docs/bedrock.md @@ -60,8 +60,11 @@ Codex dependency; a successful inference alone does not verify all model metadat Bedrock defaults `model_reasoning_summary` to `none` because some models reject `reasoning.summary`. This setting reaches Deep Scan discovery and reducer workers, -including resumes. Reasoning effort is unchanged; an explicit summary override -still takes precedence. See [provider configuration](../sdk/typescript/README.md#amazon-bedrock). +including resumes. To request summaries from a model that supports them, add +`--codex 'model_reasoning_summary="auto"'` to the scan command. This explicit +override takes precedence over the default and does not change reasoning effort. +See [native configuration overrides](../sdk/typescript/docs/cli.md#runtime-configuration-and-worker-limits) +for the `--codex KEY=VALUE` syntax. ## Daybreak Blue and Red diff --git a/docs/project-configuration.md b/docs/project-configuration.md index 9e1651d672..707434f913 100644 --- a/docs/project-configuration.md +++ b/docs/project-configuration.md @@ -78,25 +78,28 @@ node sdk/typescript/bin/codex-security.mjs scan . -c docs/examples/codex-securit ## Settings -| Field | Meaning | Default | -| ------------------------------ | ---------------------------------------------------------------------------- | ---------------------------------- | -| `auth` | Credential source: `auto`, `chatgpt`, or `api-key`; never a credential value | `auto` | -| `scan.mode` | `standard` or `deep` | `standard` | -| `scan.max_time_minutes` | Advisory Standard investigation allowance; enforced Deep discovery limit, in minutes | Unset in Standard; 5760 in Deep | -| `scan.cyber_access_program` | Experimental OpenAI program: `standard`, `daybreak_blue`, or `daybreak_red` | Unset; preserve Codex defaults | -| `scan.scope` | Exactly one of `paths: [src]`, `diff: {base: HEAD}`, or `working_tree: {}` | Whole repository | -| `scan.knowledge_base` | Context files or directories | Empty list | -| `scan.instructions_file` | Additional scan instructions | Unset | -| `scan.validation_file` | Custom validation instructions; incompatible with active deep mode | Built-in validation | -| `scan.deep` | Deep discovery settings shown below | Existing deep defaults | -| `codex` | Native Codex settings and profiles | Existing isolated configuration | -| `limits.max_cost_usd_per_scan` | Estimated USD limit for one scan attempt | No limit | -| `policy.fail_on_severity` | Exit threshold: `critical`, `high`, `medium`, or `low` | Report-only | -| `output.directory` | Artifact directory outside the scanned Git worktree | Existing private artifact location | - -The file configures scan settings. Patching, PR creation, publication, post-scan -actions, and machine-specific plugin or Python selection remain explicit CLI/SDK -inputs. +| Field | Meaning | Default | +| ------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------- | +| `auth` | Credential source: `auto`, `chatgpt`, or `api-key`; never a credential value | `auto` | +| `scan.mode` | `standard` or `deep` | `standard` | +| `scan.max_time_minutes` | Advisory Standard investigation allowance; enforced Deep discovery limit, in minutes | Unset in Standard; 5760 in Deep | +| `scan.cyber_access_program` | Experimental OpenAI program: `standard`, `daybreak_blue`, or `daybreak_red` | Unset; preserve Codex defaults | +| `scan.scope` | Exactly one of `paths: [src]`, `diff: {base: HEAD}`, or `working_tree: {}` | Whole repository | +| `scan.knowledge_base` | Context files or directories | Empty list | +| `scan.instructions_file` | Additional scan instructions | Unset | +| `scan.validation_file` | Custom validation instructions; incompatible with active deep mode | Built-in validation | +| `scan.owner_suggestions` | Generate an owner-suggestions report after a committed Git scan | `false` | +| `scan.deep` | Deep discovery settings shown below | Existing deep defaults | +| `codex` | Native Codex settings and profiles | Existing isolated configuration | +| `limits.max_cost_usd_per_scan` | Estimated USD limit for one scan attempt | No limit | +| `policy.fail_on_severity` | Exit threshold: `critical`, `high`, `medium`, or `low` | Report-only | +| `output.directory` | Artifact directory outside the scanned Git worktree | Existing private artifact location | + +See [owner suggestions](../sdk/typescript/README.md#scan-options-and-output) for +supported scan types, cost-limit behavior, and the saved report. + +Patching, PR creation, publication, post-scan prompt files, and machine-specific +plugin or Python selection remain explicit CLI/SDK inputs. ## SDK and CLI contract @@ -116,6 +119,7 @@ The resolver maps file keys to the existing SDK options: | `scan.knowledge_base` | `knowledgeBasePaths` | `--knowledge-base` | | `scan.instructions_file` | `scanPromptFile` | `--scan-prompt-file` | | `scan.validation_file` | `validationPromptFile` | `--validation-prompt-file` | +| `scan.owner_suggestions` | `ownerSuggestions` | `--owner-suggestions` | | `scan.deep.workers` | `workers` | `--workers` | | `scan.deep.subagents_per_worker` | `subagents` | `--subagents` | | `scan.deep.stop_after_no_new` | `stopAfterNoNew` | `--stop-after-no-new` | diff --git a/github-action/README.md b/github-action/README.md index 113ab613b5..7373083ecf 100644 --- a/github-action/README.md +++ b/github-action/README.md @@ -120,12 +120,12 @@ sandbox requirements apply on both supported GitHub Cloud hosts. The CLI configures the provider and validates its model requirements. The Action uses the same provider names and forwards only the selected provider's credentials: -| `provider` | Step environment | -| --- | --- | -| `openai` (default) | `OPENAI_API_KEY`, or `CODEX_API_KEY` as a fallback | -| `amazon-bedrock` | AWS credentials and region; see the OIDC example below | -| `openrouter` | `OPENROUTER_API_KEY` | -| `fireworks` | `FIREWORKS_API_KEY` | +| `provider` | Step environment | +| ------------------ | ------------------------------------------------------ | +| `openai` (default) | `OPENAI_API_KEY`, or `CODEX_API_KEY` as a fallback | +| `amazon-bedrock` | AWS credentials and region; see the OIDC example below | +| `openrouter` | `OPENROUTER_API_KEY` | +| `fireworks` | `FIREWORKS_API_KEY` | OpenAI retains the `gpt-5.6-sol` default. Other providers require an explicit model ID your credentials can access. For example, replace the scan step in the @@ -360,11 +360,11 @@ findings policy. Completion does not certify that every vulnerability was found. The Action follows the CLI outcome consistently: -| CLI exit | Action result | -| --- | --- | -| `0` | `scan-status: completed`, `policy-status: passed`; the step succeeds. | -| `1` | `scan-status: completed`, `policy-status: failed`; the step fails on findings. | -| `2` or an interrupted process | `scan-status: failed`, `policy-status: not-evaluated`; the step fails. | +| CLI exit | Action result | +| ----------------------------- | ------------------------------------------------------------------------------ | +| `0` | `scan-status: completed`, `policy-status: passed`; the step succeeds. | +| `1` | `scan-status: completed`, `policy-status: failed`; the step fails on findings. | +| `2` or an interrupted process | `scan-status: failed`, `policy-status: not-evaluated`; the step fails. | Usable reports retained after an execution failure remain available, but are not eligible for SARIF upload. Invalid or missing required reports, a changed @@ -487,28 +487,12 @@ the next product version. This development pin does not necessarily track the latest CLI release. To upgrade it, update it and regenerate `runtime/package-lock.json`, rebuild the bundles, and run validation. -Releases use the product version from `sdk/typescript/package.json`. Before npm -publication, the release workflow exercises the Action's compatibility suite -against the packed CLI candidate. After publication and provenance verification, -the Action release workflow starts from that exact CLI source commit, updates -the runtime pin and integrity lock, and fetches the locked runtime through -Socket Firewall with an empty cache before running the CLI. The lock keeps -public npm URLs for Action consumers. The workflow rebuilds the bundles and -runs the Action checks in a job with read-only repository permissions. -A fresh publisher takes only the tested runtime lock, rebuilds -from the same source, and verifies the bundle hashes without executing the CLI. -It creates a distribution commit and an immutable `action-vX.Y.Z` tag with the -same version as `npm-vX.Y.Z`. The companion Action release includes the manifest -and SBOM before publication, lists the full distribution commit SHA, and links -to the npm release's canonical changelog. It is never marked Latest. - -The Action distribution commit differs from the CLI source commit because the -registry integrity lock is finalized after publication. Release metadata records -both commits, both tags, and the verified CLI integrity. A failed Action stage -can be rerun without republishing npm or changing its immutable release assets. -Recovery verifies existing Action assets and can finish a partial draft release. -Existing version tags are never moved. -See [the release process](../RELEASING.md) for the orchestration and recovery flow. +The `action-vX.Y.Z` release uses the same version as the corresponding +`npm-vX.Y.Z` CLI release. Its distribution commit includes the built bundles and +final runtime lock and differs from the CLI source commit. Pin the full Action +distribution SHA listed in the Action release, which also includes its manifest, +SBOM, and a link to the product changelog. See [the release process](../RELEASING.md) +for publication, verification, and recovery instructions. diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index e31bb320b0..405ea14d0c 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -33,10 +33,6 @@ are unavailable when reading saved activity or attaching scan logs to feedback, scans whose original session is compressed cannot resume. Plain `.jsonl` logs work on all supported runtimes. -`LocalPluginBootstrapError` identifies local plugin setup failures and extends -`PluginBootstrapError`, so existing catches keep working. Knowledge-base -preparation errors use `ConfigurationError`; wrapped diagnostics remain in `cause`. - ### Install the CLI Install the CLI globally: @@ -275,6 +271,7 @@ const security = new CodexSecurity({ Constructor options are `codexOverrides`, `pythonPath`, and `pluginPath`. The bundled runtime and plugin are used by default. `pythonPath` overrides the `PYTHON` environment variable. To choose a model, set `codexOverrides.model`. +For a custom `pluginPath`, check [custom plugin compatibility](#custom-plugins). To enable Daybreak on Codex 0.163.0 or later, set `codexOverrides.daybreak: true`. The toggle defaults off; an explicit `false` keeps it off. The setting reaches @@ -283,21 +280,8 @@ isolated configuration, so a desktop toggle or personal Codex configuration does not configure an SDK scan. See [Daybreak opt-in](docs/cli.md#daybreak-opt-in) for CLI, project-file, and direct plugin configuration. -New and resumed Deep Scans require a current plugin with -`directDeepScanEngine: 1`, `workerProviderSnapshot: 4`, and isolated worker -configuration support. Older custom plugins fail before scan execution; update -the plugin or omit `pluginPath` to use the bundled version. Discovery, reducer, -and resumed workers inherit per-scan provider, authentication, environment, and -executable settings, with their existing read-only permissions. Reading saved -reports does not require these execution capabilities. - -The SDK no longer adapts the older `node ./mcp/server.mjs` MCP entrypoint; use -the current shell or Windows launcher for runtime-root routing. - -Custom plugins must support the current workbench protocol for scan comparison -and archival. Update an older custom plugin or omit `pluginPath` to use the -bundled version. The SDK no longer adapts payloads or archives scan directories -on behalf of older workbench implementations. +Deep Scan discovery, reducer, and resumed workers inherit per-scan provider, +authentication, environment, and executable settings with read-only permissions. Scans use an isolated Codex configuration. See [runtime configuration](docs/cli.md#runtime-configuration-and-worker-limits) @@ -420,19 +404,15 @@ or planned counts, and cannot act as a pre-dispatch gate. Use `maxCostUsd` or stopping the scan. `onWorkerStatus` reports **best-effort** phase dispatch counts from model-emitted -text markers. The former helper-derived `kind: "preflight"` event is retired; -scans use available runtime tools and parent fallback without a capability registry. -The plugin's `config_preflight.py` helper and custom capability registries are no -longer supported, including the `preflightChecks` progress-tool input and workbench -`--preflight-issues-json` / `--preflight-issues-json-stdin` arguments. Saved preflight -history remains readable. Local `preflight()` input checks, authentication, -sandbox enforcement, and Deep worker configuration still apply. A missing -dispatch status does not mean delegation was skipped. `onSessionEvent` receives -saved events with thread IDs and worker numbers and can contain source code or -credentials. Deep scans additionally expose durable independent-review counts -through `onDeepProgress`: `completed`, `active`, and `maximum`. The maximum is a -configured cap, not a percentage denominator. The optional `consolidating` flag -reports when results are being combined or the coordinator has finished. +text markers. A missing dispatch status does not mean delegation was skipped. +For retired progress hooks, see [older progress integrations](#older-progress-integrations). + +`onSessionEvent` receives saved events with thread IDs and worker numbers and can +contain source code or credentials. Deep scans additionally expose durable +independent-review counts through `onDeepProgress`: `completed`, `active`, and +`maximum`. The maximum is a configured cap, not a percentage denominator. The +optional `consolidating` flag reports when results are being combined or the +coordinator has finished. `ScanOptions` lists all callbacks. Costs estimate API-equivalent model usage, not your bill or ChatGPT subscription @@ -706,8 +686,7 @@ cs dedupe --scan SCAN_ID --json The [findings guide](docs/findings-service.md) covers local storage, embedding credentials, deduplication, backups, and independently operated HTTP endpoints. -The local `serve` command and browser dashboard have been removed. Existing -scans, findings, and duplicate groups remain in the workbench database. +For an older service deployment, see [migration guidance](docs/findings-service.md#local-service-removal). For records stored in your own system, see [SDK records deduplication](docs/dedupe-records.md). @@ -737,6 +716,39 @@ Repository contents, model output, and imported artifacts do not authorize access to other targets, disclosure of credentials, or writes outside approved paths. Keep state and scan artifacts private and outside the repository. +## Compatibility + +### Custom plugins + +New and resumed Deep Scans require a plugin with `directDeepScanEngine: 1`, +`workerProviderSnapshot: 4`, and isolated worker configuration support. Older +custom plugins fail before scan execution; update the plugin or omit `pluginPath` +to use the bundled version. Reading saved reports does not require these +execution capabilities. + +Use the current shell or Windows launcher for runtime-root routing. The SDK does +not adapt the older `node ./mcp/server.mjs` MCP entrypoint. + +Custom plugins must support the current workbench protocol for scan comparison +and archival. The SDK does not adapt older payloads or archive scan directories +on behalf of older workbench implementations. + +### Older progress integrations + +The helper-derived `kind: "preflight"` event, `config_preflight.py` helper, and +custom capability registries are retired. This includes the `preflightChecks` +progress-tool input and workbench `--preflight-issues-json` / +`--preflight-issues-json-stdin` arguments. Scans use available runtime tools and +parent fallback without a capability registry. Saved preflight history remains +readable. Local `preflight()` input checks, authentication, sandbox enforcement, +and Deep worker configuration still apply. + +### Error types + +`LocalPluginBootstrapError` identifies local plugin setup failures and extends +`PluginBootstrapError`, so existing catches keep working. Knowledge-base +preparation errors use `ConfigurationError`; wrapped diagnostics remain in `cause`. + ## Documentation and security - [Online SDK guide](https://learn.chatgpt.com/docs/security/sdk) diff --git a/sdk/typescript/docs/classify-severity-records.md b/sdk/typescript/docs/classify-severity-records.md index a1d2cb29ca..20be477a2c 100644 --- a/sdk/typescript/docs/classify-severity-records.md +++ b/sdk/typescript/docs/classify-severity-records.md @@ -7,9 +7,8 @@ Use `--records` alone or with `--runs N`; model execution remains host-provided. The SDK exports `classifySeverityRecords`, `classifySeverityRecordsInputSchema`, and their input, result, and review-request types. The protocol and input have -version `1`. This is an additive capability: pin an artifact containing this -implementation until it is included in a published release. A prior CLI that does -not advertise `--records` in `classify-severity --help` cannot run this protocol. +version `1`. Before using the protocol, confirm that your installed CLI lists +`--records` in `classify-severity --help`. ## Immutable inputs @@ -26,7 +25,7 @@ Send one newline-delimited JSON-RPC request with `method: "run"` and these param ``` The `rubric` field is optional. Omit it to classify with the -[built-in severity rubric](../src/default-severity-rubric.ts), using the same configured +[built-in severity rubric](https://github.com/openai/codex-security/blob/main/sdk/typescript/src/default-severity-rubric.ts), using the same configured independent host reviews and usage accounting. The result echoes its built-in revision (currently `1`) and exact Markdown SHA-256. Supplying a custom rubric replaces the default completely and preserves the supplied revision/hash binding. diff --git a/sdk/typescript/docs/cli.md b/sdk/typescript/docs/cli.md index 94ba464595..d82eae6a64 100644 --- a/sdk/typescript/docs/cli.md +++ b/sdk/typescript/docs/cli.md @@ -23,6 +23,28 @@ findings file in local scan history, use GitHub import returns upstream alerts for validation; file import saves findings without running security analysis. +## Find a workflow + +- [Sign in or configure a provider](#authentication). +- [Scan a repository or selected paths](#scan-options-and-output), + [configure a Deep Scan](#configure-deep-scans), or + [save project settings](#project-files). +- [Review one system across repositories](#review-one-system-across-repositories) + or [run independent bulk scans](#bulk-scans). +- [Import vendor findings locally](#import-vendor-findings-locally), + [save findings as a scan](#import-findings-as-a-saved-scan), or + [retrieve GitHub alerts](#import-alerts-from-the-cli). +- [Inspect saved scans and rerun them](#scan-history-and-reruns), + [classify severity](#classify-finding-severity), or + [suggest owners](#suggest-finding-owners). +- [Validate and patch findings](#validate-and-patch-findings) or + [verify an existing fix](#verify-fixes). +- [Publish to Cloud](#publish-findings-to-cloud) or + [Linear](#publish-completed-scans-to-linear), or [export results](#exports-and-ci). +- [Draft a security policy](#generate-a-security-policy). +- [Use a hosted executor](#hosted-standard-scan) or + [run bulk scans in containers](#containerized-bulk-scans). + ## Authentication Sign in with ChatGPT, or supply an API key for CI: @@ -739,16 +761,9 @@ not to planning, result matching, or the total campaign. ### Configure deep scans -```ts -await security.run("/path/to/repository", { - mode: "deep", - workers: 2, - subagents: 0, - stopAfterNoNew: 3, - stopAfterConsecutiveErrors: 2, - maxDiscoveryRuns: 10, - maxTimeMinutes: 90, -}); +```bash +codex-security scan . --mode deep --workers 2 --subagents 0 \ + --stop-after-no-new 3 --max-discovery-runs 10 --max-time 90 ``` For `scan --mode deep`, `--workers` controls discovery concurrency and @@ -757,11 +772,13 @@ For `scan --mode deep`, `--workers` controls discovery concurrency and or duration. At the deadline, discovery stops; the scan then combines and returns completed findings. +For TypeScript, see the [SDK Deep Scan example](../README.md#configure-deep-scans). + Use project-file `scan.deep` settings or legacy `$CODEX_HOME/codex-security/config.toml` defaults. Counts must be positive except that `subagents` can be zero. Discovery time accepts positive fractional minutes; -its default and maximum remain 5760 minutes (96 hours). Unlike Standard's -advisory allowance, this existing Deep discovery limit is enforced. Resuming a +its default and maximum are 5760 minutes (96 hours). Unlike Standard's +advisory allowance, the Deep discovery limit is enforced. Resuming a Deep scan keeps its original deadline; rerunning starts a new scan. `--max-time-hours`, SDK `maxTimeHours`, project `scan.deep.max_time_hours`, and legacy TOML `deep_scan.max_time_hours` remain deprecated Deep-only aliases in @@ -1261,6 +1278,8 @@ network findings are not supported by this repository importer. Cloud destinatio currently support connected GitHub and GitHub Enterprise repositories, including custom Enterprise hostnames. Named Wiz exports do not add other VCS destinations. +#### Select findings and a destination + Use an authorized [Wiz MCP](https://www.wiz.io/blog/introducing-wiz-mcp) or Wiz API connection to acquire findings and save the supported native JSON. A configured plugin may provide that connection; an official Codex plugin is not a prerequisite. @@ -1307,6 +1326,8 @@ gzip-compressed JSON or CSV are accepted; gzip is detected regardless of the filename extension. **Raw Event** on Code & Build Scans contains scan metadata rather than findings. +#### Configure an alternate Cloud deployment + For an alternate Cloud deployment, set `CODEX_SECURITY_CLOUD_BASE_URL` to its API root before previewing or uploading, for example `https://cloud.example.test/backend-api/aardvark`. Remote APIs require HTTPS; @@ -1327,6 +1348,8 @@ the return link; all API requests still use `CODEX_SECURITY_CLOUD_BASE_URL`. For custom API destinations without a configured app URL, completion retains the manual navigation guidance rather than guessing a UI host or port. +#### Preview and publish + Preview the selection and destination: ```bash @@ -1352,6 +1375,8 @@ exclusions. `--dry-run --format json` retains all normalized findings and comple evidence for inspection. A prompt explicitly includes any records that will be skipped. +#### Package vulnerability inputs + Native package input can be a Wiz JSON vulnerability report, a vulnerability finding, an array, a complete `data.vulnerabilityFindings.nodes` response, or JSONL with one package record per line. The repository package-vulnerability CSV @@ -1402,6 +1427,8 @@ fetch from Wiz, assess findings, or change vendor or Cloud triage decisions. Findings from external network scans are excluded from this package vulnerability mapping. +#### SAST, repository secrets, and IaC inputs + For SAST, repository secrets, and IaC, save the documented JSON API collection: | Finding family | Collection | Raw occurrence identity | @@ -1460,6 +1487,8 @@ collection: } ``` +#### Preserved evidence + The adapters preserve each selected raw node exactly in `source_data`. Typed `evidence.details` carries `kind`, verified `repository`, vendor `source_status`, and family-specific evidence: @@ -1478,6 +1507,8 @@ does not establish that it is deployed. Precise original timestamps remain in `source_updated_at` field. SAST creation time and IaC last-seen time are not update timestamps. +#### Convert CSV reports + Native SAST and secret report downloads can be CSV, including gzip-compressed CSV. Those CSV profiles are not parsed directly. Convert a selected report with a reviewed mapping for its actual column headers into normalized JSONL, preserving each original row @@ -1502,6 +1533,8 @@ Inputs must be valid UTF-8. Integer-valued evidence outside JavaScript's safe integer range is rejected; export those values as strings to preserve them exactly. Invalid records appear in `excluded` with their source ID and reason. +#### Resume interrupted imports + Requests contain at most 100 findings and respect the Cloud payload limits. Before uploading, the publisher saves request IDs and bodies privately under the configured Codex Security state directory. After an uncertain response, @@ -1513,6 +1546,8 @@ API endpoint, not a link to the Cloud UI. A reset retires the old request without republishing; review and explicitly approve a fresh invocation. +#### Results and exit codes + Results distinguish completion from partial or interrupted work: | Status | Exit code | Meaning | @@ -1663,7 +1698,7 @@ The [records protocol](classify-severity-records.md) accepts immutable Markdown report snapshots and delegates model execution to the host. For saved findings, use exactly one of `--scan` (ID, prefix, or `latest`) and `--scan-dir`. -Omitting `--rubric` runs classification with the [built-in severity rubric](../src/default-severity-rubric.ts). +Omitting `--rubric` runs classification with the [built-in severity rubric](https://github.com/openai/codex-security/blob/main/sdk/typescript/src/default-severity-rubric.ts). It evaluates attacker access, boundary crossing, additional harm, and evidence for Critical, High, Medium, Low, and Informational findings. Confidence remains separate from severity; missing proof alone does not justify a downgrade. An explicit @@ -2464,6 +2499,10 @@ scan, triage, patch, and verification workflows, see the For local findings storage, deduplication, and custom endpoints, see the [findings guide](findings-service.md). +### Hosted Standard scan + +`codex-security scan --host` runs one versioned JSON-RPC invocation with an explicit host executor. Use it alone; it never performs local inference. See [the hosted scan protocol](hosted-scans.md) for input, filesystem, artifact, usage, and cancellation requirements. + ## Containerized bulk scans Create `repositories.csv` as described under [Bulk scans](#bulk-scans), then run @@ -2503,7 +2542,3 @@ capabilities, no-new-privileges, and seccomp policy. Hosts that permit nested us namespaces do not need it. The legacy Landlock fallback is unsupported. See the [Docker guide](https://github.com/openai/codex-security/blob/main/docker/README.md) for deployment and source-build instructions. - -### Hosted Standard scan - -`codex-security scan --host` runs one versioned JSON-RPC invocation with an explicit host executor. Use it alone; it never performs local inference. See [the hosted scan protocol](hosted-scans.md) for input, filesystem, artifact, usage, and cancellation requirements. diff --git a/sdk/typescript/docs/findings-service.md b/sdk/typescript/docs/findings-service.md index cb7f5083ee..9a62803887 100644 --- a/sdk/typescript/docs/findings-service.md +++ b/sdk/typescript/docs/findings-service.md @@ -5,124 +5,7 @@ Deduplication reads that database directly; no local HTTP service is needed. The CLI can also publish to and deduplicate against independently operated compatible endpoints through explicit `--findings-url` settings. -## Local service removal - -The `serve` command (including `--port`), `start:server` script, -`dist/server/index.js` entrypoint, `startFindingsServer` SDK export, browser -dashboard, and findings-service Compose deployment have been removed. -`HOST`, `PORT`, and `CODEX_SECURITY_FINDINGS_IMAGE` no longer configure a bundled -service. The dashboard storage projection is also removed. - -Existing SQLite databases, migrations, saved scans, findings, and duplicate -groups are retained. No data migration or deletion is performed. Keep any -existing service volume or state directory and back it up before changing -deployments; local deduplication uses the database selected by -`CODEX_SECURITY_STATE_DIR`, not a separate service volume automatically. - -`@openai/codex-security/server` continues to export `OpenAiFindingEmbedder`, -`SqliteFindingsStore`, and their storage types for direct storage users. - -For direct embedding/storage integrations, `OpenAiFindingEmbedder` accepts a -static key or `() => string | Promise` as its first argument. It calls -the callback before each HTTP batch; the caller handles token acquisition. -Cancellation prevents a new callback or HTTP request. Direct embedder callers -still await a key callback that has already started. -Pass `fetch` as the second argument and the full endpoint URL as the third. -By default, the saved-scan deduplication APIs use environment credentials. A -custom SDK `embedding` binding can supply an adapter with its own credentials, -including an `OpenAiFindingEmbedder` with a renewable key callback. - -Custom publication, explicit remote deduplication, Cloud publication, the -plugin MCP server, and Codex app-server are unchanged. - -## Direct storage helpers - -Direct callers of the retired Python findings helpers can use the retained Node -helpers from an installed plugin directory: - -```bash -scripts/launch_codex_security_mcp --helper list-stored-findings < request.json -``` - -On Windows, use `scripts\launch_codex_security_mcp.cmd` with the same arguments -and JSON on stdin. For example, `request.json` selects the existing database: - -```json -{ - "stateDirectory": "/absolute/path/to/state", - "payload": { "limit": 50, "offset": 0 } -} -``` - -Use an absolute Windows path on Windows. The retained helper commands accept -these `payload` fields: - -| Command | Payload | -| --------------------------- | ------------------------------------------------------------------------------------------------------- | -| `store-findings` | `entries` containing finding and embedding records; optional `repositoryId`. | -| `list-stored-findings` | Positive integer `limit` and non-negative integer `offset`. | -| `find-potential-duplicates` | `findingId` and `scope`: either `{ "repositoryId": "REPOSITORY_ID" }` or `{ "allRepositories": true }`. | -| `store-dedupe-groups` | `groups`, an array of finding-ID arrays. | -| `list-dedupe-groups` | `findingId`. | - -Retained scan commands such as `workbench_db.py list-findings` keep their existing -interface. The dashboard projection is removed along with the browser dashboard. - -## Publish a scan - -Send a completed scan to an independently operated compatible endpoint: - -```bash -codex-security publish scan --scan SCAN_ID --to custom \ - --findings-url https://findings.example.com --json -``` - -`--findings-url` is required. The client appends `/v1/bulk/findings` to this -base URL, preserving any base path. Custom endpoints must implement that API -and return the stored finding IDs. - -Publication sends the complete sealed findings and the manifest's -`scan.target.targetId` as `repositoryId`. It leaves the scan artifacts unchanged -and does not forward model credentials. The endpoint is responsible for storing the batch before acknowledging it. - -Use `--scan` for a saved scan, `--scan-dir` for an external scan directory, or -the interactive picker. Custom publication accepts one scan; CSV input and -Linear options do not apply. Add `--dry-run` to preview the payload without an -HTTP request. Upload failures and incomplete receipts fail the command. Uploads -are not automatically retried because a lost response may have been committed. - -```typescript -import { publishScanToCustom } from "@openai/codex-security"; - -const receipt = await publishScanToCustom("/path/to/completed-scan", { - findingsUrl: "https://findings.example.com", - // dryRun: true, - // signal: controller.signal, -}); -console.log(receipt.repositoryId, receipt.findingIds); -``` - -## Compatible endpoint contract - -The retained HTTP clients use these endpoints on the supplied base URL, -preserving its base path: - -| Method | Path | Response | -| ------ | --------------------------------------- | ------------------------------------------------------------------------ | -| `POST` | `/v1/bulk/findings` | An array acknowledging all submitted finding IDs; order does not matter. | -| `GET` | `/v1/finding/{id}/potential-duplicates` | `{finding, potentialDuplicates}` containing complete finding records. | -| `POST` | `/v1/dedupe-groups` | A successful JSON acknowledgement, such as `{}`. | - -Publication sends `{findings, repositoryId}`. Candidate requests include either -`repositoryId` or `allRepositories=true`. Group writes send -`{groups: [[findingId, ...], ...]}`; repeated membership must be idempotent for -workflow retries. Both POST endpoints must persist their writes before -acknowledging them and return a JSON body. An explicit URL selects this remote -contract instead of local SQLite. This package no longer implements or hosts the HTTP endpoints. - -SDK findings client failures preserve the endpoint's error code and message with -the HTTP status. Other responses retain the HTTP-status diagnostic. Retry -behavior uses the HTTP status and `Retry-After`. +For an older service deployment or helper integration, see [compatibility](#compatibility). ## Deduplicate a scan @@ -405,3 +288,121 @@ including `text-embedding-3-large`, 1,536-dimensional float vectors, and token array inputs. Requests encode the complete finding JSON with `cl100k_base` and send the API key as a bearer token. Long inputs are combined without truncation. Cached compatible vectors avoid new requests. + +## Publish a scan + +Send a completed scan to an independently operated compatible endpoint: + +```bash +codex-security publish scan --scan SCAN_ID --to custom \ + --findings-url https://findings.example.com --json +``` + +`--findings-url` is required. The client appends `/v1/bulk/findings` to this +base URL, preserving any base path. Custom endpoints must implement that API +and return the stored finding IDs. + +Publication sends the complete sealed findings and the manifest's +`scan.target.targetId` as `repositoryId`. It leaves the scan artifacts unchanged +and does not forward model credentials. The endpoint is responsible for storing the batch before acknowledging it. + +Use `--scan` for a saved scan, `--scan-dir` for an external scan directory, or +the interactive picker. Custom publication accepts one scan; CSV input and +Linear options do not apply. Add `--dry-run` to preview the payload without an +HTTP request. Upload failures and incomplete receipts fail the command. Uploads +are not automatically retried because a lost response may have been committed. + +```typescript +import { publishScanToCustom } from "@openai/codex-security"; + +const receipt = await publishScanToCustom("/path/to/completed-scan", { + findingsUrl: "https://findings.example.com", + // dryRun: true, + // signal: controller.signal, +}); +console.log(receipt.repositoryId, receipt.findingIds); +``` + +## Compatible endpoint contract + +The retained HTTP clients use these endpoints on the supplied base URL, +preserving its base path: + +| Method | Path | Response | +| ------ | --------------------------------------- | ------------------------------------------------------------------------ | +| `POST` | `/v1/bulk/findings` | An array acknowledging all submitted finding IDs; order does not matter. | +| `GET` | `/v1/finding/{id}/potential-duplicates` | `{finding, potentialDuplicates}` containing complete finding records. | +| `POST` | `/v1/dedupe-groups` | A successful JSON acknowledgement, such as `{}`. | + +Publication sends `{findings, repositoryId}`. Candidate requests include either +`repositoryId` or `allRepositories=true`. Group writes send +`{groups: [[findingId, ...], ...]}`; repeated membership must be idempotent for +workflow retries. Both POST endpoints must persist their writes before +acknowledging them and return a JSON body. An explicit URL selects this remote +contract instead of local SQLite. This package no longer implements or hosts the HTTP endpoints. + +SDK findings client failures preserve the endpoint's error code and message with +the HTTP status. Other responses retain the HTTP-status diagnostic. Retry +behavior uses the HTTP status and `Retry-After`. + +## Compatibility + +### Local service removal + +The `serve` command (including `--port`), `start:server` script, +`dist/server/index.js` entrypoint, `startFindingsServer` SDK export, browser +dashboard, and findings-service Compose deployment have been removed. +`HOST`, `PORT`, and `CODEX_SECURITY_FINDINGS_IMAGE` no longer configure a bundled +service. The dashboard storage projection is also removed. + +Existing SQLite databases, migrations, saved scans, findings, and duplicate +groups are retained. No data migration or deletion is performed. Keep any +existing service volume or state directory and back it up before changing +deployments; local deduplication uses the database selected by +`CODEX_SECURITY_STATE_DIR`, not a separate service volume automatically. + +`@openai/codex-security/server` continues to export `OpenAiFindingEmbedder`, +`SqliteFindingsStore`, and their storage types for direct storage users. + +For direct embedding/storage integrations, `OpenAiFindingEmbedder` accepts a +static key or `() => string | Promise` as its first argument. It calls +the callback before each HTTP batch; the caller handles token acquisition. +Cancellation prevents a new callback or HTTP request. Direct embedder callers +still await a key callback that has already started. +Pass `fetch` as the second argument and the full endpoint URL as the third. +By default, the saved-scan deduplication APIs use environment credentials. A +custom SDK `embedding` binding can supply an adapter with its own credentials, +including an `OpenAiFindingEmbedder` with a renewable key callback. + +### Direct storage helpers + +Direct callers of the retired Python findings helpers can use the retained Node +helpers from an installed plugin directory: + +```bash +scripts/launch_codex_security_mcp --helper list-stored-findings < request.json +``` + +On Windows, use `scripts\launch_codex_security_mcp.cmd` with the same arguments +and JSON on stdin. For example, `request.json` selects the existing database: + +```json +{ + "stateDirectory": "/absolute/path/to/state", + "payload": { "limit": 50, "offset": 0 } +} +``` + +Use an absolute Windows path on Windows. The retained helper commands accept +these `payload` fields: + +| Command | Payload | +| --------------------------- | ------------------------------------------------------------------------------------------------------- | +| `store-findings` | `entries` containing finding and embedding records; optional `repositoryId`. | +| `list-stored-findings` | Positive integer `limit` and non-negative integer `offset`. | +| `find-potential-duplicates` | `findingId` and `scope`: either `{ "repositoryId": "REPOSITORY_ID" }` or `{ "allRepositories": true }`. | +| `store-dedupe-groups` | `groups`, an array of finding-ID arrays. | +| `list-dedupe-groups` | `findingId`. | + +Retained scan commands such as `workbench_db.py list-findings` keep their existing +interface. diff --git a/sdk/typescript/docs/hosted-remediation.md b/sdk/typescript/docs/hosted-remediation.md index 5adcf0685a..3d379826aa 100644 --- a/sdk/typescript/docs/hosted-remediation.md +++ b/sdk/typescript/docs/hosted-remediation.md @@ -124,7 +124,9 @@ the final execution receipt so usage and session identity survive cancellation. The transport emits one terminal result. Preparation failures are JSON-RPC errors; a mismatched HEAD includes `error.data.reason: "revision_mismatch"`. -Run the deterministic installed-package smoke check without model credentials: +To run the deterministic installed-package smoke check, use a source checkout +of this repository and run the following from `sdk/typescript`. The script is +not included in the npm package and needs no model credentials: ```sh node scripts/smoke-hosted-remediation.mjs /path/to/node_modules/@openai/codex-security