feat(policy): change priority hierarchy to Admin > User > Project > Default

Updates the policy engine to prioritize User policies over Project-specific policies.
This change is a security measure to ensure that users maintain control over their
environment and are not inadvertently compromised by policies defined in a cloned
repository.

Key Changes:
- Swapped Tier 2 (now Project) and Tier 3 (now User).
- Updated documentation to reflect the new hierarchy.
- Updated all built-in policy TOML files with correct tier information.
- Adjusted all tests and integration test expectations to match new priority values.
This commit is contained in:
Abhijit Balaji
2026-02-09 16:17:10 -08:00
parent f34a3ee1df
commit 3a24b0c975
12 changed files with 146 additions and 138 deletions
@@ -148,13 +148,13 @@ describe('Policy Engine Integration Tests', () => {
);
const engine = new PolicyEngine(config);
// MCP server allowed (priority 2.1) provides general allow for server
// MCP server allowed (priority 2.1) provides general allow for server
// MCP server allowed (priority 3.1) provides general allow for server
// MCP server allowed (priority 3.1) provides general allow for server
expect(
(await engine.check({ name: 'my-server__safe-tool' }, undefined))
.decision,
).toBe(PolicyDecision.ALLOW);
// But specific tool exclude (priority 2.4) wins over server allow
// But specific tool exclude (priority 3.4) wins over server allow
expect(
(await engine.check({ name: 'my-server__dangerous-tool' }, undefined))
.decision,
@@ -412,25 +412,25 @@ describe('Policy Engine Integration Tests', () => {
// Find rules and verify their priorities
const blockedToolRule = rules.find((r) => r.toolName === 'blocked-tool');
expect(blockedToolRule?.priority).toBe(2.4); // Command line exclude
expect(blockedToolRule?.priority).toBe(3.4); // Command line exclude
const blockedServerRule = rules.find(
(r) => r.toolName === 'blocked-server__*',
);
expect(blockedServerRule?.priority).toBe(2.9); // MCP server exclude
expect(blockedServerRule?.priority).toBe(3.9); // MCP server exclude
const specificToolRule = rules.find(
(r) => r.toolName === 'specific-tool',
);
expect(specificToolRule?.priority).toBe(2.3); // Command line allow
expect(specificToolRule?.priority).toBe(3.3); // Command line allow
const trustedServerRule = rules.find(
(r) => r.toolName === 'trusted-server__*',
);
expect(trustedServerRule?.priority).toBe(2.2); // MCP trusted server
expect(trustedServerRule?.priority).toBe(3.2); // MCP trusted server
const mcpServerRule = rules.find((r) => r.toolName === 'mcp-server__*');
expect(mcpServerRule?.priority).toBe(2.1); // MCP allowed server
expect(mcpServerRule?.priority).toBe(3.1); // MCP allowed server
const readOnlyToolRule = rules.find((r) => r.toolName === 'glob');
// Priority 70 in default tier → 1.07 (Overriding Plan Mode Deny)
@@ -577,16 +577,16 @@ describe('Policy Engine Integration Tests', () => {
// Verify each rule has the expected priority
const tool3Rule = rules.find((r) => r.toolName === 'tool3');
expect(tool3Rule?.priority).toBe(2.4); // Excluded tools (user tier)
expect(tool3Rule?.priority).toBe(3.4); // Excluded tools (user tier)
const server2Rule = rules.find((r) => r.toolName === 'server2__*');
expect(server2Rule?.priority).toBe(2.9); // Excluded servers (user tier)
expect(server2Rule?.priority).toBe(3.9); // Excluded servers (user tier)
const tool1Rule = rules.find((r) => r.toolName === 'tool1');
expect(tool1Rule?.priority).toBe(2.3); // Allowed tools (user tier)
expect(tool1Rule?.priority).toBe(3.3); // Allowed tools (user tier)
const server1Rule = rules.find((r) => r.toolName === 'server1__*');
expect(server1Rule?.priority).toBe(2.1); // Allowed servers (user tier)
expect(server1Rule?.priority).toBe(3.1); // Allowed servers (user tier)
const globRule = rules.find((r) => r.toolName === 'glob');
// Priority 70 in default tier → 1.07