How Roo Code Enforces Tool Group Restrictions and File Patterns in Its Mode System
Roo Code uses a mode‑centric permission model that cross‑references mode configurations with tool group memberships, alias resolution, and runtime overrides to enforce strict access controls, while file‑pattern limits are applied per‑call via ripgrep glob arguments.
The Roo Code mode system, as implemented in the RooCodeInc/Roo‑Code repository, provides a granular sandbox for AI assistant capabilities. By defining which tool groups each mode may access and enforcing file pattern restrictions at the tool‑execution layer, the system ensures that agents operate within their intended boundaries.
The Mode-Centric Permission Architecture
Roo Code’s enforcement mechanism rests on a validation pipeline that translates high‑level mode configurations into concrete runtime permissions. The process involves canonical group definitions, alias resolution, and multi‑layered filtering before any tool reaches the LLM context.
Canonical Tool Groups and Schema Definitions
The foundation of the permission model is the toolGroups array defined in the shared types package:
export const toolGroups = ["read", "edit", "command", "mcp", "modes"] as const
This declaration in packages/types/src/tool.ts L07‑L10 establishes the valid group namespaces that modes can request. Each group represents a logical collection of native tools—for example, the edit group contains file‑modifying utilities, while read covers inspection tools.
Expanding Mode Groups to Concrete Tool Lists
When a user selects a mode, the system expands the mode’s configured groups into an explicit list of tool names via getToolsForMode(modeConfig.groups). This expansion occurs in src/core/prompts/tools/filter‑tools‑for‑mode.ts L45‑L46, where group entries (which may be simple strings or tuples with options) are resolved into the full set of tools implied by those groups.
Validating Tools Against Mode Permissions
The core enforcement logic resides in isToolAllowedForMode, which validates whether a specific tool belongs to one of the mode’s enabled groups. During the filtering process in filter‑tools‑for‑mode.ts L48‑L60, the system:
- Iterates over
allToolsForMode. - Resolves any aliases to canonical names.
- Calls
isToolAllowedForMode(implemented insrc/core/tools/validateToolUse.ts) to verify the tool’s group membership against the mode’s whitelist.
If a tool does not belong to an allowed group, it is excluded from the final set.
Alias Resolution Before Validation
To maintain backward compatibility without breaking security boundaries, Roo Code resolves legacy tool names before validation. The ALIAS_TO_CANONICAL map—built from TOOL_ALIASES at module load time in L14‑L22—translates aliases like search_and_replace to their canonical equivalents (e.g., edit).
During the construction of allowedToolNames in L96‑L99, resolveToolAlias ensures that even when an LLM requests a tool by its legacy name, the permission check evaluates against the canonical group membership.
Runtime Overrides and Final Whitelist Construction
After establishing the base tool set, filterNativeToolsForMode applies several conditional filters to produce the final runtime whitelist:
- Model customizations:
applyModelToolCustomizationadds or removes tools based on the specific LLM’s capabilities. - Feature flags: Code like
allowedToolNames.delete("codebase_search")in L71‑L77 removes tools when prerequisite services (such as the code‑index) are unavailable. - User settings: Blocks checking
settings?.disabledTools?.lengthin L94‑L100 prune tools explicitly disabled by the user. - MCP availability: Lines L04‑L07 verify that MCP tools are only included when the MCP hub is active.
The result is a Set<string> of allowedToolNames that represents the definitive boundary of what the assistant may invoke.
File Pattern Enforcement in Search Operations
Beyond group‑level restrictions, Roo Code enforces file‑pattern limits at the individual tool‑call level, particularly for the search_files utility.
The search_files Tool Interface
The search_files tool accepts an optional file_pattern parameter that constrains the search scope:
interface SearchFilesParams {
path: string
regex: string
file_pattern?: string | null // optional glob pattern
}
In src/core/tools/SearchFilesTool.ts L58‑L60, the implementation forwards this parameter unchanged to the underlying search service:
const results = await regexSearchFiles(
task.cwd,
absolutePath,
regex,
filePattern, // forwarded to ripgrep
task.rooIgnoreController
);
Ripgrep Glob Filtering
The actual enforcement occurs in src/services/ripgrep/index.ts. When filePattern is provided, the service converts it into a --glob argument for the rg command:
// Inside ripgrep service, lines L21‑L23 and L157‑L158
const rgArgs = ["--glob", filePattern, ...];
This ensures that even if a mode grants access to search_files, the operation is physically restricted to files matching the glob pattern (for example, **/*.ts limits results to TypeScript files).
Complete Runtime Flow
The enforcement pipeline operates sequentially during mode activation:
- Mode selection: The user selects a mode (or a custom mode is inferred), triggering
filterNativeToolsForModewith the current mode slug, custom definitions, experiment flags, and service states. - Group expansion: Mode groups are expanded to tool lists via
getToolsForMode. - Alias resolution: Tool names are normalized using
ALIAS_TO_CANONICAL. - Permission validation:
isToolAllowedForModefilters the list to only those tools belonging to enabled groups. - Override application: Model customizations, disabled tool lists, and feature flags prune the set further.
- Tool exposure: The resulting array of
OpenAI.Chat.ChatCompletionToolobjects is injected into the LLM context. - Per‑call enforcement: When the assistant invokes
search_files, the optionalfile_patternis validated and passed to ripgrep, which applies the--globfilter at the filesystem level.
Key Implementation Files
packages/types/src/tool.ts: Defines canonicaltoolGroups, tool names, and Zod schemas (L07‑L10).src/core/prompts/tools/filter‑tools‑for‑mode.ts: Orchestrates whitelist construction, alias resolution, and runtime filtering (L45‑L100).src/core/tools/validateToolUse.ts: ProvidesisToolAllowedForModefor group‑membership validation.src/core/tools/SearchFilesTool.ts: Implementssearch_filesand forwards patterns to the ripgrep service (L58‑L60).src/services/ripgrep/index.ts: Executes searches with--globarguments when file patterns are specified (L21‑L23, L157‑L158).
Summary
- Roo Code enforces tool access through a mode‑centric permission model that validates every tool against configurable group memberships.
- The
filterNativeToolsForModefunction insrc/core/prompts/tools/filter‑tools‑for‑mode.tsconstructs the runtime whitelist by expanding mode groups, resolving aliases, and applying model‑specific and user‑specific overrides. - Alias resolution occurs before validation, ensuring legacy tool names are mapped to canonical groups without bypassing restrictions.
- File‑pattern restrictions are enforced at the execution layer; the
search_filestool forwards glob patterns to ripgrep, which filters results via--globarguments. - The entire pipeline ensures that even if an LLM attempts to invoke a restricted tool or access excluded files, the operation is blocked by the mode configuration or the filesystem search boundary.
Frequently Asked Questions
How does filterNativeToolsForMode determine which tools are available?
The function first calls getToolsForMode(modeConfig.groups) to expand the mode’s groups into concrete tool names (L45‑L46). It then iterates over these candidates, uses isToolAllowedForMode to verify group membership (L48‑L60), and applies subsequent filters for disabled tools, model customizations, and MCP availability (L71‑L100). The result is a deduplicated array of tools the LLM is permitted to call.
What happens when a tool alias is used in a mode‑restricted context?
Before validation, the system checks the ALIAS_TO_CANONICAL map (constructed from TOOL_ALIASES at L14‑L22) to resolve the alias to its canonical name. For example, search_and_replace resolves to edit. The permission check then evaluates against the canonical group, ensuring aliases cannot bypass group restrictions while preserving backward compatibility (L96‑L99).
How does Roo Code handle file pattern restrictions in search_files?
The search_files tool accepts an optional file_pattern parameter that is forwarded directly to regexSearchFiles in src/core/tools/SearchFilesTool.ts (L58‑L60). The ripgrep service in src/services/ripgrep/index.ts converts this into a --glob argument for the underlying rg command (L21‑L23), filtering the search to matching paths only.
Can model‑specific customizations override mode‑based tool restrictions?
Yes. After the mode‑based whitelist is constructed, filterNativeToolsForMode invokes applyModelToolCustomization to add or remove tools based on the specific LLM’s capabilities. However, this occurs after the mode group validation, meaning model customizations can only further restrict or supplement the base set; they cannot grant access to tools outside the mode’s allowed groups unless explicitly intended by the broader override logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →