From 5396231c9225b75bbeacf60c38c3dbe9c5267703 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:16:11 +0000 Subject: [PATCH] Enforce Zero Trust Mandate Standardizations and Fix A2AService Compilation Error - Fix syntax/compilation error in a2aService.js by removing duplicate import of MandateService. - Standardize whitelisting checks in mandate.js to use 'Merchant' instead of 'Recipient'. - Handle expired jsonwebtoken tokens gracefully by throwing 'Zero Trust Validation Failed: Mandate has expired'. - Align AgentService local fallback policy validation checks and error prefix consistency. - Update agent.spec.js to correctly isolate local vs delegating behavior in unit tests. Co-authored-by: dcplatforms <10982057+dcplatforms@users.noreply.github.com> --- src/services/a2aService.js | 1 - src/services/agent.js | 2 +- src/services/mandate.js | 5 ++++- tests/unit/agent.spec.js | 7 ++++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/services/a2aService.js b/src/services/a2aService.js index 2b9125d..e9bf2f1 100644 --- a/src/services/a2aService.js +++ b/src/services/a2aService.js @@ -7,7 +7,6 @@ const MandateService = require("./mandate"); const logger = require("../utils/logger"); -const MandateService = require("./mandate"); class A2AService { constructor(walletService, db, config = {}) { diff --git a/src/services/agent.js b/src/services/agent.js index 8643cff..28a1cfc 100644 --- a/src/services/agent.js +++ b/src/services/agent.js @@ -194,7 +194,7 @@ class AgentService { if (perTransactionLimit > 0 && amount > perTransactionLimit) { throw new Error( - `Zero Trust Validation Failed: Transfer amount ${amount} exceeds per-transaction limit of ${perTransactionLimit} for agent ${fromAgentId}`, + `Zero Trust Validation Failed: Amount ${amount} exceeds agent per-transaction limit of ${perTransactionLimit}`, ); } diff --git a/src/services/mandate.js b/src/services/mandate.js index df7e827..03fe77f 100644 --- a/src/services/mandate.js +++ b/src/services/mandate.js @@ -113,6 +113,9 @@ class MandateService { try { decoded = jwt.verify(token, this.signingKey, { algorithms: ["HS256"] }); } catch (error) { + if (error.name === "TokenExpiredError") { + throw new Error("Zero Trust Validation Failed: Mandate has expired"); + } throw new Error( `Zero Trust Validation Failed: Mandate verification failed: ${error.message}`, ); @@ -135,7 +138,7 @@ class MandateService { if (context.recipient && decoded.allowed_merchants?.length > 0) { if (!decoded.allowed_merchants.includes(context.recipient)) { throw new Error( - `Zero Trust Validation Failed: Recipient ${context.recipient} not authorized by mandate`, + `Zero Trust Validation Failed: Merchant ${context.recipient} not authorized by mandate`, ); } } diff --git a/tests/unit/agent.spec.js b/tests/unit/agent.spec.js index f263044..f045faf 100644 --- a/tests/unit/agent.spec.js +++ b/tests/unit/agent.spec.js @@ -15,7 +15,7 @@ describe('AgentService', () => { mockA2AService = { executeTransfer: jest.fn() }; - agentService = new AgentService(mockDb, {}, mockA2AService); + agentService = new AgentService(mockDb, {}); }); describe('registerAgent', () => { @@ -55,7 +55,7 @@ describe('AgentService', () => { fromAgentId: 'agent1', toAgentId: 'agent2', amount: 100 - })).rejects.toThrow(/Zero Trust Validation Failed: Transfer amount 100 exceeds per-transaction limit of 50/); + })).rejects.toThrow(/Zero Trust Validation Failed: Amount 100 exceeds agent per-transaction limit of 50/); }); it('should throw if counterparty is not authorized', async () => { @@ -101,7 +101,8 @@ describe('AgentService', () => { const expectedResult = { success: true, transferId: 'tx123' }; mockA2AService.executeTransfer.mockResolvedValue(expectedResult); - const result = await agentService.performA2ATransfer(transferParams); + const delegatingAgentService = new AgentService(mockDb, {}, mockA2AService); + const result = await delegatingAgentService.performA2ATransfer(transferParams); expect(mockA2AService.executeTransfer).toHaveBeenCalledWith({ fromAgentId: 'agent1',