mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-18 18:11:02 -07:00
184 lines
5.0 KiB
TypeScript
184 lines
5.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import {
|
|
type PolicyEngineConfig,
|
|
PolicyDecision,
|
|
type PolicyRule,
|
|
ApprovalMode,
|
|
// Read-only tools
|
|
GlobTool,
|
|
GrepTool,
|
|
LSTool,
|
|
ReadFileTool,
|
|
ReadManyFilesTool,
|
|
RipGrepTool,
|
|
// Write tools
|
|
EditTool,
|
|
MemoryTool,
|
|
ShellTool,
|
|
WRITE_FILE_TOOL_NAME,
|
|
WebFetchTool,
|
|
WebSearchTool,
|
|
} from '@google/gemini-cli-core';
|
|
import type { Settings } from './settings.js';
|
|
|
|
// READ_ONLY_TOOLS is a list of built-in tools that do not modify the user's
|
|
// files or system state.
|
|
const READ_ONLY_TOOLS = new Set([
|
|
GlobTool.Name,
|
|
GrepTool.Name,
|
|
RipGrepTool.Name,
|
|
LSTool.Name,
|
|
ReadFileTool.Name,
|
|
ReadManyFilesTool.Name,
|
|
WebSearchTool.Name,
|
|
]);
|
|
|
|
// WRITE_TOOLS is a list of built-in tools that can modify the user's files or
|
|
// system state. These tools have a shouldConfirmExecute method.
|
|
// We are keeping this here for visibility and to maintain backwards compatibility
|
|
// with the existing tool permissions system. Eventually we'll remove this and
|
|
// any tool that isn't read only will require a confirmation unless altered by
|
|
// config and policy.
|
|
const WRITE_TOOLS = new Set([
|
|
EditTool.Name,
|
|
MemoryTool.Name,
|
|
ShellTool.Name,
|
|
WRITE_FILE_TOOL_NAME,
|
|
WebFetchTool.Name,
|
|
]);
|
|
|
|
export function createPolicyEngineConfig(
|
|
settings: Settings,
|
|
approvalMode: ApprovalMode,
|
|
): PolicyEngineConfig {
|
|
const rules: PolicyRule[] = [];
|
|
|
|
// Priority system for policy rules:
|
|
// - Higher priority numbers win over lower priority numbers
|
|
// - When multiple rules match, the highest priority rule is applied
|
|
// - Rules are evaluated in order of priority (highest first)
|
|
//
|
|
// Priority levels used in this configuration:
|
|
// 0: Default allow-all (YOLO mode only)
|
|
// 10: Write tools default to ASK_USER
|
|
// 50: Auto-accept read-only tools
|
|
// 85: MCP servers allowed list
|
|
// 90: MCP servers with trust=true
|
|
// 100: Explicitly allowed individual tools
|
|
// 195: Explicitly excluded MCP servers
|
|
// 200: Explicitly excluded individual tools (highest priority)
|
|
|
|
// MCP servers that are explicitly allowed in settings.mcp.allowed
|
|
// Priority: 85 (lower than trusted servers)
|
|
if (settings.mcp?.allowed) {
|
|
for (const serverName of settings.mcp.allowed) {
|
|
rules.push({
|
|
toolName: `${serverName}__*`,
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 85,
|
|
});
|
|
}
|
|
}
|
|
|
|
// MCP servers that are trusted in the settings.
|
|
// Priority: 90 (higher than general allowed servers but lower than explicit tool allows)
|
|
if (settings.mcpServers) {
|
|
for (const [serverName, serverConfig] of Object.entries(
|
|
settings.mcpServers,
|
|
)) {
|
|
if (serverConfig.trust) {
|
|
// Trust all tools from this MCP server
|
|
// Using pattern matching for MCP tool names which are formatted as "serverName__toolName"
|
|
rules.push({
|
|
toolName: `${serverName}__*`,
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 90,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tools that are explicitly allowed in the settings.
|
|
// Priority: 100
|
|
if (settings.tools?.allowed) {
|
|
for (const tool of settings.tools.allowed) {
|
|
rules.push({
|
|
toolName: tool,
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 100,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Tools that are explicitly excluded in the settings.
|
|
// Priority: 200
|
|
if (settings.tools?.exclude) {
|
|
for (const tool of settings.tools.exclude) {
|
|
rules.push({
|
|
toolName: tool,
|
|
decision: PolicyDecision.DENY,
|
|
priority: 200,
|
|
});
|
|
}
|
|
}
|
|
|
|
// MCP servers that are explicitly excluded in settings.mcp.excluded
|
|
// Priority: 195 (high priority to block servers)
|
|
if (settings.mcp?.excluded) {
|
|
for (const serverName of settings.mcp.excluded) {
|
|
rules.push({
|
|
toolName: `${serverName}__*`,
|
|
decision: PolicyDecision.DENY,
|
|
priority: 195,
|
|
});
|
|
}
|
|
}
|
|
|
|
// If auto-accept is enabled, allow all read-only tools.
|
|
// Priority: 50
|
|
if (settings.tools?.autoAccept) {
|
|
for (const tool of READ_ONLY_TOOLS) {
|
|
rules.push({
|
|
toolName: tool,
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 50,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Only add write tool rules if not in YOLO mode
|
|
// In YOLO mode, the wildcard ALLOW rule handles everything
|
|
if (approvalMode !== ApprovalMode.YOLO) {
|
|
for (const tool of WRITE_TOOLS) {
|
|
rules.push({
|
|
toolName: tool,
|
|
decision: PolicyDecision.ASK_USER,
|
|
priority: 10,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (approvalMode === ApprovalMode.YOLO) {
|
|
rules.push({
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 0, // Lowest priority - catches everything not explicitly configured
|
|
});
|
|
} else if (approvalMode === ApprovalMode.AUTO_EDIT) {
|
|
rules.push({
|
|
toolName: EditTool.Name,
|
|
decision: PolicyDecision.ALLOW,
|
|
priority: 15, // Higher than write tools (10) to override ASK_USER
|
|
});
|
|
}
|
|
|
|
return {
|
|
rules,
|
|
defaultDecision: PolicyDecision.ASK_USER,
|
|
};
|
|
}
|