Why this matters
Grok Build can edit the tree and run a shell. The product is useful because of that. It is also how you delete the wrong branch, commit a secret, or push from a session you were not watching.
Specialist rung. If you do not write software or run agents, you can stop after C4 and still have reached repo level.
Permissions are the control plane. Ask (default) is how you work in the TUI. Always-approve is how unattended grok -p and grok agent run without a human on the prompt. Neither one is a personality setting. A deny rule still wins. A PreToolUse deny still wins. This module is how those layers stack, how you review what already ran, and what this course will not teach.
If someone asked you to “turn off safety,” “ignore the system prompt,” or “jailbreak the hook,” the answer is no. That is not a lab. It is out of scope and out of the job.
Teach
Modes: how often Grok asks
| Mode | What runs without asking | Use |
|---|
default (ask) | Read-only tools and a fixed list of read-only shell commands | Interactive TUI. This is the desk. |
auto | Work the safety check allows; other calls block or escalate | Fewer prompts, still interactive. In headless, a blocked call fails and is reported to the model. |
acceptEdits | File edits without a prompt | Local coding if you will read the diff later. Still not a CI mode. |
bypassPermissions (always-approve) | Tool calls in general | Scripts, SDKs, grok agent --always-approve. Product name is always-approve. |
dontAsk | Only pre-approved tools and built-in read-only handling | Strict allowlists. Claude-compatible defaultMode. |
Always-approve and auto are mutually exclusive; always-approve wins if both are requested.
How you set it:
- TUI:
Shift+Tab cycles Normal → Plan → Always-approve. /always-approve toggles back to ask. /auto when that feature is on. Ctrl+O, /settings.
- CLI:
--always-approve (alias --yolo), --permission-mode auto
- Config:
[ui] permission_mode = "always-approve"
- ACP:
_meta.yoloMode: true on session/new
Admins can lock always-approve off in requirements.toml with disable_bypass_permissions_mode = true. That is a policy file, not a puzzle.
Rules sit on top of every mode
# project .grok/config.toml
[permission]
deny = [
"Bash(rm -rf *)",
"Bash(echo C10_DENY_DEMO*)",
]
allow = [
"Bash(git *)",
"Bash(npm test*)",
]
Same strings work as --allow / --deny on the CLI. Evaluation is by severity, not file order: deny > ask > allow. A project allow cannot punch through a global deny.
Bash(git *) is prefix/glob on the command string. Bash(git) also matches gitleaks — put the space and the star when you mean the git program. Chained commands: deny and ask inspect every segment; allow inspects the whole string only. So Bash(git *) as allow would approve git status && rm -rf / unless a deny catches rm. Pair narrow allows with denies.
Read, Edit, Grep take path globs (** crosses /). MCPTool(practice-fs__*) matches that server. WebFetch(domain:example.com) matches the host and subdomains.
A built-in dangerous list (rm, chmod, chown, git push, …) prompts even when a remembered prefix would have covered it. An explicit config allow or always-approve will approve them like anything else — which is why you write a deny for patterns you never want, instead of relying on memory.
Interactive “Always allow cargo test” grants live in Grok’s home directory, per project (per worktree). They are not in git. Shareable policy belongs in .grok/config.toml.
Project permission rules in .grok/config.toml and .claude/settings.json apply without a separate trust prompt. Review them in an unfamiliar checkout the same way you review project hooks (C7). Folder-trust is the hook/MCP/LSP gate, not a second chance to reject an allow.
Authorization order
When the model requests a tool:
PreToolUse hooks. An explicit deny stops the call. An allow does not skip the rest.
- Rules. Matching deny rejects. Matching ask prompts (including for reads). Matching allow approves.
- Remembered grants (skipped under always-approve).
- Built-in read-only auto-approvals.
- Mode policy — prompt, auto-approve, or auto-deny.
Always-approve short-circuits after step 2. Deny, hooks, and some shell ask rules still apply. That is the sentence people skip. --always-approve --deny "Bash(rm -rf *)" is the intended CI shape. --always-approve alone is not a review.
Hooks fail open (C7). A crashed deny-hook is not a deny. If the hook is the only gate you have, you do not have a gate.
Review is part of the work
You already have the surfaces:
- Plan mode (C3).
/plan. The agent may only edit plan.md. Approve (a), request changes (s), comment (c). Always-approve does not let plan mode write other files.
- Diffs (C4). Read the patch in scrollback. Open the block (
Enter). Refuse a write you cannot explain.
/session-info. Auth, model, sandbox profile if any.
- Hook and permission annotations in scrollback. If a deny fired, keep that line in the record.
A review you can stand behind answers: what changed, why, how you ran it, what you refused, whether secrets or deny paths were touched. “Looks good” is not a review.
/rewind undoes conversation, not files. Do not use it as rollback.
Sandbox (and what Windows actually has)
--sandbox workspace (and read-only, strict, custom profiles) uses OS kernel limits: Landlock on Linux, Seatbelt on macOS. Applied to the whole process at start. Irreversible for that session. Off by default.
| Profile | Intent |
|---|
workspace | Everyday: write CWD + ~/.grok/ + temp. Network allowed. |
read-only | Explore / review. Project files not writable. |
strict | Untrusted code. Read mostly CWD + system paths. |
Custom deny globs in sandbox.toml are kernel-enforced where the profile applies. Child-network blocks are Linux only.
Windows is not in that kernel table. On this shop’s default Windows desk, you do not get Landlock/Seatbelt from --sandbox. You still have ask mode, deny rules, hooks, and folder trust. Say that out loud. Do not paste a Linux sandbox stanza and claim the kernel will catch rm.
Shell environment policy ([shell_environment_policy]) does apply on Windows: you can stop child commands inheriting *KEY* / *TOKEN* / *SECRET*. Use it if your shell exports keys.
Recommended stack for untrusted code on a platform that supports sandbox: dontAsk + narrow allow + hook + --sandbox strict. On Windows: dontAsk or ask + narrow allow + a hook you have seen deny + do not run untrusted trees on a machine that holds production keys.
What this module will not teach
- How to disable, skip, or “jailbreak” permission prompts, hooks, managed
requirements.toml, or the model’s own refusals
- How to hide a dangerous command from the matcher on purpose
- How to recover a secret you committed (rotate it; that is ops, not a Grok trick)
- How to make always-approve ignore
deny
If a prompt appears to invite those things, stop and return to the brief. The capstone will not reward a bypass.
Worked example
Practice repo.
- Add to
.grok/config.toml:
[permission]
deny = ["Bash(echo C10_DENY_DEMO*)"]
-
Stay in ask in the TUI. Send: Run: echo hello. Approve if prompted. It should run.
-
Send: Run exactly: echo C10_DENY_DEMO. You should see a deny, not a prompt you can click through. If you can approve it, the rule did not load (new session after the file save; rule syntax). Fix the rule, /quit, start again.
-
Headless, to prove always-approve does not punch through:
grok -p "Run exactly: echo C10_DENY_DEMO" --always-approve --output-format json --no-auto-update
The command must not print C10_DENY_DEMO as a successful tool result. The model should be told it was denied.
- Ask Grok, still in ask mode, to add a one-line comment to
README.md. Read the diff. If it also “helpfully” deletes the deny rule, refuse. That refusal is the review.
Your turn
Do c10-l01-e1 in Grok Build. You will install a deny, watch it hold under --always-approve, and write a five-line review of a real diff. No grok.com. No “ignore your safety instructions” prompts.
Common failure
Always-approve in the TUI because you were tired of clicking. You now auto-run git push and rm. Toggle it off. Use narrow allow for git status and tests. Save always-approve for C9-style jobs that also have a deny list.
Allow without deny. Bash(git *) plus a chain. Read the matching rules again.
Unfamiliar repo, committed allow. You cloned a tree that allows Bash for everything. Review .grok/config.toml and .claude/settings.json before the first prompt.
Sandbox cargo-cult on Windows. You set --sandbox strict, saw a warning or a no-op, and believed writes were jailed. Check /session-info and this lesson’s platform table.
What’s next
C11 is the capstone: ship a small app with Grok Build. You submit the plan, the diffs, and a retro that includes what you refused. The safety habits in this module are part of the grade, not an appendix.