Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions src/services/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,11 @@ class AgentService {

// Basic policy checks (more complex logic would be here)
if (amount > fromAgent.policy.spendingLimit) {
throw new Error(
`Transfer amount exceeds spending limit for agent ${fromAgentId}`,
);
throw new Error(`Zero Trust Validation Failed: Transfer amount exceeds spending limit for agent ${fromAgentId}`);
}
if (
!fromAgent.policy.authorizedCounterparties.includes(toAgentId) &&
fromAgent.policy.authorizedCounterparties.length > 0
) {
throw new Error(
`Agent ${toAgentId} is not an authorized counterparty for ${fromAgentId}`,
);
if (!fromAgent.policy.authorizedCounterparties.includes(toAgentId) &&
fromAgent.policy.authorizedCounterparties.length > 0) {
throw new Error(`Zero Trust Validation Failed: Agent ${toAgentId} is not an authorized counterparty for ${fromAgentId}`);
}

// Simulate transfer success
Expand Down
23 changes: 6 additions & 17 deletions src/services/mandate.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,18 @@ class MandateService {
}) {
const decodedIntent = await this.verifyMandate(intentMandate);

if (decodedIntent.type !== "intent_mandate") {
throw new Error(
"Zero Trust Validation Failed: Invalid intent mandate type",
);
if (decodedIntent.type !== 'intent_mandate') {
throw new Error('Zero Trust Validation Failed: Invalid intent mandate type');
}

// Verify budget
if (totalPrice > decodedIntent.max_budget.value) {
throw new Error(
"Zero Trust Validation Failed: Cart total exceeds intent mandate budget",
);
throw new Error('Zero Trust Validation Failed: Cart total exceeds intent mandate budget');
}

// Verify merchant if whitelist exists
if (
decodedIntent.allowed_merchants.length > 0 &&
!decodedIntent.allowed_merchants.includes(merchantDid)
) {
throw new Error(
`Zero Trust Validation Failed: Merchant ${merchantDid} is not authorized by this mandate`,
);
if (decodedIntent.allowed_merchants.length > 0 && !decodedIntent.allowed_merchants.includes(merchantDid)) {
throw new Error(`Zero Trust Validation Failed: Merchant ${merchantDid} is not authorized by this mandate`);
}

// Create cryptographic hash of cart
Expand Down Expand Up @@ -120,9 +111,7 @@ class MandateService {
try {
return jwt.verify(token, this.signingKey, { algorithms: ["HS256"] });
} catch (error) {
throw new Error(
`Zero Trust Validation Failed: Mandate verification failed: ${error.message}`,
);
throw new Error(`Zero Trust Validation Failed: Mandate verification failed: ${error.message}`);
}
}

Expand Down
24 changes: 12 additions & 12 deletions src/services/ucp.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,26 @@ class UCPService {
/**
* Process a UCP Payload
* @param {Object} payload - The raw UCP JSON payload
* @param {string} mandate - Optional signed Mandate (AP2) for Zero Trust validation
*/
async processPayload(payload) {
async processPayload(payload, mandate) {
try {
// 1. Validate the UCP intent against schema
const { error, value } = this.ucpIntentSchema.validate(payload, {
stripUnknown: true,
});
if (error) {
throw new Error(
`Zero Trust Validation Failed: UCP Intent validation failed: ${error.details.map((x) => x.message).join(", ")}`,
);
throw new Error(`Zero Trust Validation Failed: UCP Intent validation failed: ${error.details.map(x => x.message).join(', ')}`);
}

const validatedPayload = value;
const { intent } = validatedPayload;

switch (intent) {
case "transfer":
case "payment":
return this._handleTransfer(validatedPayload);
case "purchase":
case 'transfer':
case 'payment':
return this._handleTransfer(validatedPayload, mandate);
case 'purchase':
// Future implementation: integration with Inventory/Order services
return {
status: "success",
Expand All @@ -85,21 +84,22 @@ class UCPService {
* Handle transfer/payment intents via A2AService
* @private
*/
async _handleTransfer(payload) {
async _handleTransfer(payload, mandate) {
const { sender, recipient, amount } = payload;

if (!recipient?.agent_id) {
throw new Error("Missing recipient agent_id for transfer");
throw new Error('Zero Trust Validation Failed: Missing recipient agent_id for transfer');
}
if (!amount?.value) {
throw new Error("Missing amount value");
throw new Error('Zero Trust Validation Failed: Missing amount value');
}

return this.a2aService.executeTransfer({
fromAgentId: sender.agent_id,
toAgentId: recipient.agent_id,
amount: amount.value,
ucpPayload: payload,
mandate,
ucpPayload: payload
});
}

Expand Down
61 changes: 61 additions & 0 deletions tests/unit/mandate_extra.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const MandateService = require('../../src/services/mandate');
const jwt = require('jsonwebtoken');

describe('MandateService', () => {
let mandateService;
const signingKey = 'test-secret';

beforeEach(() => {
mandateService = new MandateService({ signingKey });
});

describe('issueCartMandate', () => {
it('should throw error for invalid intent mandate type', async () => {
const invalidMandate = jwt.sign({ type: 'not_intent' }, signingKey);
await expect(mandateService.issueCartMandate({
intentMandate: invalidMandate,
cartItems: [],
totalPrice: 100,
merchantDid: 'did:key:m'
})).rejects.toThrow('Zero Trust Validation Failed: Invalid intent mandate type');
});

it('should throw error if cart total exceeds budget', async () => {
const intentMandate = await mandateService.issueIntentMandate({
userDid: 'did:key:u',
agentDid: 'did:key:a',
maxBudget: 50
});

await expect(mandateService.issueCartMandate({
intentMandate,
cartItems: [],
totalPrice: 100,
merchantDid: 'did:key:m'
})).rejects.toThrow('Zero Trust Validation Failed: Cart total exceeds intent mandate budget');
});

it('should throw error if merchant is not authorized', async () => {
const intentMandate = await mandateService.issueIntentMandate({
userDid: 'did:key:u',
agentDid: 'did:key:a',
maxBudget: 500,
allowedMerchants: ['did:key:m1']
});

await expect(mandateService.issueCartMandate({
intentMandate,
cartItems: [],
totalPrice: 100,
merchantDid: 'did:key:m2'
})).rejects.toThrow('Zero Trust Validation Failed: Merchant did:key:m2 is not authorized by this mandate');
});
});

describe('verifyMandate', () => {
it('should throw error for invalid token', async () => {
await expect(mandateService.verifyMandate('invalid-token'))
.rejects.toThrow('Zero Trust Validation Failed: Mandate verification failed: jwt malformed');
});
});
});
Loading