From a50fc8714e759071be868eca82960f1d708a4d9d Mon Sep 17 00:00:00 2001 From: lazyGPT07 Date: Sat, 13 Jun 2026 21:33:44 -0600 Subject: [PATCH 1/2] Fail closed on non-finite risk scores --- packages/account-core/src/index.test.ts | 25 +++++++++++++++++++++++++ packages/account-core/src/policy.ts | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/account-core/src/index.test.ts b/packages/account-core/src/index.test.ts index c00a8e3..bbbe93f 100644 --- a/packages/account-core/src/index.test.ts +++ b/packages/account-core/src/index.test.ts @@ -41,6 +41,31 @@ describe("account-core", () => { expect(result.decision).toBe("approval_required"); }); + it.each([Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY])( + "fails closed for a non-finite risk score of %s", + (riskScore) => { + const result = evaluateAccountPolicy({ + action: "social:profile:read", + riskScore, + principal: { type: "agent", id: "profile-agent" }, + grant: { + id: "grant_non_finite", + accountId: "account_1", + principal: { type: "agent", id: "profile-agent" }, + permissions: ["social:profile:read"], + policy: [], + createdAt: new Date(0).toISOString() + } + }); + + expect(result).toMatchObject({ + decision: "deny", + riskScore: 1, + reason: "critical risk requires admin override" + }); + } + ); + it("redacts secret-like audit previews", () => { const event = createAccountAuditEvent({ provider: "gmail", diff --git a/packages/account-core/src/policy.ts b/packages/account-core/src/policy.ts index b80ed25..4d40d92 100644 --- a/packages/account-core/src/policy.ts +++ b/packages/account-core/src/policy.ts @@ -51,7 +51,8 @@ export function scoreAccountActionRisk(input: { } export function evaluateAccountPolicy(input: LogicSrcPolicyEvaluationInput): LogicSrcPolicyEvaluationResult { - const riskScore = Math.min(1, Math.max(0, input.riskScore ?? scoreAccountActionRisk({ action: input.action }))); + const requestedRiskScore = input.riskScore ?? scoreAccountActionRisk({ action: input.action }); + const riskScore = Number.isFinite(requestedRiskScore) ? Math.min(1, Math.max(0, requestedRiskScore)) : 1; const grantActive = input.grant && !input.grant.revokedAt && (!input.grant.expiresAt || Date.parse(input.grant.expiresAt) > Date.now()); const hasPermission = Boolean(grantActive && input.grant?.permissions.includes(input.action)); From af1d9714774d673a9ad62a9e7485926e5645eea0 Mon Sep 17 00:00:00 2001 From: lazyGPT07 Date: Sat, 13 Jun 2026 23:06:39 -0600 Subject: [PATCH 2/2] Classify non-finite risk bands as critical --- packages/account-core/src/index.test.ts | 7 +++++++ packages/account-core/src/policy.ts | 3 +++ 2 files changed, 10 insertions(+) diff --git a/packages/account-core/src/index.test.ts b/packages/account-core/src/index.test.ts index bbbe93f..6f67303 100644 --- a/packages/account-core/src/index.test.ts +++ b/packages/account-core/src/index.test.ts @@ -24,6 +24,13 @@ describe("account-core", () => { expect(riskBandForScore(score)).toBe("high"); }); + it.each([Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY])( + "classifies a non-finite risk score of %s as critical", + (riskScore) => { + expect(riskBandForScore(riskScore)).toBe("critical"); + } + ); + it("requires approval for gated actions with matching grants", () => { const result = evaluateAccountPolicy({ action: "email:send", diff --git a/packages/account-core/src/policy.ts b/packages/account-core/src/policy.ts index 4d40d92..d91cd4b 100644 --- a/packages/account-core/src/policy.ts +++ b/packages/account-core/src/policy.ts @@ -14,6 +14,9 @@ const WRITE_ACTIONS = new Set([ ]); export function riskBandForScore(score: number): LogicSrcRiskBand { + if (!Number.isFinite(score)) { + return "critical"; + } if (score >= 0.75) { return "critical"; }