Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,6 @@ codex-security scan . --provider fireworks --model accounts/fireworks/models/qwe
## Documentation

**👉👉 See the [Codex Security documentation](https://learn.chatgpt.com/docs/security/cli)** for full documentation.

See [project configuration](docs/project-configuration.md) for reusable YAML/JSON
settings, CLI overrides, and editor schema support.
12 changes: 12 additions & 0 deletions docs/examples/codex-security.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "./node_modules/@openai/codex-security/schemas/project-config.schema.json",
"scan": {
"mode": "standard",
"scope": { "paths": ["sdk/typescript/src"] }
},
"codex": {
"model": "gpt-5.6-sol",
"model_reasoning_effort": "xhigh"
},
"policy": { "fail_on_severity": "high" }
}
11 changes: 11 additions & 0 deletions docs/examples/codex-security.yaml
Comment thread
mldangelo-oai marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# yaml-language-server: $schema=./node_modules/@openai/codex-security/schemas/project-config.schema.json
# Schema path assumes this file is copied to the root of your project.
scan:
mode: standard
scope:
paths: [sdk/typescript/src]
codex:
model: gpt-5.6-sol
model_reasoning_effort: xhigh
policy:
fail_on_severity: high
343 changes: 343 additions & 0 deletions docs/project-configuration.md
Comment thread
mldangelo-oai marked this conversation as resolved.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions plugins/codex-security/plugin-files.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"schemas/tools/worker-threat-model.schema.json",
"scripts/config_preflight.py",
"scripts/deep_scan_config.py",
"scripts/deep_scan_defaults.json",
"scripts/deep_scan_workbench.py",
"scripts/filesystem_identity.py",
"scripts/finalize_scan_contract.py",
Expand Down
18 changes: 10 additions & 8 deletions plugins/codex-security/scripts/deep_scan_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import argparse
import json
import math
import os
from pathlib import Path
Expand All @@ -13,12 +14,15 @@
except ModuleNotFoundError: # pragma: no cover - Python 3.10 only
import tomli as tomllib

