Trust is the foundation of cooperation. Just as human societies require trust to function effectively, multi-agent systems must establish security and trust mechanisms to protect all participants and enable safe collaboration for the collective good.
Multi-agent systems face unique security challenges due to their distributed nature, autonomous agents, and open environments.
Primary security concerns:
Agents must prove their identity before being trusted. Multiple authentication mechanisms exist:
class AgentAuthenticationSystem {
constructor() {
this.registeredAgents = new Map();
this.sessions = new Map();
this.crypto = require('crypto');
}
// Register new agent with public key
registerAgent(agentId, publicKey, metadata) {
if (this.registeredAgents.has(agentId)) {
throw new Error('Agent already registered');
}
this.registeredAgents.set(agentId, {
id: agentId,
publicKey: publicKey,
registeredAt: Date.now(),
metadata: metadata,
trustScore: 50, // Initial trust score
verified: false
});
return { success: true, agentId: agentId };
}
// Authenticate agent with challenge-response
async authenticate(agentId, signature, challenge) {
const agent = this.registeredAgents.get(agentId);
if (!agent) {
throw new Error('Agent not registered');
}
// Verify signature
const verify = this.crypto.createVerify('SHA256');
verify.update(challenge);
const isValid = verify.verify(agent.publicKey, signature, 'hex');
if (!isValid) {
this.recordFailedAuth(agentId);
throw new Error('Authentication failed');
}
// Create session token
const sessionToken = this.generateSessionToken();
this.sessions.set(sessionToken, {
agentId: agentId,
createdAt: Date.now(),
expiresAt: Date.now() + 3600000, // 1 hour
permissions: this.getAgentPermissions(agentId)
});
return {
success: true,
sessionToken: sessionToken,
expiresAt: this.sessions.get(sessionToken).expiresAt
};
}
// Token-based authentication
validateSession(sessionToken) {
const session = this.sessions.get(sessionToken);
if (!session) {
throw new Error('Invalid session');
}
if (Date.now() > session.expiresAt) {
this.sessions.delete(sessionToken);
throw new Error('Session expired');
}
return session;
}
generateSessionToken() {
return this.crypto.randomBytes(32).toString('hex');
}
recordFailedAuth(agentId) {
const agent = this.registeredAgents.get(agentId);
if (agent) {
agent.failedAuthAttempts = (agent.failedAuthAttempts || 0) + 1;
agent.trustScore = Math.max(0, agent.trustScore - 5);
// Lock account after too many failures
if (agent.failedAuthAttempts >= 5) {
agent.locked = true;
}
}
}
getAgentPermissions(agentId) {
const agent = this.registeredAgents.get(agentId);
return {
canSendMessages: agent.trustScore >= 30,
canAccessResources: agent.verified && agent.trustScore >= 50,
canCreateCoalitions: agent.verified && agent.trustScore >= 70,
maxMessageRate: agent.trustScore >= 80 ? 1000 : 100
};
}
}
// 弘益人間: Secure authentication protecting all participants
Trust is fundamental to multi-agent collaboration. Trust models help agents evaluate the reliability of other agents.
class ReputationSystem {
constructor() {
this.reputations = new Map();
this.interactions = [];
this.decayRate = 0.05;
}
// Record interaction outcome
recordInteraction(agentA, agentB, outcome, context) {
const interaction = {
timestamp: Date.now(),
initiator: agentA,
respondent: agentB,
outcome: outcome, // success, failure, partial
rating: this.outcomeToRating(outcome),
context: context
};
this.interactions.push(interaction);
this.updateReputation(agentB, interaction);
}
outcomeToRating(outcome) {
const ratings = {
'success': 1.0,
'partial': 0.5,
'failure': 0.0,
'malicious': -1.0
};
return ratings[outcome] || 0;
}
updateReputation(agentId, interaction) {
const current = this.reputations.get(agentId) || {
totalScore: 0,
interactions: 0,
reputation: 0.5
};
// Weighted average with recency bias
const recencyWeight = 1.0;
const newScore = current.totalScore * current.interactions +
interaction.rating * recencyWeight;
const newCount = current.interactions + recencyWeight;
current.totalScore = newScore;
current.interactions = newCount;
current.reputation = newScore / newCount;
this.reputations.set(agentId, current);
}
getReputation(agentId) {
const rep = this.reputations.get(agentId);
return rep ? rep.reputation : 0.5; // Neutral for new agents
}
// Calculate trust based on reputation and context
calculateTrust(agentId, context) {
const baseRep = this.getReputation(agentId);
// Context-specific reputation
const contextRep = this.getContextualReputation(agentId, context);
// Combine base and contextual reputation
return baseRep * 0.6 + contextRep * 0.4;
}
getContextualReputation(agentId, context) {
const relevant = this.interactions.filter(i =>
i.respondent === agentId &&
i.context === context
);
if (relevant.length === 0) {
return this.getReputation(agentId);
}
const sum = relevant.reduce((s, i) => s + i.rating, 0);
return sum / relevant.length;
}
// Decay old reputations over time
decayReputations() {
for (const [agentId, rep] of this.reputations) {
// Pull toward neutral (0.5)
rep.reputation += (0.5 - rep.reputation) * this.decayRate;
this.reputations.set(agentId, rep);
}
}
// Get most trusted agents
getMostTrusted(count = 10) {
return Array.from(this.reputations.entries())
.sort((a, b) => b[1].reputation - a[1].reputation)
.slice(0, count)
.map(([id, rep]) => ({ agentId: id, reputation: rep.reputation }));
}
}
// 弘익人間: Trust system ensuring reliable collaboration
Agents can leverage trust relationships transitively: if A trusts B, and B trusts C, then A may trust C to some degree.
class TransitiveTrustNetwork {
constructor() {
this.trustEdges = new Map(); // agentA -> { agentB: trust_value }
}
setDirectTrust(agentA, agentB, trustValue) {
if (!this.trustEdges.has(agentA)) {
this.trustEdges.set(agentA, new Map());
}
this.trustEdges.get(agentA).set(agentB, trustValue);
}
getDirectTrust(agentA, agentB) {
const edges = this.trustEdges.get(agentA);
return edges ? (edges.get(agentB) || 0) : 0;
}
// Calculate transitive trust through paths
calculateTransitiveTrust(agentA, agentC, maxDepth = 3) {
const paths = this.findPaths(agentA, agentC, maxDepth);
if (paths.length === 0) {
return 0; // No trust path
}
// Calculate trust for each path
const pathTrusts = paths.map(path => this.pathTrust(path));
// Return maximum trust path
return Math.max(...pathTrusts);
}
pathTrust(path) {
let trust = 1.0;
for (let i = 0; i < path.length - 1; i++) {
const edgeTrust = this.getDirectTrust(path[i], path[i + 1]);
trust *= edgeTrust;
}
// Decay with path length
const decay = Math.pow(0.8, path.length - 1);
return trust * decay;
}
findPaths(start, end, maxDepth) {
const paths = [];
const visited = new Set();
const dfs = (current, target, path, depth) => {
if (current === target) {
paths.push([...path]);
return;
}
if (depth >= maxDepth) return;
if (visited.has(current)) return;
visited.add(current);
const neighbors = this.trustEdges.get(current);
if (neighbors) {
for (const [neighbor, trust] of neighbors) {
if (trust > 0.3) { // Only follow strong trust edges
path.push(neighbor);
dfs(neighbor, target, path, depth + 1);
path.pop();
}
}
}
visited.delete(current);
};
dfs(start, end, [start], 0);
return paths;
}
}
// 弘益人間: Building trust networks for community benefit
Protecting message confidentiality and integrity is critical:
class SecureAgentCommunication {
constructor(privateKey, publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
this.crypto = require('crypto');
}
// Encrypt and sign message
sendSecureMessage(recipientPublicKey, message) {
// 1. Generate symmetric key for this message
const symmetricKey = this.crypto.randomBytes(32);
const iv = this.crypto.randomBytes(16);
// 2. Encrypt message with symmetric key
const cipher = this.crypto.createCipheriv('aes-256-gcm', symmetricKey, iv);
let encrypted = cipher.update(JSON.stringify(message), 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
// 3. Encrypt symmetric key with recipient's public key
const encryptedKey = this.crypto.publicEncrypt(
recipientPublicKey,
symmetricKey
);
// 4. Sign the package
const sign = this.crypto.createSign('SHA256');
sign.update(encrypted + iv.toString('hex') + authTag.toString('hex'));
const signature = sign.sign(this.privateKey, 'hex');
return {
encryptedMessage: encrypted,
encryptedKey: encryptedKey.toString('hex'),
iv: iv.toString('hex'),
authTag: authTag.toString('hex'),
signature: signature,
senderPublicKey: this.publicKey
};
}
// Decrypt and verify message
receiveSecureMessage(secureMessage) {
// 1. Verify signature
const verify = this.crypto.createVerify('SHA256');
verify.update(
secureMessage.encryptedMessage +
secureMessage.iv +
secureMessage.authTag
);
if (!verify.verify(secureMessage.senderPublicKey, secureMessage.signature, 'hex')) {
throw new Error('Invalid signature');
}
// 2. Decrypt symmetric key
const symmetricKey = this.crypto.privateDecrypt(
this.privateKey,
Buffer.from(secureMessage.encryptedKey, 'hex')
);
// 3. Decrypt message
const decipher = this.crypto.createDecipheriv(
'aes-256-gcm',
symmetricKey,
Buffer.from(secureMessage.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(secureMessage.authTag, 'hex'));
let decrypted = decipher.update(secureMessage.encryptedMessage, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
}
// 弘益人間: Secure communication protecting all agents
Systems must detect and isolate malicious agents:
class MaliciousAgentDetector {
constructor() {
this.behaviorProfiles = new Map();
this.anomalyThreshold = 0.7;
this.quarantined = new Set();
}
recordBehavior(agentId, behavior) {
if (!this.behaviorProfiles.has(agentId)) {
this.behaviorProfiles.set(agentId, {
messageFrequency: [],
failureRate: [],
resourceUsage: [],
interactionPatterns: []
});
}
const profile = this.behaviorProfiles.get(agentId);
profile.messageFrequency.push(behavior.messagesPerMinute || 0);
profile.failureRate.push(behavior.failureRate || 0);
profile.resourceUsage.push(behavior.resourceUsage || 0);
// Keep only recent history
const maxHistory = 100;
Object.keys(profile).forEach(key => {
if (profile[key].length > maxHistory) {
profile[key].shift();
}
});
// Check for anomalies
const anomalyScore = this.detectAnomaly(agentId);
if (anomalyScore > this.anomalyThreshold) {
this.flagMalicious(agentId, anomalyScore);
}
}
detectAnomaly(agentId) {
const profile = this.behaviorProfiles.get(agentId);
if (!profile) return 0;
let anomalyScore = 0;
// Check message frequency
const avgFreq = this.average(profile.messageFrequency);
const stdFreq = this.stdDev(profile.messageFrequency);
const recentFreq = profile.messageFrequency.slice(-10);
const recentAvg = this.average(recentFreq);
if (recentAvg > avgFreq + 3 * stdFreq) {
anomalyScore += 0.3; // Unusual message rate
}
// Check failure rate
const recentFailures = this.average(profile.failureRate.slice(-10));
if (recentFailures > 0.5) {
anomalyScore += 0.3; // High failure rate
}
// Check resource usage
const recentUsage = this.average(profile.resourceUsage.slice(-10));
const avgUsage = this.average(profile.resourceUsage);
if (recentUsage > avgUsage * 3) {
anomalyScore += 0.4; // Excessive resource usage
}
return Math.min(1.0, anomalyScore);
}
flagMalicious(agentId, score) {
console.warn(`Agent ${agentId} flagged as potentially malicious (score: ${score})`);
this.quarantined.add(agentId);
// Notify system administrators
this.notifyAdministrators({
agentId: agentId,
reason: 'Anomalous behavior detected',
anomalyScore: score,
timestamp: Date.now()
});
}
isQuarantined(agentId) {
return this.quarantined.has(agentId);
}
average(arr) {
return arr.length > 0 ? arr.reduce((sum, val) => sum + val, 0) / arr.length : 0;
}
stdDev(arr) {
const avg = this.average(arr);
const squareDiffs = arr.map(val => Math.pow(val - avg, 2));
return Math.sqrt(this.average(squareDiffs));
}
}
// 弘익人間: Protecting the community from malicious actors
Fine-grained access control ensures agents can only access authorized resources:
class RoleBasedAccessControl {
constructor() {
this.roles = new Map();
this.permissions = new Map();
this.agentRoles = new Map();
}
defineRole(roleName, permissions) {
this.roles.set(roleName, permissions);
}
assignRole(agentId, roleName) {
if (!this.roles.has(roleName)) {
throw new Error(`Role ${roleName} not defined`);
}
if (!this.agentRoles.has(agentId)) {
this.agentRoles.set(agentId, new Set());
}
this.agentRoles.get(agentId).add(roleName);
}
hasPermission(agentId, permission) {
const roles = this.agentRoles.get(agentId);
if (!roles) return false;
for (const roleName of roles) {
const rolePerms = this.roles.get(roleName);
if (rolePerms && rolePerms.includes(permission)) {
return true;
}
}
return false;
}
checkAccess(agentId, resource, action) {
const permission = `${resource}:${action}`;
if (!this.hasPermission(agentId, permission)) {
throw new Error(`Access denied: ${agentId} cannot ${action} ${resource}`);
}
return true;
}
}
// Example usage
const rbac = new RoleBasedAccessControl();
// Define roles
rbac.defineRole('admin', ['*:*']); // All permissions
rbac.defineRole('worker', ['tasks:read', 'tasks:execute', 'messages:send']);
rbac.defineRole('observer', ['tasks:read', 'messages:read']);
// Assign roles
rbac.assignRole('agent-001', 'admin');
rbac.assignRole('agent-002', 'worker');
rbac.assignRole('agent-003', 'observer');
// Check access
rbac.checkAccess('agent-002', 'tasks', 'execute'); // OK
// rbac.checkAccess('agent-003', 'tasks', 'execute'); // Error
// 弘익人間: Fair access control protecting shared resources