Skip to content

feat: merge skill-level sandbox policy for shell commands in zsh fork mode#11676

Closed
celia-oai wants to merge 1 commit intomainfrom
dev/cc/skill-sandbox
Closed

feat: merge skill-level sandbox policy for shell commands in zsh fork mode#11676
celia-oai wants to merge 1 commit intomainfrom
dev/cc/skill-sandbox

Conversation

@celia-oai
Copy link
Collaborator

@celia-oai celia-oai commented Feb 13, 2026

Summary

This change ensures shell command execution honors skill-level permissions for zsh-fork command flows
when the invoked executable is inside a skill’s scripts directory.

  • Skill-aware sandbox extension is applied only in shell_zsh_fork mode.
  • Turn-level and skill-level sandbox rules are merged into a single least-privilege effective policy.
  • The effective policy is used consistently for both approval checks and execution in the shell path.

A follow-up PR will wire skill-level seatbelt_permissions.

Skill Sandbox Extension Test Plan

  1. Create demo files and directories.
  cd /Users/celia/code/codex
  bash .tmp/skill-sandbox-demo/setup_demo.sh
  1. Configure skill permissions as read-only.
  # /Users/celia/code/codex/.agents/skills/sandbox-approval-demo/agents/openai.yaml
  permissions:
    network: true
    file_system:
      read:
        - "./workspace"
  1. Set and verify custom interceptable zsh.
  INTERCEPTABLE_ZSH=/Users/celia/.local/codex-zsh-77045ef/bin/zsh
  "$INTERCEPTABLE_ZSH" -fc '/usr/bin/true'
  EXEC_WRAPPER=/usr/bin/false "$INTERCEPTABLE_ZSH" -fc '/usr/bin/true'  # should fail if intercept works
  1. Build binaries used by the test.
  cd /Users/celia/code/codex/codex-rs
  cargo build -p codex -p codex-app-server-test-client
  1. Clean test artifacts.
  cd /Users/celia/code/codex
  rm -f .agents/skills/sandbox-approval-demo/workspace/runs.log
  rm -f .tmp/skill-sandbox-demo/should_be_blocked.txt
  rm -f .tmp/skill-sandbox-demo/should_be_allowed.txt
  1. Baseline: zsh fork disabled.
  cd /Users/celia/code/codex/codex-rs
  cargo run -p codex-app-server-test-client -- \
    --codex-bin ./target/debug/codex \
    --config 'features.shell_zsh_fork=false' \
    --config 'approval_policy="on-request"' \
    --config 'sandbox_mode="danger-full-access"' \
    --skill-name sandbox-approval-demo \
    --skill-path ../.agents/skills/sandbox-approval-demo/SKILL.md \
    send-message-v2 'Run this: ../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_allowed > ../.tmp/skill-sandbox-demo/should_be_allowed.txt'

Expected:

  • Command runs successfully.
  • ../.tmp/skill-sandbox-demo/should_be_allowed.txt is created.
  • No skill sandbox extension behavior is expected in this control path.
  1. Main test: zsh fork enabled, skill sandbox enforced (custom interceptable zsh).
  cd /Users/celia/code/codex/codex-rs
  cargo run -p codex-app-server-test-client -- \
    --codex-bin ./target/debug/codex \
    --config 'features.shell_zsh_fork=true' \
    --config "zsh_path=\"$INTERCEPTABLE_ZSH\"" \
    --config 'approval_policy="on-request"' \
    --config 'sandbox_mode="danger-full-access"' \
    --skill-name sandbox-approval-demo \
    --skill-path ../.agents/skills/sandbox-approval-demo/SKILL.md \
    send-message-v2 'Run this: ../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_blocked > ../.tmp/skill-sandbox-demo/should_be_blocked.txt'

Expected:

  • Approval is requested consistently before execution like this:
< {
<   "id": 0,
<   "method": "item/commandExecution/requestApproval",
<   "params": {
<     "command": "/bin/zsh -lc '../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_blocked > ../.tmp/skill-sandbox-demo/should_be_blocked.txt'",
<     "commandActions": [
<       {
<         "command": "../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_blocked > ../.tmp/skill-sandbox-demo/should_be_blocked.txt",
<         "type": "unknown"
<       }
<     ],
<     "cwd": "/Users/celia/code/codex/codex-rs",
<     "itemId": "call_2FcXvhGx8ci3XlYQTxDufZus",
<     "proposedExecpolicyAmendment": [
<       "/bin/zsh",
<       "-lc",
<       "../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_blocked > ../.tmp/skill-sandbox-demo/should_be_blocked.txt"
<     ],
<     "reason": "Do you want me to run your exact sandbox-approval demo command, including the chained write probe, once as requested?",
<     "threadId": "019c7756-81d5-7df0-aa87-df35dacf7728",
<     "turnId": "019c7756-820b-7220-a90c-a128443f691b"
<   }
< }
  • Approval request command is "$INTERCEPTABLE_ZSH" -lc ... and references the full command string.
  • If approval is declined, command does not execute and should_be_blocked.txt is not created.
  • If approval is accepted, command may execute successfully (this test is about approval gating, not deny-on-execute).
  • when click "always allow", this is written to the rules:
