TL;DR
OpenAI open-sourced Codex Security under Apache-2.0 — a CLI plus TypeScript SDK (npm install @openai/codex-security, Node 22+, Python 3.10+) that scans a repo, builds a codebase-specific threat model, then reproduces each finding in an isolated sandbox before reporting it. That validation step is the real difference: Snyk and Semgrep tell you a pattern matched, Codex tries to prove it is exploitable. It hit 4.1k GitHub stars and 554 points on Hacker News within days. Skip it for now if you need sub-30-second PR feedback, air-gapped scanning, or SCA — Semgrep still wins all three.
OpenAI Just Open-Sourced Its Own Code Scanner — Here Is What Changed
By Rohit Raj — Founding Engineer · 10+ yrs MVP shipping · LinkedIn
OpenAI released `openai/codex-security` as an open-source project under the Apache-2.0 license — a CLI and TypeScript SDK for "finding, validating, and fixing security vulnerabilities in your code." The tool had been in research preview since March 2026; the open-sourcing is what put it on the Hacker News front page at 554 points and past 4.1k stars with 111 commits on main.
The one capability that actually changed the category is not the scanning. It is the validation. Every SAST tool you have used — Snyk, Semgrep, CodeQL, Checkmarx — reports a finding when a pattern matches a rule. Codex Security runs an extra step: it spins up an isolated environment, attempts to reproduce the issue, captures the execution details, and only surfaces the finding if it confirms exploitability (OpenAI docs).
Why that matters right now: false positives are the reason SAST gets switched off. Every security team I have worked with has the same arc — turn on the scanner, get 400 findings, triage 60, declare bankruptcy, set it to warn-only, forget it exists. A scanner that ships an exploitability verdict alongside the finding is attacking the actual failure mode of the category rather than adding another rule pack. Whether it *delivers* on that is the rest of this post — and there are three concrete cases below where I would not use it yet.
What Is Codex Security, and How Is It Different From a Linter?
A linter matches syntax. A traditional SAST tool matches syntax plus dataflow. Codex Security adds two stages neither has.
Stage 1 — it builds a threat model before it scans. When Codex connects to a repo it walks commits in reverse chronological order and constructs a codebase-specific model that captures *attacker entry points, trust boundaries, sensitive data, and high-impact code paths*. This is the part Semgrep structurally cannot do: Semgrep's engine is pattern-matching over an AST with a YAML rule syntax — deliberately stateless and fast, which is its strength. Codex is building a map of your application's actual attack surface first, then looking for issues *along* that map.
Stage 2 — it validates in a sandbox. Rather than emitting "possible SQL injection at line 44," it attempts to reproduce the issue in an isolated environment and captures execution details. The output is closer to a mini pentest finding than a lint warning.
The practical surface area, from the README:
- Repository-wide assessment — full scan, cold
- Targeted path review — scope to a directory
- Pull-request diff scanning — scan only what changed
- Scan history — findings tracked over time in a workbench state directory
- CI integration — non-interactive via
OPENAI_API_KEY - Structured output — for piping into security automation
Requirements are heavier than a typical scanner: Node.js 22 or later and Python 3.10 or later. That Python dependency is worth flagging — it means this is not a single static binary you drop into a slim Alpine CI image, and you will feel it in build times.
The honest framing: this is not a Semgrep replacement, it is a different layer. Semgrep answers "does this code match a known-bad pattern, in under 30 seconds." Codex answers "is there a reachable, exploitable vulnerability in this application, and can you prove it." Those are different questions with different price tags.
How Do You Actually Run It?
Install and first scan are genuinely two commands:
You can pin the credential explicitly, which matters when a machine has both available:
For CI there is no interactive login — you set OPENAI_API_KEY and it runs headless. A minimal GitHub Actions job that scans a pull request diff:
Two things in that YAML are not in the quickstart and will cost you an afternoon if you miss them. `fetch-depth: 0` — the default actions/checkout does a shallow clone, and a tool whose first move is walking commits in reverse chronological order has nothing to walk. `CODEX_SECURITY_STATE_DIR` — scan history lands in a workbench state directory, and on a hosted runner the default path is not reliably writable; the docs mention setting it explicitly for exactly this reason.
The TypeScript SDK is the same engine, programmatically:
That close() is not decorative — the SDK holds a session, and skipping it leaks the handle. Wrap it in try/finally in anything long-running.
Where Does Codex Security Actually Beat Snyk and Semgrep?
Three workflows where the validation step earns its cost.
1. Auditing a codebase you did not write. This is the strongest case. Inheriting a repo — an acquisition, a contractor handoff, a legacy service nobody owns — is exactly when you have no idea where the trust boundaries are. Semgrep will give you 300 pattern matches with no sense of which ones are reachable from the internet. A tool that builds an entry-point map first and validates exploitability gives you a triage order on day one instead of week three. If you are taking over an unfamiliar service, this is the scan to run before you touch anything.
2. Reviewing AI-generated code at volume. This is the whole reason the category is heating up. AI coding tools generate code at a pace human review does not match, and the failure modes are specific: hardcoded credentials, hallucinated API calls, and auth checks that look right and are not. A pattern matcher catches the hardcoded-secret class fine. It does *not* catch "this endpoint's authorization check passes a variable that is always truthy" — that needs reachability plus an exploitability attempt. I wrote about the adjacent problem of agents running destructive shell commands; this is the same trust problem one layer down, in the code the agent writes rather than the commands it runs.
3. Cutting triage cost on an existing backlog. If you already run Snyk or CodeQL and have a standing backlog of unresolved findings, the interesting play is not replacing your scanner. It is running Codex over the *backlog* to get exploitability verdicts on findings you have been ignoring for six months. That is a one-off job with a clear payoff and no pipeline change — the cheapest possible way to evaluate whether the validation actually works on your code.
What it does not do: dependency scanning. There is no SCA here, no CVE database for your package-lock.json. Snyk's core business is unaffected.
Codex Security vs Snyk vs Semgrep vs CodeQL: The Comparison Table
| Codex Security | Snyk Code | Semgrep | CodeQL | |
|---|---|---|---|---|
| License | Apache-2.0 (open source) | Proprietary | LGPL-2.1 CE + paid | Free for OSS, paid for private |
| Core method | Threat model + LLM analysis + sandbox validation | ML on vuln patterns (DeepCode AI) | AST pattern match, YAML rules | Dataflow queries over a compiled DB |
| Exploitability validation | Yes — reproduces in isolation | No | No | No |
| Typical scan time | Minutes (LLM + sandbox) | Seconds to minutes | <30s medium repo | 3–10 min / 100K LOC |
| SCA / dependency CVEs | No | Yes | Partial (Supply Chain tier) | No |
| Custom rules | No rule language | Limited | 2,000+ community rules, 30+ langs | Full QL query language |
| Runs offline / air-gapped | No — needs API | Partial | Yes | Yes |
| Cost model | OpenAI API token usage | ~$50/mo/dev; free tier 200 tests/mo | Free CE; paid tiers above | Free on public repos; GHAS on private |
| Best at | "Is this actually exploitable?" | Breadth + dependency coverage | Speed + customisation | Deep dataflow on supported langs |
The row that decides most architectures is scan time. Semgrep finishing a medium codebase in under 30 seconds is what makes it viable as a blocking pre-commit or PR gate. Anything that takes minutes and calls an external API cannot sit in that slot — developers route around a gate that costs them five minutes per push, every time, without exception.
The row that decides most *budgets* is cost model. Snyk and CodeQL are seat- or plan-priced, so cost is predictable. Codex Security is Apache-2.0 but bills through OpenAI API token usage, which means your scanning bill scales with repo size and scan frequency — a genuinely different financial shape. A 500-file monorepo scanned on every PR is not the same line item as a seat licence, and nobody can quote you a number until you measure it on your own code.
When Should You Skip It and Stay on Semgrep?
Three cases where I would not adopt this today, and one where I would refuse outright.
Skip if you need a fast blocking PR gate. Covered above and it is decisive. If your security check is the thing standing between a developer and a merge, it has to finish in seconds. Semgrep's sub-30-second scan is not a nice-to-have, it is the entire reason the gate survives contact with a team under deadline. Run Codex nightly or on a schedule instead — but do not put it in the merge path.
Skip if you need custom rules. Semgrep's YAML rule syntax lets you encode *your* invariants: "no raw SQL outside the repository layer," "every route handler calls requireAuth." That is often where your real risk lives, and it is organisation-specific by definition. Codex Security has no rule language at all. It finds what it decides is worth finding. Powerful, and not steerable.
Skip if you cannot send code to an external API. This is the hard blocker. Codex Security requires OpenAI API access — there is no air-gapped mode. If you work in defence, regulated health, or anywhere with a contractual prohibition on third-party code transmission, the evaluation ends here regardless of how good the tool is. Semgrep and CodeQL both run fully local.
Do not treat the validator as an assurance. This is the one I would push back on hardest if a client proposed it. A confirmed finding is strong evidence something *is* broken. An unconfirmed finding is not evidence something is safe — it may just mean the sandbox could not construct a working reproduction. If "Codex found nothing" starts being read as "we passed our security review," the tool has made you less safe, not more. That inversion is a governance problem, not a technical one, and it is the failure mode I would actually expect to see in the wild within a year.
Also worth noting: it is a research-preview tool that was open-sourced days ago, with 39 open issues on a 111-commit repo. Pin your version.
How I Would Wire This Into a Real Production Pipeline
If a client asked me to adopt this next sprint, I would not replace anything. I would run it as a second, slower tier beside what they already have — because the two failure modes it fixes (triage cost, exploitability doubt) are not the failure modes the fast tier is solving.
The shape I would ship:
- Tier 1 — blocking, on every PR: Semgrep. Sub-30-second, local, custom rules encoding the team's own invariants. This is the gate. Nothing that calls an external API goes here.
- Tier 2 — non-blocking, nightly on `main`: Codex Security, full repo scan, results posted to a channel rather than a merge check. Nightly caps your token spend at a knowable number instead of "however many PRs we opened today."
- Tier 3 — on demand: the backlog pass described earlier, run manually against existing unresolved findings.
Four wiring details that will not be in the README:
Cost ceiling before anything else. Token-billed scanning on a per-PR trigger is an unbounded cost with a broken feedback loop — the bill arrives a month after the busy sprint that caused it. I would set a hard OpenAI spend limit on the key *before* the first CI run, not after the first invoice. Scheduled triggers over event triggers, until you have a month of real numbers.
A dedicated, scoped API key. Not the application's key. A separate key for CI, so scanning spend is attributable and revocable without taking production down. This is the same discipline that stops a leaked build credential from becoming a product outage.
Findings into the tracker, not into a channel that scrolls. A confirmed-exploitable finding is a P1 with a reproduction attached. It should become a ticket automatically. If it lands in a Slack channel it is gone in a day, and you have paid for an audit nobody read.
Store the reproduction, not just the verdict. The execution details the validator captures are the most valuable artefact the tool produces, and they are also the bit that quietly disappears if you only persist a pass/fail. When the fix gets written six weeks later, the reproduction is what tells you whether it actually worked.
The honest summary: this is a real advance on a real problem, in a v-early package. The validation step attacks the thing that actually kills SAST adoption. The Python dependency, the missing air-gap mode, the absent rule language, and the token-based cost shape are all reasons to run it beside your existing scanner rather than instead of it — for at least a couple of release cycles.
Want This Wired Up Without the Five Gotchas the README Skips?
Most of the cost of adopting a new security tool is not the tool. It is the shallow-clone that silently breaks the threat model, the unbounded token bill nobody set a ceiling on, and the findings channel everyone muted in week two.
I build production systems where the security layer is wired in from the first sprint rather than bolted on before launch — CI gates, scoped credentials, and findings that land somewhere a human actually reads.
- Shipping something new? 6-week MVP — a working product with the pipeline, gates, and secrets handling already in place.
- Need this depth on the team, not on a ticket? Hire a founding engineer — architecture and delivery, embedded.
If you are also standing up agent infrastructure, the MCP stateless spec migration is the other thing worth reading this month.
