fix: harden deploy enforcement paths (#1030)

* fix: harden deploy enforcement paths

* fix: update Docker toolchain to Go 1.26.3

* fix: repair Dockerfile tr argument split across lines

* fix: bump protobufjs to clear npm audit high-severity advisories

* fix(test): add execFile to child_process mock in compose-images test

* fix: resolve merge conflicts with main

* fix: resolve merge conflicts with main

* fix: resolve merge conflicts with main
This commit is contained in:
Anso
2026-05-12 19:30:49 -04:00
committed by GitHub
parent 74ae2ce0c6
commit b1c5fe8391
19 changed files with 1179 additions and 922 deletions
+27
View File
@@ -4,6 +4,8 @@ import DockerController from '../services/DockerController';
import { DatabaseService } from '../services/DatabaseService';
import { NotificationService } from '../services/NotificationService';
import TrivyService, { DIGEST_CACHE_TTL_MS } from '../services/TrivyService';
import { LicenseService } from '../services/LicenseService';
import { effectiveTier } from '../middleware/tierGates';
import { getErrorMessage } from '../utils/errors';
import { sanitizeForLog } from '../utils/safeLog';
@@ -18,12 +20,37 @@ export function buildPolicyGateOptions(
return {
bypass: overrides.bypass ?? defaultBypass,
actor: overrides.actor ?? req.user?.username ?? 'unknown',
blockingEnabled: effectiveTier(req) === 'paid',
ip: (req.ip ?? req.socket.remoteAddress ?? '') as string,
auditMethod: req.method,
auditPath: req.originalUrl || req.url,
};
}
export function buildSystemPolicyGateOptions(
actor: string,
overrides: { bypass?: boolean; blockingEnabled?: boolean; auditPath?: string; auditMethod?: string } = {},
): PolicyEnforcementOptions {
return {
bypass: overrides.bypass ?? false,
actor,
blockingEnabled: overrides.blockingEnabled ?? LicenseService.getInstance().getTier() === 'paid',
auditMethod: overrides.auditMethod ?? 'POST',
auditPath: overrides.auditPath,
};
}
export async function assertPolicyGateAllows(
stackName: string,
nodeId: number,
options: PolicyEnforcementOptions,
): Promise<void> {
const gate = await enforcePolicyPreDeploy(stackName, nodeId, options);
if (!gate.ok) {
throw new Error(`Policy "${gate.policy?.name}" blocked deploy: ${gate.violations.length} image(s) exceed ${gate.policy?.max_severity}`);
}
}
/**
* Returns true if the deploy may proceed. Returns false after sending a 409,
* in which case the caller must return immediately.