Independent AI intelligence Two editions daily · ET
FervorAI

Analysis · July 29, 2026 · repo

openai/codex-securityCodex Security CLISARIFcodexagent-securityagent-infrastructureagent-harness

OpenAI's codex-security Refuses to Write Its Findings Inside Your Repo

The Apache-2.0 scanner OpenAI shipped without an announcement spends more of its README on where results go than on what it detects. That is the part worth copying.

A repository appeared under the openai organization on July 28 with no blog post, no launch thread, and no announcement. Hacker News found it first and OpenAI's account acknowledged it afterward. It is openai/codex-security, Apache-2.0, a CLI plus TypeScript SDK that scans a codebase for security issues, validates the candidates, and writes patches.

Read the README expecting detection claims and you will not find any. There is no benchmark, no false-positive rate, no comparison against a SAST tool. What you find instead is an unusual amount of text about the results directory. It must sit outside the scanned directory and outside any enclosing Git worktree. On macOS and Linux an existing output directory must be chmod 700. The README says why, in plain words: "Scan artifacts can contain source excerpts, vulnerability details, and reproduction steps. Keep them out of repositories, public issue reports, and shared locations."

The tool will not let you put its output next to your code. That refusal is the most interesting thing in the repository, and it is pointing at a problem most teams have not thought about yet.

The output is the dangerous artifact

Traditional static analysis produces noise. A SAST report is mostly false positives, which is annoying and also, accidentally, a form of protection. Leak the report and an attacker inherits your triage problem along with it.

codex-security is built to remove exactly that property. The scan runs in four named phases: ranking, file review, validation, and attack path. The validation phase runs candidates in a sandbox to discard false positives. OpenAI's product description says the agent tests suspected flaws and generates proof-of-concept exploits.

So what lands in that results directory is not a list of maybes. It is a filtered set of issues that a model already confirmed, ranked by severity, annotated with the source that contains them and the steps to reproduce them. That document is more useful to an attacker than your source code is, because your source code does not come with a table of contents pointing at the soft parts.

Nobody has habits for this. Teams commit .eslintcache. They paste scan output into Slack. They attach reports to Jira tickets that half the company can read. They push CI artifacts to buckets with generous read policies. Every one of those reflexes was formed in an era when a scan report was a pile of unconfirmed guesses, and codex-security is the first widely visible tool to say out loud that the era ended.

What the tool actually enforces

The controls are worth listing because they read like a policy document that someone turned into code.

Results are written as canonical scan documents with size limits (16 MiB manifest, 128 MiB findings, 32 MiB coverage) and a seal. The export command validates that seal before it writes SARIF, CSV, or JSON, and it can produce those exports without starting Codex or loading credentials at all, which means the person generating a report for auditors never needs the key that generated the findings.

Coverage is a first-class output rather than a footnote. Exit code 2 covers incomplete coverage alongside invalid input and runtime errors, so a scan that could not review everything fails your pipeline the same way a broken scan does. The scans compare command classifies findings between two runs as new, persisting, reopened, resolved, or unknown, and "unknown" specifically means the finding's original location was not reviewed this time. The tool tells you what it did not look at. Very few scanners do.

The MCP surface is deliberately almost empty. codex-security registers an MCP server, but it exposes only a read-only metadata command. Scans, authentication, exports, validation, and patching stay CLI-only, and the stated reason is that the MCP transport cannot cancel an active scan. A vendor shipping an agent tool that declines to give agents the interesting verbs is a small thing, and it is the right call.

The container story has a similar flavor. The bundled Compose config drops all Linux capabilities, sets no-new-privileges, runs as a nonroot user, and ships its own default-deny seccomp profile. That last one exists because Docker's default seccomp profile blocks the user and mount namespaces the per-scan sandbox needs, so OpenAI had to write a profile that permits precisely those operations and nothing more. The scanner runs each scan command inside its own unprivileged sandbox, which is the correct posture for a tool whose job is reading hostile-shaped code.

Then there is bulk-scan, which is where the output problem stops being theoretical. Sign in with gh auth login and the command discovers every GitHub repository you pushed to in the last 90 days, excluding archives and forks. Select, confirm, and scan. Four workers by default, resumable, results and manifest landing on the host. That single command can turn a quiet afternoon into a directory containing validated, reproducible attack paths across your entire org's active codebase.

