fix(policy): ensure user policies are loaded when policyPaths is empty (#22090)

This commit is contained in:
N. Taylor Mullen
2026-03-11 16:58:58 -07:00
committed by GitHub
parent 90b53f9a82
commit 7380424782
5 changed files with 139 additions and 2 deletions
+50
View File
@@ -19,6 +19,7 @@ import { isDirectorySecure } from '../utils/security.js';
import {
createPolicyEngineConfig,
clearEmittedPolicyWarnings,
getPolicyDirectories,
} from './config.js';
import { Storage } from '../config/storage.js';
import * as tomlLoader from './toml-loader.js';
@@ -746,3 +747,52 @@ modes = ["plan"]
feedbackSpy.mockRestore();
});
});
describe('getPolicyDirectories', () => {
const USER_POLICIES_DIR = '/mock/user/policies';
const SYSTEM_POLICIES_DIR = '/mock/system/policies';
beforeEach(() => {
vi.spyOn(Storage, 'getUserPoliciesDir').mockReturnValue(USER_POLICIES_DIR);
vi.spyOn(Storage, 'getSystemPoliciesDir').mockReturnValue(
SYSTEM_POLICIES_DIR,
);
});
it('should include default user policies directory when policyPaths is undefined', () => {
const dirs = getPolicyDirectories();
expect(dirs).toContain(USER_POLICIES_DIR);
});
it('should include default user policies directory when policyPaths is an empty array', () => {
// This is the specific case that regressed
const dirs = getPolicyDirectories(undefined, []);
expect(dirs).toContain(USER_POLICIES_DIR);
});
it('should replace default user policies directory when policyPaths has entries', () => {
const customPath = '/custom/policies';
const dirs = getPolicyDirectories(undefined, [customPath]);
expect(dirs).toContain(customPath);
expect(dirs).not.toContain(USER_POLICIES_DIR);
});
it('should include all tiers in correct order', () => {
const defaultDir = '/default/policies';
const workspaceDir = '/workspace/policies';
const adminPath = '/admin/extra/policies';
const userPath = '/user/custom/policies';
const dirs = getPolicyDirectories(defaultDir, [userPath], workspaceDir, [
adminPath,
]);
// Order should be Admin -> User -> Workspace -> Default
// getPolicyDirectories returns them in that order (which is then reversed by the loader)
expect(dirs[0]).toBe(SYSTEM_POLICIES_DIR);
expect(dirs[1]).toBe(adminPath);
expect(dirs[2]).toBe(userPath);
expect(dirs[3]).toBe(workspaceDir);
expect(dirs[4]).toBe(defaultDir);
});
});
+3 -1
View File
@@ -124,7 +124,9 @@ export function getPolicyDirectories(
...(adminPolicyPaths ?? []),
// User tier (second highest priority)
...(policyPaths ?? [Storage.getUserPoliciesDir()]),
...(policyPaths && policyPaths.length > 0
? policyPaths
: [Storage.getUserPoliciesDir()]),
// Workspace Tier (third highest)
workspacePoliciesDir,