UNPKG

@kya-os/mcp-i

Version:

COMING SOON:Production-ready MCP Identity with automatic registration, key rotation, and optimized performance

133 lines 4.55 kB
/** * Key rotation support for MCP-I */ import { generateKeyPair, sign } from './crypto.js'; export class KeyRotationManager { identity; transport; policy; signatureCount = 0; keyCreatedAt; lastRotatedAt; constructor(identity, transport, policy = {}) { this.identity = identity; this.transport = transport; this.policy = policy; this.keyCreatedAt = new Date(identity.registeredAt); } /** * Check key health and rotation needs */ checkKeyHealth() { const now = new Date(); const age = now.getTime() - this.keyCreatedAt.getTime(); const maxAge = this.policy.maxAge || 90 * 24 * 60 * 60 * 1000; // 90 days default const maxSignatures = this.policy.maxSignatures || 1000000; // 1M default const shouldRotate = age > maxAge || this.signatureCount > maxSignatures; return { age, signatureCount: this.signatureCount, shouldRotate, lastRotated: this.lastRotatedAt }; } /** * Increment signature count */ incrementSignatureCount() { this.signatureCount++; } /** * Rotate keys with the registry */ async rotateKeys(reason = 'scheduled') { try { // Generate new key pair const newKeyPair = await generateKeyPair(); // Create rotation request const timestamp = Date.now(); const message = `rotate-keys:${this.identity.did}:${timestamp}:${reason}`; const signature = await sign(message, this.identity.privateKey); // Prepare rotation payload const rotationRequest = { newPublicKey: { type: 'Ed25519VerificationKey2020', publicKeyBase64: newKeyPair.publicKey }, rotationReason: reason, signedStatement: signature, timestamp }; // Get the correct registry URL const registryUrl = this.getRegistryUrl(); const agentId = this.extractAgentId(); // Submit rotation request const response = await this.transport.post(`${registryUrl}/api/agents/${agentId}/rotate-key`, rotationRequest, { headers: { 'Authorization': `DID-Auth ${signature}`, 'Content-Type': 'application/json' } }); if (response.data.success) { // Update local identity with new keys this.identity.publicKey = newKeyPair.publicKey; this.identity.privateKey = newKeyPair.privateKey; this.lastRotatedAt = new Date(); this.keyCreatedAt = new Date(); this.signatureCount = 0; return { success: true, newKeyId: response.data.newKeyId, oldKeyId: response.data.oldKeyId, gracePeriodEnd: new Date(response.data.gracePeriodEnd) }; } else { return { success: false, error: response.data.error || 'Key rotation failed' }; } } catch (error) { return { success: false, error: error.message || 'Key rotation error' }; } } /** * Setup automatic rotation based on policy */ setupAutoRotation(callback) { const checkInterval = 24 * 60 * 60 * 1000; // Check daily return setInterval(async () => { const health = this.checkKeyHealth(); if (health.shouldRotate) { const result = await this.rotateKeys('auto-rotation'); if (callback) { callback(result); } } }, checkInterval); } /** * Get registry URL based on DID host */ getRegistryUrl() { // Always use knowthat.ai as the registry return 'https://knowthat.ai'; } /** * Extract agent ID from DID or identity */ extractAgentId() { if (this.identity.agentId) { return this.identity.agentId; } // Extract from DID (e.g., did:web:knowthat.ai:agents:my-agent -> my-agent) const parts = this.identity.did.split(':'); return parts[parts.length - 1]; } } //# sourceMappingURL=rotation.js.map