Put this into practice

Do the smallest useful thing first, and decide where the output lives before you generate any.

Install and scan one repository you own:

npm install @openai/codex-security
npx codex-security login
npx codex-security scan /path/to/repo --dry-run

The --dry-run flag reports the effective model, reasoning effort, and credential source without contacting the network or starting a scan. Run it before the real thing so you know what you are about to be billed for. Then run the real scan with results in a throwaway private directory:

SCAN_ROOT="$(mktemp -d)"
npx codex-security scan /path/to/repo --output-dir "$SCAN_ROOT/results" --json

For CI, use diff mode rather than full-repository mode. A full scan takes tens of minutes per repository at the default extra-high reasoning setting, which is a budget decision on a monorepo, not a free check. Scanning the diff against your main branch turns that into something you can afford on every pull request:

npx codex-security scan . --diff origin/main \
  --output-dir "$SCAN_ROOT/results" --json --fail-on-severity high

Treat exit code 2 as a real failure, not a flake. It means coverage was incomplete, which means a clean report is a clean report about part of your code.

Skip install-hook for now. It blocks commits on high-severity findings, and until you know this tool's behavior on your codebase, a pre-commit gate driven by a model is a good way to make your team learn how to bypass it. Earn that gate after a few weeks of report-only runs.

Before your first bulk-scan, write down three things: where the results directory lives, who can read it, and how long you keep it. Scan output should be treated like credentials in transit and like an incident file at rest. If you cannot answer those three questions, you are not ready to generate a validated exploit inventory for your whole organization.

The scanner also accepts --knowledge-base pointed at your threat models or architecture docs, in Markdown, text, PDF, or Word. That is the single most useful flag in the tool for anyone with real design documentation, and almost nobody will use it.

Honest limitations

The license is not the product. The CLI and SDK are Apache-2.0, and the code is genuinely public, but the scanning happens against OpenAI's service. You sign in with an OpenAI account or supply an API key, and Codex Security itself is a research preview available to ChatGPT Pro, Enterprise, Business, and Edu customers, or via API key in CI. Open-sourcing the client is real and useful and it does not mean you can run this without a relationship with OpenAI. Every scan sends your code somewhere and bills someone.

There is no published detection evidence in the repository. No benchmark, no comparison against Semgrep or CodeQL, no recall figure, no false-positive rate after validation. You cannot tell from the README whether this finds more than the scanner you already run, and the only way to know is to point both at a repository whose bugs you already know and compare.

The project is early by its own admission. Ninety-eight commits at the time I looked, a semver note warning that the public API may change between minor versions before 1.0.0, and three open pull requests. GitHub's anonymous pages served zero stars, zero forks, and zero watchers for a repository that hit the top of the trending boards the same week, so the counters are stale and there is no reliable adoption signal to read.

The operational requirements are narrower than the "macOS, Linux, and Windows" line suggests. Scanning and exporting need Python 3.10 or later on top of Node 22. Production Docker campaigns need a Linux host that allows unprivileged user namespaces, because some Docker Desktop virtual machines restrict the nested mount namespaces the sandbox depends on. OpenAI says so in the README, which is to their credit, and it still means the polished bulk path is not going to run on your laptop.

And the bulk-scan convenience is a trade. Handing a tool your GitHub CLI session so it can enumerate and clone 90 days of your pushes is a large grant made through a very small prompt. It reuses your existing sign-in without touching your global Git config, which is careful engineering, and the grant is still the grant.

The habit worth stealing

You do not need to adopt this scanner to take the useful thing from it.

Go look at where your current security tooling writes its output. Check whether that path is inside a repository, inside a shared bucket, inside a ticket, inside a channel. Then ask what that file would be worth to somebody who wanted into your systems, now that a model has already done the work of separating the real findings from the noise.

OpenAI answered that question by making the tool physically refuse to write results next to the code. Your tools probably will not stop you. That is the part you have to decide for yourself.

Sources: openai/codex-security README; Codex Security research preview announcement, OpenAI; Codex Security docs; open-source request, openai/codex issue #29878.