From 67640ec0c9599b47c747ce791373c304ea98258b Mon Sep 17 00:00:00 2001 From: sairenchristianbuerano Date: Tue, 20 Oct 2026 12:25:02 +0800 Subject: [PATCH] feat(agent_config): add AGCFG-008 for Codex project hooks A committed .codex/hooks.json hook that runs a repo script, a network or inline-execution primitive, or a credential path, once the user has reviewed and trusted it. Medium severity, separate from AGCFG-005 because Codex skips an untrusted project hook. Mirrors the engine fixture byte for byte and bumps the pack schema to 24. Merge only after the analyzer change that adds the repo_codex_hook_runs_repo_command predicate: an older engine skips the rule. --- README.md | 1 + agent_config/codex_hooks.yaml | 44 +++++++++++++++++++++++++++++++++++ manifest.yaml | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 agent_config/codex_hooks.yaml diff --git a/README.md b/README.md index 3a9cf38..10e1aa6 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ vercel_ai/ Vercel AI SDK rules (VAI-NNN, all typescri └── tool_definition.yaml VAI-004, VAI-005 agent_config/ Pre-trust harness config rules (AGCFG-NNN, MCPCFG-NNN; repo scope, no SDK gate) +├── codex_hooks.yaml AGCFG-008 ├── mcp_client_config.yaml MCPCFG-002 └── preauth_execution.yaml AGCFG-004..007 ``` diff --git a/agent_config/codex_hooks.yaml b/agent_config/codex_hooks.yaml new file mode 100644 index 0000000..fe145e6 --- /dev/null +++ b/agent_config/codex_hooks.yaml @@ -0,0 +1,44 @@ +policy: + id: agent_config_codex_hooks + name: Codex project hooks + category: agent_config + description: > + Repo-scoped rule for hooks committed to a repository's .codex/hooks.json. + Codex loads project hooks only from a trusted project layer and skips a hook + until the user has reviewed and trusted its exact definition, so this is not + a pre-trust execution rule like AGCFG-005. It flags a hook that, once + trusted, runs repo-controlled code or reaches the network or credential + files. The pack loads for every scan (the file it reads has no SDK import), + so the rule's own predicate does the gating. Fires once per scan, + attributed to the first offending hook. + +rules: + - id: AGCFG-008 + title: Codex project hook runs a repo-controlled command once trusted + severity: medium + confidence: 0.55 + applies_to: + - agent_config + scope: repo + match: + repo_codex_hook_runs_repo_command: true + explanation: > + A committed .codex/hooks.json declares a hook whose command or + commandWindows runs a script from the repo, uses a network or + inline-execution primitive such as curl, wget, nc, bash -c, sh -c or + python -c, or reads $HOME/.ssh, .aws or .env. Codex loads project hooks + only from a trusted project layer and skips a hook until the user has + reviewed and trusted its exact definition, so this does not run before + that review. Once trusted it runs on agent events with the developer's + privileges, and whoever controls the repo controls what it executes. The + documentation describes trust as recorded against the hook definition and + does not say whether editing a script the hook calls prompts a new + review. Hooks that only call a vetted binary outside the repo are not + flagged. + fix: > + Review each project hook before trusting it, and read the script it + calls. Prefer a command that is a vetted binary on the user's PATH over a + repo script, and never let a hook read credential files or call out to the + network. Keep personal hooks in ~/.codex/hooks.json instead of a file that + travels with the repo. If a project hook is unavoidable, review changes to + it and to the scripts it calls as you would a CI step. diff --git a/manifest.yaml b/manifest.yaml index f203f22..1d40fab 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -11,4 +11,4 @@ # # This file is metadata, not a rule: the engine's loader skips manifest.yaml # when walking the pack for policy files. -schema_version: 23 +schema_version: 24