UNPKG

pm-orchestrator-enhancement

Version:

PM Orchestrator Enhancement - Multi-agent parallel execution system

221 lines 7.18 kB
"use strict"; /** * Permission Checker Module * * サブエージェントの権限管理とアクセス制御を提供します。 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.PermissionChecker = void 0; class PermissionChecker { constructor() { this.roles = new Map(); this.agentRoles = new Map(); this.initializeDefaultRoles(); } /** * デフォルトロールの初期化 */ initializeDefaultRoles() { // Read-only role this.defineRole({ name: 'readonly', permissions: [ { resource: '*', action: 'read' } ] }); // Developer role this.defineRole({ name: 'developer', permissions: [ { resource: 'src/**', action: 'read' }, { resource: 'src/**', action: 'write' }, { resource: 'tests/**', action: 'read' }, { resource: 'tests/**', action: 'write' }, { resource: 'package.json', action: 'read' } ] }); // Admin role this.defineRole({ name: 'admin', permissions: [ { resource: '*', action: 'read' }, { resource: '*', action: 'write' }, { resource: '*', action: 'execute' }, { resource: '.env', action: 'delete', condition: (ctx) => ctx.confirmed === true } ] }); // Quality Checker role this.defineRole({ name: 'quality-checker', permissions: [ { resource: '**/*.ts', action: 'read' }, { resource: '**/*.js', action: 'read' }, { resource: 'tests/**', action: 'execute' } ] }); // Implementer role this.defineRole({ name: 'implementer', permissions: [ { resource: 'src/**', action: 'read' }, { resource: 'src/**', action: 'write' }, { resource: 'tests/**', action: 'read' }, { resource: 'tests/**', action: 'write' } ] }); } /** * ロールを定義 */ defineRole(role) { this.roles.set(role.name, role); } /** * エージェントにロールを割り当て */ assignRole(agentName, roleName) { const currentRoles = this.agentRoles.get(agentName) || []; if (!currentRoles.includes(roleName)) { currentRoles.push(roleName); this.agentRoles.set(agentName, currentRoles); } } /** * エージェントのロールを取得 */ getAgentRoles(agentName) { return this.agentRoles.get(agentName) || []; } /** * アクセス権限をチェック */ checkAccess(context) { const roles = this.getAgentRoles(context.agentName); if (roles.length === 0) { // ロールが割り当てられていない場合、デフォルトでreadonly roles.push('readonly'); } // 各ロールの権限をチェック for (const roleName of roles) { const role = this.roles.get(roleName); if (!role) { continue; } // ロールの権限をチェック for (const permission of role.permissions) { if (this.matchesPermission(context, permission)) { return true; } } } return false; } /** * 権限がコンテキストにマッチするかチェック */ matchesPermission(context, permission) { // アクションが一致するかチェック if (permission.action !== context.action) { return false; } // リソースパターンが一致するかチェック if (!this.matchesResource(context.resource, permission.resource)) { return false; } // 条件が設定されている場合はチェック if (permission.condition) { return permission.condition(context.metadata || {}); } return true; } /** * リソースパターンマッチング */ matchesResource(resource, pattern) { // ワイルドカード "*" は全てにマッチ if (pattern === '*') { return true; } // "**" は任意のディレクトリ深度にマッチ const regexPattern = pattern .replace(/\*\*/g, '.*') // ** → .* .replace(/\*/g, '[^/]*') // * → [^/]* .replace(/\./g, '\\.'); // . → \. const regex = new RegExp(`^${regexPattern}$`); return regex.test(resource); } /** * エージェントのアクセス可能なリソースを取得 */ getAccessibleResources(agentName, action) { const roles = this.getAgentRoles(agentName); const resources = new Set(); for (const roleName of roles) { const role = this.roles.get(roleName); if (!role) { continue; } for (const permission of role.permissions) { if (permission.action === action) { resources.add(permission.resource); } } } return Array.from(resources); } /** * アクセス拒否の理由を取得 */ getAccessDenialReason(context) { const roles = this.getAgentRoles(context.agentName); if (roles.length === 0) { return `Agent "${context.agentName}" has no assigned roles`; } const roleNames = roles.join(', '); return `Agent "${context.agentName}" with roles [${roleNames}] does not have permission to ${context.action} "${context.resource}"`; } /** * 全ロールを取得 */ getAllRoles() { return Array.from(this.roles.values()); } /** * ロールを削除 */ removeRole(roleName) { return this.roles.delete(roleName); } /** * エージェントのロールを削除 */ revokeRole(agentName, roleName) { const roles = this.agentRoles.get(agentName); if (!roles) { return false; } const index = roles.indexOf(roleName); if (index === -1) { return false; } roles.splice(index, 1); if (roles.length === 0) { this.agentRoles.delete(agentName); } return true; } /** * 権限チェック結果をログ */ logAccessCheck(context, allowed) { const timestamp = new Date().toISOString(); const status = allowed ? 'ALLOWED' : 'DENIED'; const message = `[${timestamp}] ${status}: ${context.agentName} ${context.action} ${context.resource}`; console.log(message); if (!allowed) { console.log(` Reason: ${this.getAccessDenialReason(context)}`); } } } exports.PermissionChecker = PermissionChecker; //# sourceMappingURL=permission-checker.js.map