mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-17 09:30:58 -07:00
feat(cli): configure policy engine from existing settings (#8348)
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
export * from './config/config.js';
|
||||
export * from './output/types.js';
|
||||
export * from './output/json-formatter.js';
|
||||
export * from './policy/types.js';
|
||||
export * from './policy/policy-engine.js';
|
||||
|
||||
// Export Core Logic
|
||||
export * from './core/client.js';
|
||||
|
||||
@@ -217,6 +217,75 @@ describe('PolicyEngine', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('MCP server wildcard patterns', () => {
|
||||
it('should match MCP server wildcard patterns', () => {
|
||||
const rules: PolicyRule[] = [
|
||||
{
|
||||
toolName: 'my-server__*',
|
||||
decision: PolicyDecision.ALLOW,
|
||||
priority: 10,
|
||||
},
|
||||
{
|
||||
toolName: 'blocked-server__*',
|
||||
decision: PolicyDecision.DENY,
|
||||
priority: 20,
|
||||
},
|
||||
];
|
||||
|
||||
engine = new PolicyEngine({ rules });
|
||||
|
||||
// Should match my-server tools
|
||||
expect(engine.check({ name: 'my-server__tool1' })).toBe(
|
||||
PolicyDecision.ALLOW,
|
||||
);
|
||||
expect(engine.check({ name: 'my-server__another_tool' })).toBe(
|
||||
PolicyDecision.ALLOW,
|
||||
);
|
||||
|
||||
// Should match blocked-server tools
|
||||
expect(engine.check({ name: 'blocked-server__tool1' })).toBe(
|
||||
PolicyDecision.DENY,
|
||||
);
|
||||
expect(engine.check({ name: 'blocked-server__dangerous' })).toBe(
|
||||
PolicyDecision.DENY,
|
||||
);
|
||||
|
||||
// Should not match other patterns
|
||||
expect(engine.check({ name: 'other-server__tool' })).toBe(
|
||||
PolicyDecision.ASK_USER,
|
||||
);
|
||||
expect(engine.check({ name: 'my-server-tool' })).toBe(
|
||||
PolicyDecision.ASK_USER,
|
||||
); // No __ separator
|
||||
expect(engine.check({ name: 'my-server' })).toBe(PolicyDecision.ASK_USER); // No tool name
|
||||
});
|
||||
|
||||
it('should prioritize specific tool rules over server wildcards', () => {
|
||||
const rules: PolicyRule[] = [
|
||||
{
|
||||
toolName: 'my-server__*',
|
||||
decision: PolicyDecision.ALLOW,
|
||||
priority: 10,
|
||||
},
|
||||
{
|
||||
toolName: 'my-server__dangerous-tool',
|
||||
decision: PolicyDecision.DENY,
|
||||
priority: 20,
|
||||
},
|
||||
];
|
||||
|
||||
engine = new PolicyEngine({ rules });
|
||||
|
||||
// Specific tool deny should override server allow
|
||||
expect(engine.check({ name: 'my-server__dangerous-tool' })).toBe(
|
||||
PolicyDecision.DENY,
|
||||
);
|
||||
expect(engine.check({ name: 'my-server__safe-tool' })).toBe(
|
||||
PolicyDecision.ALLOW,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('complex scenarios', () => {
|
||||
it('should handle multiple matching rules with different priorities', () => {
|
||||
const rules: PolicyRule[] = [
|
||||
|
||||
@@ -18,8 +18,16 @@ function ruleMatches(
|
||||
stringifiedArgs: string | undefined,
|
||||
): boolean {
|
||||
// Check tool name if specified
|
||||
if (rule.toolName && toolCall.name !== rule.toolName) {
|
||||
return false;
|
||||
if (rule.toolName) {
|
||||
// Support wildcard patterns: "serverName__*" matches "serverName__anyTool"
|
||||
if (rule.toolName.endsWith('__*')) {
|
||||
const prefix = rule.toolName.slice(0, -3); // Remove "__*"
|
||||
if (!toolCall.name || !toolCall.name.startsWith(prefix + '__')) {
|
||||
return false;
|
||||
}
|
||||
} else if (toolCall.name !== rule.toolName) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check args pattern if specified
|
||||
|
||||
Reference in New Issue
Block a user