Skip to content

fix: trust-gate project hooks and exec policies#14718

Merged
viyatb-oai merged 33 commits intomainfrom
codex/viyatb/trusted-project-config-gating
Apr 18, 2026
Merged

fix: trust-gate project hooks and exec policies#14718
viyatb-oai merged 33 commits intomainfrom
codex/viyatb/trusted-project-config-gating

Conversation

@viyatb-oai
Copy link
Copy Markdown
Collaborator

@viyatb-oai viyatb-oai commented Mar 14, 2026

Summary

  • trust-gate project .codex layers consistently, including repos that have .codex/hooks.json or .codex/execpolicy/*.rules but no .codex/config.toml
  • keep disabled project layers in the config stack so nested trusted project layers still resolve correctly, while preventing hooks and exec policies from loading until the project is trusted
  • update app-server/TUI onboarding copy to make the trust boundary explicit and add regressions for loader, hooks, exec-policy, and onboarding coverage

Security

Before this change, an untrusted repo could auto-load project hooks or exec policies from .codex/ as long as config.toml was absent. This makes trust the single gate for project-local config, hooks, and exec policies.

Stack

Test

  • cargo test -p codex-core without_config_toml

@viyatb-oai viyatb-oai changed the title Trust-gate project hooks and exec policies fix: trust-gate project hooks and exec policies Mar 14, 2026
@viyatb-oai viyatb-oai marked this pull request as draft March 14, 2026 21:29
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/trusted-project-config-gating branch from bc1c282 to 3b7e933 Compare March 27, 2026 01:22
@viyatb-oai viyatb-oai marked this pull request as ready for review March 27, 2026 01:22
@viyatb-oai viyatb-oai marked this pull request as draft March 27, 2026 01:24
@viyatb-oai viyatb-oai requested a review from bolinfest March 27, 2026 01:32
@viyatb-oai viyatb-oai marked this pull request as ready for review March 30, 2026 17:33
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
# Conflicts:
#	codex-rs/core/src/tasks/review.rs
# Conflicts:
#	codex-rs/core/src/codex_tests.rs
#	codex-rs/core/src/config/mod.rs
#	codex-rs/core/src/config_loader/mod.rs
viyatb-oai and others added 8 commits April 6, 2026 20:03
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Keep canonical project trust keys first so persisted trusted project entries keep their existing lookup shape while still matching symlink aliases.

Use the per-thread derived config for app-server thread-initialized analytics and isolate app-server integration subprocesses from host managed config by default.

Co-authored-by: Codex <noreply@openai.com>
Use the production project trust key helper in hook trust tests and normalize the migrated project expectation so Windows canonical path handling matches runtime behavior.

Co-authored-by: Codex <noreply@openai.com>
Session-start hook discovery is disabled on Windows, so trust-loading assertions for hooks are not meaningful there. Keep the cross-platform project trust normalization regression covered separately.

Co-authored-by: Codex <noreply@openai.com>
The session-start hook trust-loading assertions depend on hooks.json lifecycle hook discovery, which is intentionally disabled on Windows. Mark the two coverage tests ignored there so Windows CI stops expecting handlers that cannot load.\n\nCo-authored-by: Codex <noreply@openai.com>
@eternal-openai
Copy link
Copy Markdown
Contributor

Hey ok, thanks your patience -- I've reviewed this as best as I could, and it looks good though a few notes:

  • this does slightly change execpolicy semantics, though I think for the better
  • windows tests should probably be enabled, since we more recently tested that everything works fine on windows with hooks & re-enabled the feature for windows
  • there's a minor but potentially important issue with aliases and the hashmap:

Before this PR, the lookup had a clear rule:

  1. try the canonical path key
  2. if that misses, try the raw path key
  3. So if the config had both entries, there was still a deterministic winner: canonical first.

This PR changes that into:

  1. expand every configured project into all its alias keys
  2. insert all of them into a new HashMap
  3. later, look up whichever key matches

That sounds tidy, but it creates a collision problem. If config contains two entries that alias the same repo and disagree, both write to the same normalized key. One overwrites the other

[projects."/work/repo"]
trust_level = "trusted"

[projects."/tmp/link-to-repo"]
trust_level = "untrusted"

If /tmp/link-to-repo resolves to /work/repo, the new code can collapse both onto the same lookup key. Now the effective answer becomes “whichever entry won the overwrite,” instead of a defined policy.

@viyatb-oai
Copy link
Copy Markdown
Collaborator Author

Thanks for the detailed pass. I agree with the notes.

  • The execpolicy behavior change is intentional: project-owned policy should only participate once the project config layer is trusted, so an untrusted checkout cannot widen execution behavior.
  • I agree on Windows coverage. I had temporarily skipped the two tests while debugging the Windows hook runner, but since hooks are enabled there now, I will re-enable them and make the fixtures pass on Windows instead.
  • The alias collision is a good catch. I will fix the lookup to keep the prior deterministic precedence semantics (canonical path first, then raw path) rather than relying on alias-expanded HashMap insertion order. If two configured entries resolve to the same canonical project, the effective winner should be defined, not incidental.

I will patch those before merge.

Re-enable hook discovery on Windows so the trust-gating tests cover the real behavior instead of skipping it.

Avoid alias-expanded project maps that can let a configured symlink alias satisfy the canonical project lookup; keep exact/case-normalized matching deterministic instead.

Co-authored-by: Codex <noreply@openai.com>
viyatb-oai and others added 12 commits April 13, 2026 21:11
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
@viyatb-oai viyatb-oai merged commit 370bed4 into main Apr 18, 2026
25 checks passed
@viyatb-oai viyatb-oai deleted the codex/viyatb/trusted-project-config-gating branch April 18, 2026 00:57
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants