Skip to content
Crystal CodeDocs
ENEnglish

Safety

Every model-generated tool call is classified, then decided by ApprovalPolicy (Crystal.Tools.ToolInvocationPolicy). Side effects are not invoked by bypassing that executor.

Risk is read, write, privileged, or forbidden. Authority is workspace, outside_workspace, network, or privileged_escalation.

A call passes without review only when all of these hold:

  • The classification does not require a prompt.
  • Risk is not Forbidden or Privileged.
  • Authority is Workspace.
  • The tool is in the automatic-tool set, or risk is Read, or risk is Write and the approval mode allows that write.
Mode What auto-passes
Full Any Workspace write that cleared the checks above, including an external tool that stays Write + Workspace. Bash, bash_start, and bash_stop only when they classified as Workspace write
Edit, Review Built-in write and edit only
Default No writes

A network, privileged, or forbidden command does not auto-pass. Forbidden, Privileged, outside-workspace, and network authority never fully auto-pass. A reusable grant is skipped when the classification does not allow one.

Review can allow a call. A Forbidden classification or a required prompt still falls back to you. A reviewer Allow of Forbidden does not execute.

An unknown tool name, including one no plugin classifier claims, is Privileged with PrivilegedEscalation and the summary Unknown tool.

A path is a credential path when any segment is .ssh or .gnupg (case-insensitive), or a .crystal segment is immediately followed by credentials.json. ~ is expanded first. The check runs on the argument and again on the resolved full path.

Those paths are Forbidden / PrivilegedEscalation for read, list, tree, glob, grep, search, describe_image, view_image, write, and edit. Directory walks skip a file whose resolved target is a credential path. Session directory rules cannot grant one. Export refuses one.

A missing or unparsable path does not become Forbidden. A required path that cannot be read is a workspace read. A write or edit whose path cannot be parsed, or that the workspace cannot normalize, is a workspace write. A path that normalizes outside the accessible session directories is Read or Write with OutsideWorkspace. That does not auto-pass.

bash and bash_start use the same classifier. Matching is case-insensitive. A match that takes more than one second is treated as a hit, so a timeout fails closed.

Class Pattern Risk Authority
Forbidden \bsudo\b forbidden privileged_escalation
Forbidden rm with both recursive and force flags, aimed at /, ~, $HOME, or ${HOME} forbidden privileged_escalation
Forbidden curl or wget piped to sh or bash forbidden privileged_escalation
Forbidden git push with -f or --force forbidden privileged_escalation
Forbidden a .ssh, .gnupg, or .crystal/credentials.json path in the command text forbidden privileged_escalation
Privileged chmod 777, chown, mkfs, dd , kill -9, shutdown, reboot privileged privileged_escalation
Network curl, wget, ssh, scp, nc, nmap when not already forbidden write network
Other any other non-empty command write workspace

Forbidden is tested first, then privileged, then network. A command that matches nothing, or that cannot be read from the arguments, is a workspace write named Workspace shell command.

bash_status and bash_logs are workspace reads (Read background shell task). bash_stop is a workspace write (Stop background shell task) and is not re-classified from the command string.

  • A workspace tool that may not leave the root rejects a path that leaves it. A readable tool may resolve an outside path, then classify it as OutsideWorkspace.
  • A write or edit into a read-only session directory is rejected before classification: Writing to a read-only session directory is not allowed. Change its access with /access.
  • In Plan, edit, write, bash, bash_start, and bash_stop are rejected before classification: Plan mode does not allow <name>.
  • Plugin hooks may raise approval risk. They cannot lower it. A raw hook is not held to that limit and is named at load. See Plugins.
  • Runtime text is plain English. No emoji in exceptions, logs, or UI chrome.
  • Secrets must not appear in source, logs, diagnostics, or commits. credentials.json is owner read/write on Unix (0600). Windows leaves the file ACL unchanged.