Tool Security Reference
This page is the authoritative reference for which SDK built-in tools an agent can use, how path sandboxing works, and how permissions are auto-derived from an agent's configuration. For the mechanism that enforces all of this, see Architecture → Tool Security.
This page covers SDK built-in tools only - the filesystem / web / interactive tools the Copilot SDK ships with.
MCP tools (Pimcore PHP tools, third-party MCP servers) are governed by Pimcore user permissions via cookie forwarding.
Which MCP groups an agent can see is controlled by pimcoreMcpServers / pimcoreMetaGroups - see MCP Servers.
What tools does an agent get?
Four categories - enabled by default, opt-in, always blocked, SDK-managed. The agent's YAML only touches opt-in tools; everything else is policy.
Enabled by default
Every agent automatically has these tools. No configuration needed.
| Tool | What it does |
|---|---|
view | Read file contents (path-sandboxed) |
grep | Search file contents (path-sandboxed) |
glob | Match files by pattern (path-sandboxed) |
skill | Loads skill content into the agent's system context |
report_intent | SDK-internal - declares the agent's intended action |
fetch_copilot_cli_documentation | SDK-internal - documentation lookup |
skillmust remain enabled. The SDK uses this tool to inject skill content into the system message. Excluding it silently disablesskillDirectories- no skill content reaches the agent and no error is raised. The agent-server keepsskillinALWAYS_ACTIVE_TOOLS; removing it will break skill loading.
Opt-in via includeSdkTools
These are disabled by default. Enable them per agent in the YAML config.
| Tool | What it does | Notes |
|---|---|---|
create | Create new files on disk | Path-sandboxed. Enabling auto-approves the write permission. |
edit | Edit existing files with diffs | Path-sandboxed. Enabling auto-approves the write permission. |
web_fetch | Fetch a URL and return content as markdown | Enabling auto-approves the url permission. |
ask_user | Interactively ask the user a question mid-turn | See Features → Interactive Input. |
Example:
includeSdkTools:
- web_fetch
- ask_user
Listing a default tool (view, grep, glob) is harmless but
unnecessary - they are already enabled.
Task-session ask_user exclusion
ask_user is force-excluded from every turn of a headless agent task,
even for an agent that lists it under includeSdkTools. This is applied server-side from the session's origin
column, not something an agent configuration can opt back into for its own task runs - an unattended task has no
human to answer a mid-turn question. See
Architecture → Tool Security → Task-session tool overrides.
Always blocked
These tools are denied unconditionally at the runtime hook level. Even if the LLM hallucinates a call to them, the call is rejected before it reaches the SDK with "This tool is not available in the agent environment".
| Tool | Why blocked |
|---|---|
bash | Shell command execution |
list_bash | List interactive bash sessions |
read_bash | Read from an interactive bash session |
write_bash | Write to an interactive bash session |
stop_bash | Stop an interactive bash session |
task | Spawns sub-agents that would bypass tool restrictions |
All denials are audit-logged via logger.audit() with the tool name,
session id, and request kind - searchable from the structured log
stream.
SDK-managed (cannot be controlled)
Some tools are injected internally by the SDK and are always available. They are not returned by the tool list API and cannot be disabled through agent configuration.
| Tool | What it does |
|---|---|
sql | Per-session SQLite scratch database (with todos / todo_deps tables) |
Auto-derived permissions
Agent configurations do not have a permissions field. The
agent-server auto-derives the SDK permission set from the resolved
config - no manual listing needed.
| Kind | Approved when |
|---|---|
read | Always approved (default read tools are always on) |
mcp | The agent has any MCP server (mcpServers, pimcoreMcpServers, or pimcoreMetaGroups) |
url | web_fetch is listed in includeSdkTools |
write | create or edit is listed in includeSdkTools |
shell | Never approved. The PreToolUseHook blocks every shell tool unconditionally |
Execution user and information disclosure
Agent configurations can optionally set executionUser, a Pimcore username the whole session runs as instead of the
chat initiator. Full field reference: Configuration → Agents → Execution user.
Resolution mechanism: Architecture → Authentication → Execution user resolution.
| Aspect | Behavior |
|---|---|
| Who can set it | Administrators only. The server rejects a changed value coming from a non-admin request. |
| Studio visibility | Non-admins see the field read only on the agent's General tab; Pimcore Studio shows a warning next to it once it carries a value. |
| Unresolvable value | Session creation fails with an error, no silent fallback to the initiator (fail closed). |
| Session ownership | Stays with the initiator; only the acting identity changes. |
Security implication: the execution user can hold more permissions than the users who chat with the agent.
Because the agent acts as the execution user, its responses (and any HITL proposal it creates) can surface
information - object content, listings, search results, proposed values - that the chatting users cannot access
directly. Recommended mitigation: combine an execution user with the agent's own
run permission so only an intended audience can start sessions with that agent.
See Architecture → Tool Security → Execution user and information disclosure for the mechanism behind this table.
Path sandboxing
File-system tools (view, grep, glob, create, edit) are restricted to two per-session directories:
/app/uploads/{chatSessionId}/uploaded/ ← user-uploaded files
/app/uploads/{chatSessionId}/staged/ ← staged Pimcore asset copies
A tool call with a path outside these directories is denied with "Access denied: path is outside the allowed scope". For the pre-tool-use hook that enforces this, see Architecture → Tool Security.
Read-only path: /tmp/
When an MCP tool returns a response larger than ~30 KB, the Copilot SDK writes the full output to a temp file in
/tmp/ and tells the LLM to use view or grep to read it. /tmp/ is a read-only path with tighter restrictions
than the session sandbox:
| Tool | Specific file (e.g. /tmp/123-copilot-tool-output-abc.txt) | Directory (/tmp/) |
|---|---|---|
view | allowed | denied |
grep | allowed | denied |
glob | denied | denied |
create/edit | denied | denied |
view and grep can read a specific file by exact path but cannot target the directory itself - a directory listing
could expose temp files from other sessions and a recursive grep could leak their contents. glob is always denied on
read-only paths.
Startup validation
On startup (deferred 5 seconds to let the SDK initialize) and on every
admin reload, the agent-server validates every agent's
includeSdkTools entries. Warnings are logged when:
- A tool name is not in the valid configurable set (
view,grep,glob,create,edit,web_fetch,ask_user). - A tool name is not found in the current SDK's tool list.
Inspect validation results manually:
curl -X POST \
-H "Authorization: Bearer $AGENT_SERVER_ADMIN_TOKEN" \
http://localhost/agent-server/api/admin/reload-agents
The response includes a toolWarnings array alongside any
modelWarnings.