PBAC

정책 기반 접근 제어(Policy-Based Access Control, PBAC) 중앙에서 정의된 정책들을 기반으로 접근 권한을 결정하는 접근 제어 방식. 각 정책은 “누가”, “무엇을”, “어떤 조건에서” 할 수 있는지를 정의하며, 이러한 정책들은 프로그래밍 방식으로 표현되고 평가된다. 현대적인 클라우드 환경이나 마이크로서비스 아키텍처에서 특히 유용하다. AWS IAM, Azure RBAC 등의 클라우드 서비스들이 PBAC를 구현한 대표적인 예시. 작동 방식: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 class Policy { constructor(name, conditions, effect) { this.name = name; this.conditions = conditions; this.effect = effect; // 'allow' 또는 'deny' } evaluate(context) { try { // 모든 조건을 평가 return this.conditions.every(condition => condition(context)); } catch (error) { console.error(`Policy evaluation error: ${error.message}`); return false; } } } class PolicyEngine { constructor() { this.policies = new Map(); } addPolicy(policy) { this.policies.set(policy.name, policy); } evaluateAccess(context) { let finalDecision = false; for (const policy of this.policies.values()) { const matches = policy.evaluate(context); if (matches) { finalDecision = policy.effect === 'allow'; // 명시적인 거부 정책이 있으면 즉시 거부 if (policy.effect === 'deny') { return false; } } } return finalDecision; } } // 정책 조건 예시들 const conditions = { isWorkingHours: (context) => { const hour = context.time.getHours(); return hour >= 9 && hour < 18; }, isInternalNetwork: (context) => { return context.ipAddress.startsWith('192.168.'); }, hasRole: (role) => (context) => { return context.user.roles.includes(role); }, hasPermission: (permission) => (context) => { return context.user.permissions.includes(permission); } }; // 정책 엔진 사용 예시 const policyEngine = new PolicyEngine(); // HR 문서 접근 정책 const hrDocumentPolicy = new Policy( 'HR_Document_Access', [ conditions.isWorkingHours, conditions.isInternalNetwork, conditions.hasRole('HR'), conditions.hasPermission('read_hr_documents') ], 'allow' ); // 주말 접근 제한 정책 const weekendRestrictionPolicy = new Policy( 'Weekend_Restriction', [ (context) => { const day = context.time.getDay(); return day === 0 || day === 6; } ], 'deny' ); policyEngine.addPolicy(hrDocumentPolicy); policyEngine.addPolicy(weekendRestrictionPolicy); // 접근 시도 예시 const accessContext = { user: { name: 'Alice', roles: ['HR'], permissions: ['read_hr_documents'] }, time: new Date('2024-12-17T14:00:00'), // 평일 오후 2시 ipAddress: '192.168.1.100', resource: 'employee_records' }; const hasAccess = policyEngine.evaluateAccess(accessContext); console.log(`Access granted: ${hasAccess}`); 주요 특징 유연성: 다양한 조건과 규칙을 조합하여 세밀한 접근 제어가 가능하다. 중앙 집중식 관리: 정책을 중앙에서 관리하여 일관성을 유지하고 관리를 용이하게 한다. 컨텍스트 인식: 사용자 신원, 리소스 특성, 시간, 위치 등 다양한 컨텍스트 정보를 고려한다. 동적 평가: 접근 요청 시 실시간으로 정책을 평가하여 결정을 내린다. 장점 세밀한 접근 제어: 복잡한 비즈니스 규칙과 요구사항을 정책에 반영할 수 있다. 변화에 대한 빠른 대응: 정책 변경만으로 접근 제어 로직을 신속하게 수정할 수 있다. 일관성 유지: 중앙에서 관리되는 정책으로 전체 시스템의 일관성을 보장한다. 예시 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 class AdvancedPolicyEngine { constructor() { this.policies = new Map(); this.auditLog = []; } addPolicy(policy) { this.policies.set(policy.name, policy); } async evaluateAccess(context) { const decisions = []; const startTime = Date.now(); try { for (const policy of this.policies.values()) { const decision = { policyName: policy.name, effect: policy.effect, matches: await policy.evaluate(context), timestamp: new Date() }; decisions.push(decision); if (decision.matches && policy.effect === 'deny') { this.logDecision(context, decisions, 'denied'); return false; } } const finalDecision = decisions.some(d => d.matches && d.effect === 'allow'); this.logDecision(context, decisions, finalDecision ? 'allowed' : 'denied'); return finalDecision; } catch (error) { this.logError(context, error); throw error; } } logDecision(context, decisions, result) { const logEntry = { timestamp: new Date(), user: context.user.name, resource: context.resource, action: context.action, decisions: decisions, finalResult: result, contextSnapshot: { …context } }; this.auditLog.push(logEntry); } logError(context, error) { const errorEntry = { timestamp: new Date(), type: 'error', user: context.user.name, error: error.message, stack: error.stack, context: { …context } }; this.auditLog.push(errorEntry); } getAuditLog(filters = {}) { return this.auditLog.filter(entry => { return Object.entries(filters).every(([key, value]) => entry[key] === value ); }); } } 참고 및 출처

November 6, 2024 · 4 min · Me