Codex Guardian incorrectly denies an explicitly authorized patch because it hallucinates a SHA-256 mismatch
Summary
Codex Guardian denied a narrowly scoped apply_patch request to add one exact Git-hook approval entry.
The planned SHA-256 and explicitly authorized SHA-256 were identical, but Guardian claimed they did not match and classified the clear authorization as user_authorization: "low".
This was an incorrect denial decision, not only an inaccurate displayed message.
Security impact
This affects security-sensitive approval workflows. The observed approval path provided Guardian with the unified diff as a string plus conversation history, rather than a typed deterministic comparison of authorization fields.
Possible effects:
- exact valid authorizations are rejected;
- cryptographic values are described inaccurately;
- fail-closed security workflows become impossible to complete;
- users may be encouraged to reword, retry, weaken, or bypass controls.
No control was bypassed. The registry and hook remained unchanged.
Environment
- Product: Codex Desktop
- Desktop version:
26.609.30741(build3808) - Embedded CLI/core:
codex-cli 0.140.0-alpha.2 - OS: macOS 26.5.2 (25F84), Apple Silicon
- Main model: GPT-5.6 Sol
- Approval reviewer:
auto_review/ Guardian - Operation:
apply_patch - Time: 2026-07-30, approximately 19:16–19:20 UTC+8
- Network during the original reproduction: off
Local paths below are deliberately redacted.
Exact values
Authorized SHA-256:
42d1fd4e8d8c139236a02b398cf9ea506fc69cea053b7e17431498889185d0
Independently calculated:
shasum -a 256 <REDACTED_HOOK_PATH>
42d1fd4e8d8c139236a02b398cf9ea506fc69cea053b7e17431498889185d0
Validation:
- planned length: 64
- authorized length: 64
- direct character comparison: equal
- leading/trailing whitespace: none
- embedded newline: none
- case difference: none
- prefix such as
sha256:: none
Redacted planned entry
{
"classification": "APPROVED_EFFECTIVE_HOOK_CHAIN",
"worktree": {
"method": "git_rev_parse",
"root": "<REDACTED_EXACT_WORKTREE>"
},
"repository_common_dir": "<REDACTED_REPOSITORY_COMMON_DIR>",
"global_hook": {
"path": "<REDACTED_HOOK_PATH>",
"realpath": "<REDACTED_HOOK_PATH>",
"sha256": "42d1fd4e8d8c139236a02b398cf9ea506fc69cea053b7e17431498889185d0",
"owner_uid": "<REDACTED_UID>",
"mode": "0755",
"state": "executable"
},
"delegated_hook": {
"path": "<REDACTED_EXACT_DELEGATED_PATH>",
"state": "absent"
},
"fixed_dependencies": []
}
Expected behavior
For an exact security-sensitive authorization, Guardian should deterministically compare typed values:
planned.global_hook.sha256 == authorized.global_hook.sha256
It may independently assess path and scope, but it should not claim cryptographic inequality without a deterministic comparison.
Actual behavior
First attempt:
{
"risk_level": "high",
"user_authorization": "low",
"outcome": "deny",
"rationale": "The planned entry's hook SHA-256 does not exactly match the user-authorized and reverified value."
}
The same exact patch was retried once after the user explicitly authorized one identical retry and reverified the 64-character value. Guardian again returned user_authorization: "low", outcome: "deny", and the same alleged mismatch.
No third attempt was made.
Observed approval path
Read-only local diagnosis found:
- The local preflight computes SHA-256 from the hook's raw bytes correctly.
- Its registry logic directly compares path, realpath, SHA-256, owner UID, mode, and state.
- The
apply_patchapproval prompt containscwd,files[], the complete unified diff in apatchstring, andtool: "apply_patch". - No typed
authorized_hook_sha256or deterministic authorization comparison was observable. - The patch string preserved the exact 64-character value on both attempts.
- A dedicated Guardian rollout returned the incorrect semantic assessment above.
- Guardian did not disclose the internal operands it believed were unequal.
The full rollout may contain sensitive conversation context and is intentionally not attached. A minimal redacted extract can be provided privately if needed.
Reproduction outline
- Enable
approvals_reviewer = "auto_review". - Request a security-sensitive
apply_patchthat requires one exact typed hash value. - Explicitly authorize the exact target, scope, path, mode, and SHA-256.
- Recalculate the file hash and verify direct equality immediately before the request.
- Submit a patch containing the exact authorized value.
- Observe Guardian incorrectly claim the hashes differ and downgrade authorization to
low.
Suggested correction
For security-sensitive approvals, supply Guardian or a deterministic policy layer with typed fields such as:
{
"authorization_type": "exact_git_hook_registry_entry",
"hash_domain": "raw_file_sha256",
"planned_sha256": "42d1fd4e8d8c139236a02b398cf9ea506fc69cea053b7e17431498889185d0",
"authorized_sha256": "42d1fd4e8d8c139236a02b398cf9ea506fc69cea053b7e17431498889185d0",
"algorithm": "SHA-256"
}
The equality decision should be deterministic. A denial should expose:
- compared field paths;
- hash domain;
- normalized planned and authorized values;
- lengths;
- equality result;
- stable error code.
Guardian can still assess authorization scope, but should not replace cryptographic equality with natural-language inference.
Requested outcome
Please confirm whether this is known and provide one of:
- a Codex update with deterministic typed authorization comparison;
- a supported structured approval mechanism for exact security-sensitive patches;
- a safe documented procedure that does not weaken or bypass the approval layer.
The affected workflow remains intentionally fail-closed.
Related area but different symptoms: #34976 and #33765.
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action