Agents and security

Providers and security

Models and providers

phax can run a phase with Claude Code, OpenAI Codex or Mistral Vibe. A plan asks for a model and an effort; the routing layer maps them to a provider that has them, following providerPriority in ~/.phax/model-routing.json (mistral-vibe, codex-cli, then claude-code by default). Vibe and Codex are disabled until you enable them, so a fresh install runs everything with Claude Code.

phax agent models                                    # the routing table and the provider priority
phax agent resolve --model claude-sonnet-5 --effort medium   # where a request would go
phax agent probe                                     # which provider CLIs are installed
phax agent setup providers --write                   # enable the providers that are installed
phax agent setup mistral-vibe --install-model-aliases   # add phax's model aliases to Vibe

docs/model-routing.md explains how a request is resolved, and the model catalog lists the models phax knows.

Security modes

Every run has a security mode, from security.profile in phax.json or --security:

ModeWhat the agent can do
secureDefault. The provider's own sandbox: files limited to the worktree, network as network.profile allows where the provider can enforce it, no MCP.
unsafeAnything on your machine. phax warns you. For plans you trust.
isolatedAn external sandbox. Planned, refused today.

Providers differ: Claude Code and Codex jail the filesystem; Vibe only partly, so a secure run skips it and falls back to Claude Code. No provider filters network by domain, and only Codex can cut a phase's network off. The mode a phase actually ran with is in its security.json. phax security status shows what each installed provider can enforce.

The agent can run your gate commands and the commands in security.agentCommands, and nothing else where the provider supports an allowlist. The phax binary has no network permission of its own: what reaches the network (an agent, git push, gh) is a program it starts. And phax never builds a shell command from your data: every command it runs gets its arguments one by one. docs/security.md has the details.