DEFAULT_WORKERS = 4
DEFAULT_SUBAGENTS = 3
DEFAULT_STOP_AFTER_NO_NEW = 4
DEFAULT_STOP_AFTER_CONSECUTIVE_ERRORS = 3
DEFAULT_MAX_DISCOVERY_RUNS = 40
DEFAULT_MAX_TIME_HOURS = 96
DEFAULTS = json.loads(
Path(__file__).with_name("deep_scan_defaults.json").read_text(encoding="utf-8")
)
DEFAULT_WORKERS = DEFAULTS["workers"]
DEFAULT_SUBAGENTS = DEFAULTS["subagents"]
DEFAULT_STOP_AFTER_NO_NEW = DEFAULTS["stopAfterNoNew"]
DEFAULT_STOP_AFTER_CONSECUTIVE_ERRORS = DEFAULTS["stopAfterConsecutiveErrors"]
DEFAULT_MAX_DISCOVERY_RUNS = DEFAULTS["maxDiscoveryRuns"]
DEFAULT_MAX_TIME_HOURS = DEFAULTS["maxTimeHours"]
MAX_TIME_HOURS = 96
CONFIG_KEYS = {
"workers",
Expand Down Expand Up @@ -130,8 +134,6 @@ def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--available-parallelism", type=int, required=True)
args = parser.parse_args()
import json

print(json.dumps(resolve_deep_scan_config(args.available_parallelism), sort_keys=True))


Expand Down
8 changes: 8 additions & 0 deletions plugins/codex-security/scripts/deep_scan_defaults.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"workers": 4,
"subagents": 3,
"stopAfterNoNew": 4,
"stopAfterConsecutiveErrors": 3,
"maxDiscoveryRuns": 40,
"maxTimeHours": 96
}
222 changes: 185 additions & 37 deletions sdk/typescript/README.md

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions sdk/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"./schemas/project-config.schema.json": "./schemas/project-config.schema.json"
},
"bin": {
"codex-security": "./bin/codex-security.mjs"
},
"files": [
"bin",
"dist",
"schemas",
"_bundled_plugin",
"LICENSE",
"README.md"
Expand All @@ -43,7 +45,7 @@
"scripts": {
"audit:prod": "pnpm audit --prod --audit-level high",
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
"build": "node --run clean && tsc -p tsconfig.build.json && node scripts/build-dashboard.mjs",
"build": "node --run clean && node scripts/generate-deep-defaults.mjs && tsc -p tsconfig.build.json && node scripts/generate-project-config-schema.mjs && node scripts/build-dashboard.mjs",
"build:plugin": "node scripts/build-plugin.mjs",
"check:plugin-source": "node scripts/check-plugin-source.mjs",
"check:package": "node scripts/check-package.mjs",
Expand All @@ -58,7 +60,7 @@
"test:mcp": "node --run build:plugin && pnpm --dir ../../plugins/codex-security/mcp-app run test:mcp",
"test:mutation": "stryker run",
"test:package": "node scripts/smoke-package.mjs",
"types": "pnpm run generate:models:check && pnpm --dir ../../plugins/codex-security/mcp-app run typecheck && tsc --noEmit"
"types": "node scripts/generate-deep-defaults.mjs --check && node scripts/generate-project-config-schema.mjs --check && pnpm run generate:models:check && pnpm --dir ../../plugins/codex-security/mcp-app run typecheck && tsc --noEmit"
},
"dependencies": {
"@inquirer/prompts": "8.3.0",
Expand All @@ -77,7 +79,9 @@
"pdfjs-dist": "6.2.108",
"react": "19.2.4",
"semver": "7.8.5",
"smol-toml": "1.6.1"
"smol-toml": "1.6.1",
"yaml": "2.9.0",
"zod": "4.4.3"
},
"devDependencies": {
"@openai/apps-sdk-ui": "0.2.2",
Expand Down
6 changes: 6 additions & 0 deletions sdk/typescript/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

211 changes: 211 additions & 0 deletions sdk/typescript/schemas/project-config.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"$schema": {
"description": "Editor schema URI or relative path. The CLI does not fetch or select a validator from this value.",
"type": "string",
"minLength": 1
},
"auth": {
"default": "auto",
"description": "Credential-source choice only; never a credential value.",
"type": "string",
"enum": ["auto", "chatgpt", "api-key"]
},
"scan": {
"type": "object",
"properties": {
"mode": {
"default": "standard",
"type": "string",
"enum": ["standard", "deep"]
},
"scope": {
"description": "One scope variant. Omit for the whole repository. Mode compatibility is checked after overrides.",
"anyOf": [
{
"type": "object",
"properties": {
"paths": {
"minItems": 1,
"type": "array",
"items": { "type": "string", "minLength": 1 },
"description": "Literal paths relative to the selected repository."
}
},
"required": ["paths"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"diff": {
"type": "object",
"properties": {
"base": { "type": "string", "minLength": 1 },
"head": {
"default": "HEAD",
"type": "string",
"minLength": 1
}
},
"required": ["base"],
"additionalProperties": false
}
},
"required": ["diff"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"working_tree": {
"type": "object",
"properties": {
"base": {
"default": "HEAD",
"type": "string",
"minLength": 1
}
},
"additionalProperties": false
}
},
"required": ["working_tree"],
"additionalProperties": false
}
]
},
"knowledge_base": {
"description": "Context files or directories, relative to this file. An empty list selects no additional context.",
"type": "array",
"items": { "type": "string", "minLength": 1 }
},
"instructions_file": {
"description": "Additional scan instructions, relative to this file.",
"type": "string",
"minLength": 1
},
"validation_file": {
"description": "Custom validation instructions, relative to this file; not supported in active deep scans.",
"type": "string",
"minLength": 1
},
"deep": {
"description": "Deep defaults; a valid block may be retained while standard mode is selected.",
"type": "object",
"properties": {
"workers": {
"default": 4,
"description": "Maximum concurrent deep-scan discovery workers.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"subagents_per_worker": {
"default": 3,
"description": "Subagents available to each deep-scan worker. Zero is valid.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"stop_after_no_new": {
"default": 4,
"description": "Stop after this many runs find no new issues.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"stop_after_consecutive_errors": {
"default": 3,
"description": "Stop after this many consecutive discovery errors.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max_discovery_runs": {
"default": 40,
"description": "Maximum deep-scan discovery runs.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max_time_hours": {
"default": 96,
"description": "Maximum deep-scan discovery hours (default: 96; maximum: 96).",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 96
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"codex": {
"description": "Native Codex overrides. Common key types are checked here; existing native and wrapper restrictions still apply.",
"type": "object",
"properties": {
"model": { "type": "string", "minLength": 1 },
"model_reasoning_effort": { "type": "string", "minLength": 1 },
"model_provider": { "type": "string", "minLength": 1 }
},
"additionalProperties": { "$ref": "#/definitions/__schema0" }
},
"limits": {
"type": "object",
"properties": {
"max_cost_usd_per_scan": {
"description": "Estimated USD limit per launched scan attempt, not a total batch budget. Omit for no limit.",
"type": "number",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
},
"policy": {
"type": "object",
"properties": {
"fail_on_severity": {
"description": "Exit threshold; does not filter retained findings. Omit for report-only behavior.",
"type": "string",
"enum": ["critical", "high", "medium", "low"]
}
},
"additionalProperties": false
},
"output": {
"type": "object",
"properties": {
"directory": {
"description": "Artifact directory relative to this file; existing outside-worktree checks still apply.",
"type": "string",
"minLength": 1
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"definitions": {
"__schema0": {
"anyOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "boolean" },
{ "type": "null" },
{ "type": "array", "items": { "$ref": "#/definitions/__schema0" } },
{
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": { "$ref": "#/definitions/__schema0" }
}
]
}
},
"title": "Codex Security project configuration",
"description": "Input schema for explicitly selected YAML or JSON project files. Filesystem, active scan combinations, native configuration, and runtime availability are checked separately.",
"$comment": "Generated from ProjectConfigInputSchema. Defaults are annotations; apply defaults only after merging input layers."
}
Loading
Loading