prefix_rule(pattern=["/bin/zsh", "-lc", "../.agents/skills/sandbox-approval-demo/scripts/skill_action.sh && echo should_be_blocked > ../.tmp/skill-sandbox-demo/should_be_blocked.txt"], decision="allow")
  1. Control: non-skill script with zsh fork enabled (custom interceptable zsh).
  cd /Users/celia/code/codex/codex-rs
  cargo run -p codex-app-server-test-client -- \
    --codex-bin ./target/debug/codex \
    --config 'features.shell_zsh_fork=true' \
    --config "zsh_path=\"$INTERCEPTABLE_ZSH\"" \
    --config 'approval_policy="on-request"' \
    --config 'sandbox_mode="danger-full-access"' \
    send-message-v2 'Run this: ../.tmp/skill-sandbox-demo/non_skill_action.sh && echo control_ok > ../.tmp/skill-sandbox-demo/should_be_allowed.txt'

Expected:

  • Command succeeds.
  • ../.tmp/skill-sandbox-demo/should_be_allowed.txt is created.
  • No skill-based approval behavior should be applied.

@celia-oai celia-oai changed the base branch from main to dev/cc/skill-permission February 13, 2026 02:03
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch from 92d0ea1 to 31a7a02 Compare February 13, 2026 02:09
@celia-oai celia-oai force-pushed the dev/cc/skill-permission branch 10 times, most recently from 7ba60dc to e94cead Compare February 13, 2026 22:51
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch 2 times, most recently from ee7b61f to 38138ce Compare February 14, 2026 00:16
@celia-oai celia-oai force-pushed the dev/cc/skill-permission branch from 5d0fe77 to a48a3cd Compare February 14, 2026 00:27
Base automatically changed from dev/cc/skill-permission to main February 14, 2026 01:43
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch 3 times, most recently from b31f5c2 to 37047c8 Compare February 17, 2026 23:49
@celia-oai celia-oai changed the title Dev/cc/skill sandbox feat: apply skill-level sandbox policy merging for shell/unified exec commands Feb 17, 2026
@celia-oai celia-oai marked this pull request as ready for review February 18, 2026 00:55
@celia-oai celia-oai marked this pull request as draft February 18, 2026 01:23
@celia-oai celia-oai closed this Feb 18, 2026
@celia-oai celia-oai reopened this Feb 18, 2026
@celia-oai celia-oai changed the title feat: apply skill-level sandbox policy merging for shell/unified exec commands feat: apply skill-level sandbox policy merging for shell/unified exec zsh commands for skill executables Feb 18, 2026
@celia-oai celia-oai changed the title feat: apply skill-level sandbox policy merging for shell/unified exec zsh commands for skill executables feat: merge skill-level sandbox policy for shell/unified exec zsh commands in skill/script directories Feb 18, 2026
@celia-oai celia-oai changed the title feat: merge skill-level sandbox policy for shell/unified exec zsh commands in skill/script directories feat: merge skill-level sandbox policy for shell/unified exec zsh commands in skill's scripts directories Feb 18, 2026
@celia-oai celia-oai marked this pull request as ready for review February 18, 2026 05:30
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch from 6cea73c to 4112ef0 Compare February 19, 2026 00:45
@celia-oai celia-oai changed the title feat: merge skill-level sandbox policy for shell/unified exec zsh commands in skill's scripts directories feat: merge skill-level sandbox policy for shell zsh fork commands Feb 19, 2026
@celia-oai celia-oai changed the title feat: merge skill-level sandbox policy for shell zsh fork commands feat: merge skill-level sandbox policy for shell commands in zsh fork mode Feb 19, 2026
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch 3 times, most recently from d6670e9 to db8098b Compare February 19, 2026 23:21
@celia-oai celia-oai force-pushed the dev/cc/skill-sandbox branch from db8098b to fef532c Compare February 19, 2026 23:28
@celia-oai celia-oai closed this Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant