feat(security): add disableAlwaysAllow setting to disable auto-approvals (#21941)

This commit is contained in:
Gal Zahavi
2026-03-13 16:02:09 -07:00
committed by GitHub
parent b0d151bd65
commit b49fc8122d
20 changed files with 352 additions and 63 deletions
+18
View File
@@ -13,6 +13,7 @@ import {
type HookCheckerRule,
ApprovalMode,
type CheckResult,
ALWAYS_ALLOW_PRIORITY_FRACTION,
} from './types.js';
import { stableStringify } from './stable-stringify.js';
import { debugLogger } from '../utils/debugLogger.js';
@@ -154,6 +155,7 @@ export class PolicyEngine {
private hookCheckers: HookCheckerRule[];
private readonly defaultDecision: PolicyDecision;
private readonly nonInteractive: boolean;
private readonly disableAlwaysAllow: boolean;
private readonly checkerRunner?: CheckerRunner;
private approvalMode: ApprovalMode;
@@ -169,6 +171,7 @@ export class PolicyEngine {
);
this.defaultDecision = config.defaultDecision ?? PolicyDecision.ASK_USER;
this.nonInteractive = config.nonInteractive ?? false;
this.disableAlwaysAllow = config.disableAlwaysAllow ?? false;
this.checkerRunner = checkerRunner;
this.approvalMode = config.approvalMode ?? ApprovalMode.DEFAULT;
}
@@ -187,6 +190,13 @@ export class PolicyEngine {
return this.approvalMode;
}
private isAlwaysAllowRule(rule: PolicyRule): boolean {
return (
rule.priority !== undefined &&
Math.round((rule.priority % 1) * 1000) === ALWAYS_ALLOW_PRIORITY_FRACTION
);
}
private shouldDowngradeForRedirection(
command: string,
allowRedirection?: boolean,
@@ -422,6 +432,10 @@ export class PolicyEngine {
}
for (const rule of this.rules) {
if (this.disableAlwaysAllow && this.isAlwaysAllowRule(rule)) {
continue;
}
const match = toolCallsToTry.some((tc) =>
ruleMatches(
rule,
@@ -684,6 +698,10 @@ export class PolicyEngine {
// Evaluate rules in priority order (they are already sorted in constructor)
for (const rule of this.rules) {
if (this.disableAlwaysAllow && this.isAlwaysAllowRule(rule)) {
continue;
}
// Create a copy of the rule without argsPattern to see if it targets the tool
// regardless of the runtime arguments it might receive.
const ruleWithoutArgs: PolicyRule = { ...rule, argsPattern: undefined };