feat(policy): add source tracking to policy rules (#16670)

This commit is contained in:
Allen Hutchison
2026-01-15 08:06:07 -08:00
committed by GitHub
parent fa3981990c
commit f909c9ef90
6 changed files with 25 additions and 1 deletions

View File

@@ -72,6 +72,7 @@ describe('policiesCommand', () => {
{
decision: PolicyDecision.ALLOW,
argsPattern: /safe/,
source: 'test.toml',
},
{
decision: PolicyDecision.ASK_USER,
@@ -101,7 +102,9 @@ describe('policiesCommand', () => {
expect(content).toContain(
'1. **DENY** tool: `dangerousTool` [Priority: 10]',
);
expect(content).toContain('2. **ALLOW** all tools (args match: `safe`)');
expect(content).toContain(
'2. **ALLOW** all tools (args match: `safe`) [Source: `test.toml`]',
);
expect(content).toContain('3. **ASK_USER** all tools');
});
});

View File

@@ -53,6 +53,9 @@ const listPoliciesCommand: SlashCommand = {
if (rule.priority !== undefined) {
content += ` [Priority: ${rule.priority}]`;
}
if (rule.source) {
content += ` [Source: \`${rule.source}\`]`;
}
content += '\n';
});

View File

@@ -174,6 +174,7 @@ export async function createPolicyEngineConfig(
toolName: `${serverName}__*`,
decision: PolicyDecision.DENY,
priority: 2.9,
source: 'Settings (MCP Excluded)',
});
}
}
@@ -186,6 +187,7 @@ export async function createPolicyEngineConfig(
toolName: tool,
decision: PolicyDecision.DENY,
priority: 2.4,
source: 'Settings (Tools Excluded)',
});
}
}
@@ -213,6 +215,7 @@ export async function createPolicyEngineConfig(
decision: PolicyDecision.ALLOW,
priority: 2.3,
argsPattern: new RegExp(pattern),
source: 'Settings (Tools Allowed)',
});
}
}
@@ -223,6 +226,7 @@ export async function createPolicyEngineConfig(
toolName,
decision: PolicyDecision.ALLOW,
priority: 2.3,
source: 'Settings (Tools Allowed)',
});
}
} else {
@@ -234,6 +238,7 @@ export async function createPolicyEngineConfig(
toolName,
decision: PolicyDecision.ALLOW,
priority: 2.3,
source: 'Settings (Tools Allowed)',
});
}
}
@@ -252,6 +257,7 @@ export async function createPolicyEngineConfig(
toolName: `${serverName}__*`,
decision: PolicyDecision.ALLOW,
priority: 2.2,
source: 'Settings (MCP Trusted)',
});
}
}
@@ -265,6 +271,7 @@ export async function createPolicyEngineConfig(
toolName: `${serverName}__*`,
decision: PolicyDecision.ALLOW,
priority: 2.1,
source: 'Settings (MCP Allowed)',
});
}
}
@@ -310,6 +317,7 @@ export function createPolicyUpdater(
// but still lose to admin policies (3.xxx) and settings excludes (200)
priority: 2.95,
argsPattern: new RegExp(pattern),
source: 'Dynamic (Confirmed)',
});
}
}
@@ -326,6 +334,7 @@ export function createPolicyUpdater(
// but still lose to admin policies (3.xxx) and settings excludes (200)
priority: 2.95,
argsPattern,
source: 'Dynamic (Confirmed)',
});
}

View File

@@ -53,6 +53,7 @@ priority = 100
toolName: 'glob',
decision: PolicyDecision.ALLOW,
priority: 1.1, // tier 1 + 100/1000
source: 'Default: test.toml',
});
expect(result.checkers).toHaveLength(0);
expect(result.errors).toHaveLength(0);
@@ -190,6 +191,7 @@ modes = ["autoEdit"]
expect(result.rules).toHaveLength(1);
expect(result.rules[0].toolName).toBe('tier2-tool');
expect(result.rules[0].modes).toEqual(['autoEdit']);
expect(result.rules[0].source).toBe('User: tier2.toml');
expect(result.errors).toHaveLength(0);
});

View File

@@ -346,6 +346,7 @@ export async function loadPoliciesFromToml(
priority: transformPriority(rule.priority, tier),
modes: rule.modes,
allowRedirection: rule.allow_redirection,
source: `${tierName.charAt(0).toUpperCase() + tierName.slice(1)}: ${file}`,
};
// Compile regex pattern

View File

@@ -135,6 +135,12 @@ export interface PolicyRule {
* Only applies when decision is ALLOW.
*/
allowRedirection?: boolean;
/**
* Effect of the rule's source.
* e.g. "my-policies.toml", "Settings (MCP Trusted)", etc.
*/
source?: string;
}
export interface SafetyCheckerRule {