Skip to content

macOS XProtect false positive deletes the CLI native binary (npm @openai/codex 0.130.0, darwin-arm64) #31377

Description

@jaydenbarnescs-tech

What issue are you seeing?

On macOS, XProtect/Gatekeeper flags the Codex CLI's native binary as malware, blocks it, and moves it to the Trash ("Malware was blocked and moved to the Trash"). This is the npm @openai/codex CLI, not the Codex desktop app — the existing open reports (#22194, #30972, #24246) are all about Codex.app, so this looks like a separate, CLI-specific case worth tracking on its own.

The file that gets deleted is the platform package's Mach-O:

.../@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/codex/codex

After deletion the CLI is broken:

Error: spawn .../codex-darwin-arm64/vendor/aarch64-apple-darwin/codex/codex ENOENT

The match is targeted, not a blanket quarantine. The same CLI package also vendors a native rg (ripgrep) Mach-O in the same vendor/aarch64-apple-darwin/ tree — that file was left completely untouched. Only the codex Mach-O was removed, which points to a specific XProtect signature match on that build's bytes (i.e. a false positive), not a quarantine-attribute or package-wide action. The npm-installed files carry no com.apple.quarantine attribute.

Environment

  • macOS 26.4 (build 25E246), Apple silicon (arm64)
  • XProtect version 5347 (on-access YARA file dated 2026-05-29)
  • Codex CLI: @openai/codex 0.130.0 (native pkg @openai/codex-darwin-arm64@0.130.0), installed via npm on 2026-05-14
  • Node v22.14.0

Why it only surfaced ~2 months after install

The binary ran fine from mid-May onward, then was flagged out of nowhere. The sequence that explains the delay:

  1. 0.130.0 was installed 2026-05-14; early runs passed Gatekeeper/XProtect and that verdict was cached (the binary carries a com.apple.provenance xattr and is tracked in the exec-policy store).
  2. XProtect 5347 definitions (YARA file dated 2026-05-29) shipped the matching signature after the install. Gatekeeper doesn't re-scan an unchanged, already-assessed binary on every launch, so codex kept running on its cached pass through June.
  3. On 2026-07-07 the machine had an unclean reboot (hard power-off after a low-memory / jetsam event). Gatekeeper's exec-policy caches (ExecPolicy, Tickets, KextPolicy) were rebuilt on boot.
  4. The first codex launch after that reboot (a login-time automation) got a fresh XProtect scan against the 5347 defs → the signature matched → the binary was blocked and deleted.

So this isn't a change in Codex — it's an unchanged 0.130.0 binary being re-scanned against newer definitions after a Gatekeeper cache reset. A fresh install of 0.130.0 today would hit it immediately on first run, with no cached pass to ride on. (The deletion time is pinned by the file's mtime to the post-reboot login; the block event itself is redacted in the unified log, so the cache-invalidation mechanism is the explanation most consistent with the timeline rather than something I can quote a log line for.)

Steps to reproduce

  1. npm install -g @openai/codex@0.130.0 on macOS (Apple silicon) with XProtect 5347.
  2. Run codex.
  3. XProtect blocks and deletes the native binary and posts the "Malware blocked / moved to Trash" alert. (An older install may keep working until its cached Gatekeeper verdict is invalidated — e.g. by a reboot or cache reset — after which the next launch triggers the block.)

Impact

The CLI is non-functional afterward, and anything that shells out to codex (CI, agents, scheduled automation) fails with spawn ... ENOENT.

Workaround / data point

npm install -g @openai/codex@latest (0.142.5) restored a native binary that was not flagged when executed on the same machine with the same XProtect 5347 definitions. So the current release appears unaffected; the 0.130.0 build is what trips the signature.

Ask

Please submit the affected 0.130.0 CLI binary to Apple as a false positive, and/or code-sign + notarize the CLI's native binary the way Codex.app already is (Developer ID Application: OpenAI OpCo, LLC — Team ID 2DC432GLL2), so XProtect stops matching it. Tracking this separately from the app-side reports would help, since the CLI's distribution and signing differ.

Related

#22194, #30972, #24246 — same XProtect behavior reported against the Codex desktop app.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions