🤖 feat: per-project trust confirmation for hooks and scripts#2598
🤖 feat: per-project trust confirmation for hooks and scripts#2598ibetitsmike merged 67 commits intomainfrom
Conversation
|
@codex review |
fbf9a51 to
5bbff1d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbf9a5193f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review Addressed both review comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 240477bb49
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review Addressed the remaining thread:
All callers of |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f81ab8867
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review Addressed:
When untrusted, the init hook is skipped with a clear log message ("Skipping .mux/init hook (project not trusted)"). |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02d7ada9fa
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review Addressed both outstanding threads:
|
|
Codex Review: Didn't find any major issues. Swish! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
Add a trust gate that prevents repo-controlled scripts and git hooks from executing until the user explicitly trusts the project. Gated vectors: - .mux/tool_env (sourced before every bash command) - .mux/tool_pre / tool_post / tool_hook (wraps tool calls) - Git hooks (post-checkout, applypatch-msg, pre-applypatch, etc.) Implementation: - Add trusted field to ProjectConfigSchema - Add projects.setTrust IPC endpoint - Thread trust through tool system, runtimes, and git operations - Neutralize git hooks via GIT_CONFIG env vars pointing core.hooksPath to /dev/null - Add ProjectTrustBanner component with confirmation modal - Add Security section in Settings for managing trust per-project - Add tests for bash tool_env gating, git env vars, and schema
Address Codex review: - Add gitNoHooksPrefix to provisionContainer checkout (initWorkspace path) - Add gitNoHooksPrefix to forkWorkspace checkout (fork path) - WorktreeManager already uses execFileAsync with env option (resolved in rebase)
…text in autofocus test
…, and WorktreeManager fork
Skip .mux/init hook when project is untrusted in: - WorktreeRuntime - SSHRuntime - DockerRuntime - DevcontainerRuntime
Integration tests expect hooks/scripts to run, so trust the project before creating workspaces. Added trustProject helper and integrated it into createWorkspace, createWorkspaceWithInit, and create.test.ts's local helper.
…Workspace - SSHRuntime.forkWorkspace: Add gitNoHooksPrefix to git worktree add and fallback git checkout commands for untrusted projects - LocalRuntime.initWorkspace: Add trust check alongside skipInitHook so .mux/init is suppressed for untrusted projects in local runtime
The handler was a no-op when called before workspace.create since
the project didn't exist in config yet. Now creates a minimal
project entry ({workspaces:[]}) so trust can be established before
the first workspace is created — fixing integration tests that
call trustProject() before workspace.create().
The test was missing trusted:true so the init hook was being skipped by the newly added trust gate in LocalRuntime.initWorkspace.
…merge ops - fetchOriginTrunk, fastForwardToOrigin, renameWorkspace, deleteWorkspace all receive noHooksEnv and pass it to execFileAsync - WorktreeRuntime forwards trusted from Runtime interface - workspaceService retrieves trusted from config for delete/rename/fork - Add GIT_CONFIG_PARAMETERS='' to GIT_NO_HOOKS_ENV to prevent bypass
… untrusted test - Add nhp prefix to git am --abort and git worktree remove in finally block - ProjectTrustBanner: try/catch with error display, shrink-0 on button - SecuritySection: pending state, disabled during save, aria-labels - Add 'skips init hook when untrusted' negative test in LocalRuntime
…skip bug - New shouldSkipInitHook() in initHook.ts centralizes skip logic - All 5 runtimes now use the shared helper (Local, Worktree, SSH, Docker, Devcontainer) - Fix: DevcontainerRuntime was missing skipInitHook check (only checked trusted) - Fix: SSHRuntime unused skipInitHook destructure - Fix: workspaceService fork cleanup used undeclared trusted variable - Fix: gitNoHooksEnv test updated for GIT_CONFIG_PARAMETERS field
bbe8329 to
f9d2bcc
Compare
|
@codex review |
- workspaceService tests: add loadConfigOrDefault mock, update deleteWorkspace assertion - ProjectPage autofocus test: use getProjectConfig instead of removed projects field
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9d2bcc973
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2fa4e0cd66
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06e7275ba1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cc7853d189
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e31b0430a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a70f64923
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
e04e436 to
9ddbed4
Compare
|
Codex Review: Didn't find any major issues. Keep it up! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c411a9da53
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The SecurityMixedTrust story has 2 trusted projects, producing 2 'Revoke trust' buttons. findByRole (singular) throws when multiple elements match. Switch to findAllByRole and assert count, matching the pattern in SecurityAllTrusted.
Snapshot the projectPath that triggered the trust dialog into the trustPrompt state. The onConfirm callback now reads trustPrompt.projectPath instead of the outer closure's projectPath, so switching projects while the dialog is open trusts the correct repository. Addresses Codex P2 review comment.
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Summary
Replace the passive trust banner with an interactive confirmation dialog at workspace creation time. When a user creates a workspace for an untrusted project, a modal asks for explicit trust confirmation before proceeding. Adds defense-in-depth trust gates across all workspace creation paths: the primary UI hook, the backend
workspaceService, and thetaskService(sub-agent task spawning).Background
The existing trust system silently skipped hooks for untrusted projects — the user saw "Skipping .mux/init hook (project not trusted)" buried in init logs with no prior warning. This is confusing UX and doesn't enforce the security boundary at the point of action.
Implementation
Frontend: Interactive trust dialog
useCreationWorkspace.ts— Adds a promise-based trust gate inhandleSend. When the project is untrusted, execution pauses viaawait new Promise<boolean>()while aConfirmationModalasks the user to confirm. The storedresolvefunction is invoked on user action (Trust/Cancel).ChatInput/index.tsx— RenderscreationState.trustDialogin the component tree.ProjectPage.tsx— Removes the passiveProjectTrustBanner(replaced by the dialog).ProjectContextis still loading project data, preventing false-positive trust dialogs. The backend gate provides defense-in-depth.apibecomes null during a backend reconnect. TheonConfirmhandler's try/catch handles stale API references gracefully.Backend: Defense-in-depth trust gates
workspaceService.ts—create()andfork()reject with a structured error if the project is untrusted, catching secondary creation paths (slash commands, forking).taskService.ts— Trust gates in bothcreate()(immediate task path) andmaybeStartQueuedTasks()(dequeue path) block sub-agent task workspace creation for untrusted projects, including pre-existing queued tasks from before the gate was added.initHook.ts— Downgrades the "skipping init hook" log to debug since it's now only a defense-in-depth path.Test infrastructure
createSharedRepo(),createAppHarness(), ACP integration tests, smoke test script, and 6 standalone test files now explicitly trust projects before workspace creation.workspaceService.test.tsand trust dialog behavior inuseCreationWorkspace.test.tsx.taskService.test.tsupdated withtrusted: truein all project config mocks.CLI
mux runephemeral config now copies only theprojectsmap withtrustedstate, stripping workspace/task metadata to avoid stale task count interference.Risks
!result.successtoast handlers already surface. No new error display paths needed.taskServicetrust gate blocks sub-agent task spawning for untrusted projects. In upgraded installs with pre-existing workspaces created before this change, any queued tasks for untrusted projects will be silently skipped with a warning log. This is the intended security behavior.Generated with
mux• Model:anthropic:claude-opus-4-6• Thinking:xhigh• Cost:$77.65