Skip to content

Commit c078632

Browse files
authored
Merge pull request #19 from dcplatforms/align-ocp-mandate-13108048640949193712
Align OCP SDK with Zero Trust and Architectural Integrity Pillars
2 parents 99b4242 + 5377728 commit c078632

4 files changed

Lines changed: 49 additions & 21 deletions

File tree

src/services/a2aService.js

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
* policy compliance, limit checks, and authorized counterparty validation.
66
*/
77

8-
const { Agent } = require("../models/agent");
8+
const MandateService = require("./mandate");
99
const logger = require("../utils/logger");
1010

1111
class A2AService {
12-
constructor(walletService, db) {
12+
constructor(walletService, db, config = {}) {
1313
this.walletService = walletService;
1414
this.db = db;
15+
this.mandateService = config.mandateService || new MandateService(config.mandateConfig);
16+
this.strictMandateMode =
17+
config.strictMandateMode !== undefined
18+
? config.strictMandateMode
19+
: process.env.STRICT_MANDATE_MODE === "true";
1520
}
1621

1722
/**
@@ -20,19 +25,45 @@ class A2AService {
2025
* @param {string} params.fromAgentId - Sender Agent ID
2126
* @param {string} params.toAgentId - Recipient Agent ID
2227
* @param {number} params.amount - Amount to transfer
28+
* @param {string} params.mandate - Optional signed Mandate (AP2) for Zero Trust validation
2329
* @param {Object} params.ucpPayload - The original UCP intent/payload
2430
*/
25-
async executeTransfer({ fromAgentId, toAgentId, amount, ucpPayload = {} }) {
31+
async executeTransfer({
32+
fromAgentId,
33+
toAgentId,
34+
amount,
35+
mandate,
36+
ucpPayload = {},
37+
}) {
2638
try {
27-
// 1. Validate Agents
28-
const fromAgent = await Agent.findById(fromAgentId);
39+
// 0. Zero Trust Mandate Validation
40+
if (mandate) {
41+
try {
42+
await this.mandateService.verifyMandate(mandate);
43+
} catch (error) {
44+
throw new Error(
45+
`Zero Trust Validation Failed: Mandate verification failed: ${error.message}`,
46+
);
47+
}
48+
} else if (this.strictMandateMode) {
49+
throw new Error(
50+
"Zero Trust Validation Failed: Mandate required for A2A transfer in strict mode",
51+
);
52+
}
53+
54+
// 1. Validate Agents using Repository Pattern
55+
const fromAgent = await this.db.findAgentById(fromAgentId);
2956
if (!fromAgent || fromAgent.status !== "active") {
30-
throw new Error(`Sender agent ${fromAgentId} not found or inactive`);
57+
throw new Error(
58+
`Zero Trust Validation Failed: Sender agent ${fromAgentId} not found or inactive`,
59+
);
3160
}
3261

33-
const toAgent = await Agent.findById(toAgentId);
62+
const toAgent = await this.db.findAgentById(toAgentId);
3463
if (!toAgent || toAgent.status !== "active") {
35-
throw new Error(`Recipient agent ${toAgentId} not found or inactive`);
64+
throw new Error(
65+
`Zero Trust Validation Failed: Recipient agent ${toAgentId} not found or inactive`,
66+
);
3667
}
3768

3869
// 2. Policy Checks (Sender)
@@ -50,13 +81,10 @@ class A2AService {
5081
counterpartyAgentId: toAgentId,
5182
ucpPayload,
5283
type: "a2a_transfer",
84+
mandate,
5385
},
5486
});
5587

56-
// 4. Update Agent Usage (if we were tracking daily usage in db, we'd do it here)
57-
// For now, limits are stateless checks against config.
58-
// In a real implementation, we would query daily volume or update a usage record.
59-
6088
return {
6189
success: true,
6290
transferId: transferResult.transferId,

src/services/agent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AgentService {
7272
try {
7373
const agent = await this.db.findAgentById(agentId);
7474
if (!agent) {
75-
throw new Error("Agent not found");
75+
throw new Error("Zero Trust Validation Failed: Agent not found");
7676
}
7777
return agent;
7878
} catch (error) {

src/services/wallet.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class WalletService {
3636
// Check if user already has a wallet
3737
const existingWallet = await this.db.findWalletByUserId(userId);
3838
if (existingWallet) {
39-
throw new Error("User already has a wallet");
39+
throw new Error("Zero Trust Validation Failed: User already has a wallet");
4040
}
4141

4242
// Validate initial balance
@@ -91,7 +91,7 @@ class WalletService {
9191
try {
9292
const wallet = await this.db.findWalletById(walletId);
9393
if (!wallet) {
94-
throw new Error("Wallet not found");
94+
throw new Error("Zero Trust Validation Failed: Wallet not found");
9595
}
9696
return wallet;
9797
} catch (error) {
@@ -108,7 +108,7 @@ class WalletService {
108108
try {
109109
const wallet = await this.db.findWalletByUserId(userId);
110110
if (!wallet) {
111-
throw new Error("Wallet not found for user");
111+
throw new Error("Zero Trust Validation Failed: Wallet not found for user");
112112
}
113113
return wallet;
114114
} catch (error) {
@@ -142,7 +142,7 @@ class WalletService {
142142
// Get wallet
143143
const wallet = await this.getWallet(walletId);
144144
if (wallet.status !== "active") {
145-
throw new Error("Wallet is not active");
145+
throw new Error("Zero Trust Validation Failed: Wallet is not active");
146146
}
147147

148148
// Check if new balance would exceed max
@@ -215,12 +215,12 @@ class WalletService {
215215
// Get wallet
216216
const wallet = await this.getWallet(walletId);
217217
if (wallet.status !== "active") {
218-
throw new Error("Wallet is not active");
218+
throw new Error("Zero Trust Validation Failed: Wallet is not active");
219219
}
220220

221221
// Check sufficient balance
222222
if (wallet.balance < amount) {
223-
throw new Error("Insufficient balance");
223+
throw new Error("Zero Trust Validation Failed: Insufficient balance");
224224
}
225225

226226
const newBalance = wallet.balance - amount;
@@ -297,7 +297,7 @@ class WalletService {
297297
}
298298

299299
if (fromWalletId === toWalletId) {
300-
throw new Error("Cannot transfer to same wallet");
300+
throw new Error("Zero Trust Validation Failed: Cannot transfer to same wallet");
301301
}
302302

303303
// Start transaction

tests/unit/agent.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('AgentService', () => {
3535
describe('getAgent', () => {
3636
it('should throw if agent not found', async () => {
3737
mockDb.findAgentById.mockResolvedValue(null);
38-
await expect(agentService.getAgent('nonexistent')).rejects.toThrow('Agent not found');
38+
await expect(agentService.getAgent('nonexistent')).rejects.toThrow('Zero Trust Validation Failed: Agent not found');
3939
});
4040
});
4141
});

0 commit comments

Comments
 (0)