Agent can self-approve trust for a persistent hook through a nested TUI

Open 💬 3 comments Opened Aug 10, 2026 by adamseabrookclanker

What version of Codex CLI is running?

codex-cli 0.146.0

What platform is your computer?

macOS 15.7.8, Apple Silicon

What issue are you seeing?

An agent running in YOLO / danger-full-access mode created a persistent non-managed global hook, launched a nested interactive Codex TUI in a PTY, and supplied terminal input that selected “Trust all and continue” for the hook it had just authored.

The nested TUI displayed the normal hook-review checkpoint and warned that hooks run outside the sandbox after they are trusted. However, input generated by the parent agent was accepted as the user's trust decision. The UI then displayed “Trusting hooks…” and continued with the newly trusted hook.

This is distinct from #22546 and #24093, which concern an operator explicitly supplying --dangerously-bypass-hook-trust. In this case, no hook-trust bypass flag was used: the agent synthesized the interactive approval itself, and the trust was persisted.

I am not reporting this as a sandbox escape. The session was already running in YOLO mode. The issue is that the hook trust prompt appeared to be an independent human-review boundary, but the agent that authored the persistent code could satisfy that boundary itself.

What steps can reproduce the bug?

  1. Start Codex CLI 0.146.0 on macOS in YOLO / danger-full-access mode.
  2. Have the agent write or modify a non-managed persistent hook under the user's global Codex configuration.
  3. From the same agent session, launch a nested codex --no-alt-screen process using a PTY-capable shell tool.
  4. Observe the nested startup prompt:

```text
Hooks need review
...

  1. Trust all and continue

```

  1. Allow the parent agent to send keyboard input to the child PTY.
  2. The parent selects option 2 and presses Enter.
  3. Observe “Trusting hooks…” and that the nested session continues with the hook trusted.
  4. Modify the hook and repeat; the agent can also satisfy the renewed trust prompt.

The observed session log records the hook creation, nested TUI launch, selection of option 2, and the resulting “Trusting hooks…” state. I have not attached the complete log because it contains unrelated private workspace content and internal session data, but a narrow redacted excerpt can be provided privately.

What is the expected behavior?

A trust prompt for persistent non-managed hooks should require an out-of-band human action that the running agent cannot synthesize.

At minimum, an agent should not be able to both:

  1. author or modify a persistent hook; and
  2. programmatically approve the trust prompt for that same hook through a child terminal session.

Possible protections include marking agent-originated PTY input as non-human for security prompts, requiring approval in a separate trusted UI surface, or preventing model-driven tools from answering security/trust dialogs.

Additional information

Why this matters: once trusted, a global hook can execute in future sessions and projects. If an agent can author and approve the same persistent hook, a mistaken or prompt-injected agent could establish recurring code execution beyond the session where the mistake occurred.

No credentials, full session logs, local paths, or private repository content are included in this public report.

View original on GitHub ↗

3 Comments

jdcodes1 · 9 days ago

Worth stating the underlying invariant plainly, because it's stronger than the PTY trick: hook trust is a trusted_hash string in a plain TOML state file (HookStateToml.trusted_hash, compared in hook_trust_statushttps://github.com/openai/codex/blob/1f41cc5d92/codex-rs/hooks/src/engine/discovery.rs#L782-L804). A danger-full-access agent doesn't even need the nested TUI: it can write that file directly. So the trust checkpoint was never an enforceable boundary against a full-access agent — the PTY reproduction just demonstrates it politely, without the agent having to know the file format.

That reframes the fix space. You can't make the prompt agent-proof in YOLO mode; what you can fix is the silent persistence beyond the session:

  1. Record provenance with each trust grant (session id + whether a full-access/YOLO session was live when the state file changed).
  2. At the next human-interactive session start, re-surface any hook whose trust record appeared or changed during a full-access session — the startup hooks-review UI (tui/src/startup_hooks_review.rs) already exists for exactly this presentation, it just needs a "trusted while an agent had write access — reconfirm" category.
  3. Optionally treat the state file like the hook content: hash it into something the next session verifies, so out-of-band edits (by agent or attacker) are at least visible rather than indistinguishable from a human click.

That converts "agent quietly self-persists a hook that outlives the sandbox decision" into "human sees and reconfirms at the next real checkpoint," which is the actual security property the prompt appeared to provide.

sylvesterkaczmarek · 8 days ago

I have a defense-in-depth patch prepared for this. The proposed change disables persistent hook-trust actions in the startup review and /hooks when Codex thread/session launch context is present, and guards the shared TUI trust-write path as a backstop. I would frame it as Addresses #37890, not a complete fix: CODEX_THREAD_ID / CODEX_SESSION_ID are model-reachable and mutable, and a danger-full-access process can still edit user-owned trust state directly. A strong guarantee that persistent trust requires human presence needs a protected out-of-band approval/persistence surface. I’ll keep those limitations explicit in the PR.

sylvesterkaczmarek · 8 days ago

I implemented a defense-in-depth patch for this in my fork, but this repository currently restricts opening pull requests to collaborators, so GitHub will not allow me to submit it upstream directly.

Branch: https://github.com/sylvesterkaczmarek/codex/tree/fix/37890-nested-hook-trust
Diff: https://github.com/openai/codex/compare/main...sylvesterkaczmarek:codex:fix/37890-nested-hook-trust
Commit: https://github.com/sylvesterkaczmarek/codex/commit/de875e540b6d4be0aff866aae00858eb3fd30c41

The change adds a one-way deny guard on persistent hook-trust writes when a TUI inherits Codex session/thread context, with focused regression coverage. It is intentionally scoped as defense-in-depth because a full-access process can still modify user-owned config directly; a true human-presence guarantee would require a protected out-of-band approval surface.