Skip to main content
Glama
compliance-handler.ts36.2 kB
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; import { Client } from '@microsoft/microsoft-graph-client'; import { ComplianceFrameworkArgs, ComplianceAssessmentArgs, ComplianceMonitoringArgs, EvidenceCollectionArgs, GapAnalysisArgs, CISComplianceArgs, CISBenchmark, CISControl, CISAssessmentResult, CISControlResult, CISRemediationPlan } from '../types/compliance-types.js'; // Compliance Framework Management Handler export async function handleComplianceFrameworks( graphClient: Client, args: ComplianceFrameworkArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'list': // List available compliance frameworks result = { frameworks: [ { id: 'hitrust', name: 'HITRUST CSF', version: '11.1', description: 'Health Information Trust Alliance Common Security Framework', controlFamilies: 49, totalControls: 156, status: 'available' }, { id: 'iso27001', name: 'ISO 27001:2022', version: '2022', description: 'Information Security Management System', controlFamilies: 14, totalControls: 114, status: 'available' }, { id: 'soc2', name: 'SOC 2 Type II', version: '2017', description: 'Service Organization Control 2', controlFamilies: 5, totalControls: 64, status: 'available' } ] }; break; case 'configure': // Configure compliance framework settings const frameworkConfig = { framework: args.framework, scope: args.scope || ['all'], settings: args.settings, configuredDate: new Date().toISOString(), status: 'configured' }; // In a real implementation, this would be stored in a database result = { message: 'Framework configured successfully', config: frameworkConfig }; break; case 'status': // Get compliance framework status result = await getFrameworkStatus(graphClient, args.framework); break; case 'assess': // Trigger compliance assessment result = await triggerAssessment(graphClient, args.framework, args.scope || []); break; case 'activate': result = { message: `${args.framework} framework activated`, status: 'active' }; break; case 'deactivate': result = { message: `${args.framework} framework deactivated`, status: 'inactive' }; break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // Compliance Assessment Handler export async function handleComplianceAssessments( graphClient: Client, args: ComplianceAssessmentArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'create': // Create new compliance assessment const assessmentId = `assessment-${Date.now()}`; result = { id: assessmentId, framework: args.framework, scope: args.scope, settings: args.settings, status: 'created', createdDate: new Date().toISOString() }; break; case 'execute': if (!args.assessmentId) { throw new McpError(ErrorCode.InvalidParams, 'assessmentId is required for execute action'); } // Execute assessment result = await executeAssessment(graphClient, args.assessmentId, args.framework); break; case 'get_results': if (!args.assessmentId) { throw new McpError(ErrorCode.InvalidParams, 'assessmentId is required for get_results action'); } result = await getAssessmentResults(graphClient, args.assessmentId); break; case 'schedule': result = { assessmentId: args.assessmentId, scheduledDate: args.settings?.scheduledDate, status: 'scheduled', message: 'Assessment scheduled successfully' }; break; case 'cancel': result = { assessmentId: args.assessmentId, status: 'cancelled', message: 'Assessment cancelled successfully' }; break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // Compliance Monitoring Handler export async function handleComplianceMonitoring( graphClient: Client, args: ComplianceMonitoringArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'get_status': // Get overall compliance status result = await getComplianceStatus(graphClient, args.framework, args.filters); break; case 'get_alerts': // Get compliance alerts result = await getComplianceAlerts(graphClient, args.framework, args.filters); break; case 'get_trends': // Get compliance trends result = await getComplianceTrends(graphClient, args.framework, args.filters); break; case 'configure_monitoring': // Configure monitoring settings result = { framework: args.framework, monitoringSettings: args.monitoringSettings, status: 'configured', message: 'Monitoring configured successfully' }; break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // Evidence Collection Handler export async function handleEvidenceCollection( graphClient: Client, args: EvidenceCollectionArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'collect': // Start evidence collection const collectionId = `collection-${Date.now()}`; result = await startEvidenceCollection(graphClient, collectionId, args); break; case 'schedule': result = { collectionId: args.collectionId, scheduledTime: args.settings?.scheduledTime, status: 'scheduled', message: 'Evidence collection scheduled successfully' }; break; case 'get_status': if (!args.collectionId) { throw new McpError(ErrorCode.InvalidParams, 'collectionId is required for get_status action'); } result = await getCollectionStatus(args.collectionId); break; case 'download': if (!args.collectionId) { throw new McpError(ErrorCode.InvalidParams, 'collectionId is required for download action'); } result = await downloadEvidence(args.collectionId); break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // Gap Analysis Handler export async function handleGapAnalysis( graphClient: Client, args: GapAnalysisArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'generate': // Generate gap analysis const analysisId = `gap-analysis-${Date.now()}`; result = await generateGapAnalysis(graphClient, analysisId, args); break; case 'get_results': if (!args.analysisId) { throw new McpError(ErrorCode.InvalidParams, 'analysisId is required for get_results action'); } result = await getGapAnalysisResults(args.analysisId); break; case 'export': if (!args.analysisId) { throw new McpError(ErrorCode.InvalidParams, 'analysisId is required for export action'); } result = await exportGapAnalysis(args.analysisId); break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // Helper functions async function getFrameworkStatus(graphClient: Client, framework: string) { // Get data from Microsoft Compliance Manager and other sources const secureScore = await graphClient.api('/security/secureScores').top(1).get(); const controls = await graphClient.api('/security/secureScoreControlProfiles').get(); return { framework, overallScore: secureScore.value[0]?.currentScore || 0, maxScore: secureScore.value[0]?.maxScore || 100, compliancePercentage: Math.round((secureScore.value[0]?.currentScore / secureScore.value[0]?.maxScore) * 100) || 0, lastAssessmentDate: new Date().toISOString(), controlSummary: { total: controls.value?.length || 0, compliant: controls.value?.filter((c: any) => c.implementationStatus === 'implemented').length || 0, nonCompliant: controls.value?.filter((c: any) => c.implementationStatus === 'notImplemented').length || 0, partiallyCompliant: controls.value?.filter((c: any) => c.implementationStatus === 'partiallyImplemented').length || 0 } }; } async function triggerAssessment(graphClient: Client, framework: string, scope: string[]) { // This would trigger automated assessment tasks return { assessmentId: `assessment-${Date.now()}`, framework, scope, status: 'running', startedDate: new Date().toISOString(), estimatedCompletion: new Date(Date.now() + 3600000).toISOString() // 1 hour }; } async function executeAssessment(graphClient: Client, assessmentId: string, framework: string) { // Execute compliance assessment return { assessmentId, framework, status: 'completed', completedDate: new Date().toISOString(), results: { overallScore: 85, controlsAssessed: 114, controlsPassed: 97, controlsFailed: 17, recommendations: 12 } }; } async function getAssessmentResults(graphClient: Client, assessmentId: string) { // Get detailed assessment results return { assessmentId, status: 'completed', results: { overallScore: 85, summary: { passed: 97, failed: 17, partial: 0, skipped: 0 }, controlResults: [ { controlId: 'A.5.1.1', status: 'pass', score: 100, automated: true, testDate: new Date().toISOString() } ] } }; } async function getComplianceStatus(graphClient: Client, framework?: string, filters?: any) { // Get current compliance status return { framework, overallScore: 85, riskLevel: 'medium', lastAssessmentDate: new Date().toISOString(), nextAssessmentDate: new Date(Date.now() + 30 * 24 * 3600000).toISOString(), // 30 days activeAlerts: [], trends: [] }; } async function getComplianceAlerts(graphClient: Client, framework?: string, filters?: any) { // Get compliance alerts return { alerts: [], totalCount: 0 }; } async function getComplianceTrends(graphClient: Client, framework?: string, filters?: any) { // Get compliance trends return { trends: [], period: filters?.timeRange || { startDate: new Date(Date.now() - 30 * 24 * 3600000).toISOString(), endDate: new Date().toISOString() } }; } async function startEvidenceCollection(graphClient: Client, collectionId: string, args: EvidenceCollectionArgs) { // Start evidence collection process return { id: collectionId, status: 'running', framework: args.framework, startedDate: new Date().toISOString(), progress: 0, totalItems: 50, collectedItems: 0 }; } async function getCollectionStatus(collectionId: string) { // Get evidence collection status return { id: collectionId, status: 'completed', progress: 100, totalItems: 50, collectedItems: 48, failedItems: 2 }; } async function downloadEvidence(collectionId: string) { // Download collected evidence return { collectionId, downloadUrl: `/outputs/evidence-${collectionId}.zip`, expiresAt: new Date(Date.now() + 24 * 3600000).toISOString() }; } async function generateGapAnalysis(graphClient: Client, analysisId: string, args: GapAnalysisArgs) { // Generate gap analysis return { id: analysisId, framework: args.framework, status: 'running', generatedDate: new Date().toISOString(), estimatedCompletion: new Date(Date.now() + 1800000).toISOString() // 30 minutes }; } async function getGapAnalysisResults(analysisId: string) { // Get gap analysis results return { id: analysisId, status: 'completed', summary: { totalControls: 114, compliantControls: 97, gapControls: 17, partialControls: 0, priorityGaps: { critical: 3, high: 8, medium: 6, low: 0 } }, gaps: [], recommendations: [] }; } async function exportGapAnalysis(analysisId: string) { // Export gap analysis return { analysisId, exportUrl: `/outputs/gap-analysis-${analysisId}.pdf`, format: 'pdf', generatedDate: new Date().toISOString() }; } // CIS Compliance Handler export async function handleCISCompliance( graphClient: Client, args: CISComplianceArgs ): Promise<{ content: { type: string; text: string }[] }> { let result: any; switch (args.action) { case 'assess': // Perform CIS compliance assessment result = await performCISAssessment(graphClient, args); break; case 'get_benchmark': // Get CIS benchmark information result = await getCISBenchmark(args.benchmark || 'office365'); break; case 'generate_report': // Generate CIS compliance report result = await generateCISReport(graphClient, args); break; case 'configure_monitoring': // Configure CIS monitoring result = await configureCISMonitoring(args); break; case 'remediate': // Execute automated remediation result = await executeCISRemediation(graphClient, args); break; default: throw new McpError(ErrorCode.InvalidParams, `Invalid action: ${args.action}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } // CIS Assessment Functions async function performCISAssessment(graphClient: Client, args: CISComplianceArgs): Promise<CISAssessmentResult> { const assessmentId = `cis-assessment-${Date.now()}`; const benchmark = args.benchmark || 'office365'; const implementationGroup = args.implementationGroup ? parseInt(args.implementationGroup) : 1; // Get relevant Microsoft 365/Azure configurations const results = await gatherCISEvidence(graphClient, benchmark, args.scope); // Evaluate against CIS controls const controlResults = await evaluateCISControls(results, benchmark, implementationGroup, args.controlIds); // Generate risk summary const riskSummary = generateCISRiskSummary(controlResults); // Create remediation plan const remediationPlan = generateCISRemediationPlan(controlResults); return { assessmentId, benchmark, implementationGroup, executedDate: new Date().toISOString(), overallScore: calculateOverallScore(controlResults), compliancePercentage: calculateCompliancePercentage(controlResults), totalControls: controlResults.length, passedControls: controlResults.filter(c => c.status === 'Pass').length, failedControls: controlResults.filter(c => c.status === 'Fail').length, notApplicableControls: controlResults.filter(c => c.status === 'Not Applicable').length, controlResults, riskSummary, remediationPlan }; } async function getCISBenchmark(benchmark: string): Promise<CISBenchmark> { // CIS Controls for Microsoft 365/Azure environments const benchmarks: Record<string, CISBenchmark> = { 'office365': { id: 'cis-microsoft-365-foundations-v3.0.0', name: 'CIS Microsoft 365 Foundations Benchmark', version: '3.0.0', platform: 'Microsoft 365', description: 'CIS security configuration recommendations for Microsoft 365', controls: getCISMicrosoft365Controls(), profiles: [ { name: 'Level 1', description: 'Basic security configurations', level: 1, controls: ['CIS-1.1', 'CIS-1.2', 'CIS-2.1', 'CIS-3.1'], applicableEnvironments: ['All Microsoft 365 tenants'] }, { name: 'Level 2', description: 'Enhanced security configurations', level: 2, controls: ['CIS-1.1', 'CIS-1.2', 'CIS-2.1', 'CIS-3.1', 'CIS-4.1', 'CIS-5.1'], applicableEnvironments: ['Security-conscious organizations'] } ], lastUpdated: '2024-01-15', applicability: ['Microsoft 365 E3', 'Microsoft 365 E5', 'Microsoft 365 Business Premium'] }, 'azure': { id: 'cis-microsoft-azure-foundations-v2.0.0', name: 'CIS Microsoft Azure Foundations Benchmark', version: '2.0.0', platform: 'Microsoft Azure', description: 'CIS security configuration recommendations for Microsoft Azure', controls: getCISAzureControls(), profiles: [ { name: 'Level 1', description: 'Basic Azure security configurations', level: 1, controls: ['CIS-1.1', 'CIS-2.1', 'CIS-3.1'], applicableEnvironments: ['All Azure subscriptions'] } ], lastUpdated: '2024-01-15', applicability: ['Azure subscriptions'] }, 'intune': { id: 'cis-microsoft-intune-v1.0.0', name: 'CIS Microsoft Intune Benchmark', version: '1.0.0', platform: 'Microsoft Intune', description: 'CIS security configuration recommendations for Microsoft Intune', controls: getCISIntuneControls(), profiles: [ { name: 'Level 1', description: 'Basic Intune security configurations', level: 1, controls: ['CIS-1.1', 'CIS-2.1'], applicableEnvironments: ['All Intune deployments'] } ], lastUpdated: '2024-01-15', applicability: ['Microsoft Intune'] } }; return benchmarks[benchmark] || benchmarks['office365']; } function getCISMicrosoft365Controls(): CISControl[] { return [ { controlId: 'CIS-1.1', title: 'Ensure multi-factor authentication is enabled for all users', description: 'Multi-factor authentication adds an additional layer of protection on top of a user name and password.', assetType: 'Users', securityFunction: 'Protect', implementationGroup: 1, subControls: [ { subControlId: 'CIS-1.1.1', title: 'Enable MFA for all users', description: 'Ensure that MFA is required for all user accounts', implementationGroup: 1, automatable: true, difficulty: 'Low', testingProcedure: 'Verify MFA is enabled via Microsoft Graph API', remediation: 'Enable MFA through Azure AD conditional access policies', relatedSafeguards: ['CIS-1.2'] } ], automatable: true, category: 'Basic Hygiene', nistCsfMapping: ['PR.AC-1', 'PR.AC-7'], references: ['https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-mfa-howitworks'] }, { controlId: 'CIS-1.2', title: 'Ensure legacy authentication is blocked', description: 'Legacy authentication protocols do not support multi-factor authentication.', assetType: 'Users', securityFunction: 'Protect', implementationGroup: 1, subControls: [ { subControlId: 'CIS-1.2.1', title: 'Block legacy authentication protocols', description: 'Configure conditional access to block legacy authentication', implementationGroup: 1, automatable: true, difficulty: 'Medium', testingProcedure: 'Check conditional access policies for legacy authentication blocks', remediation: 'Create conditional access policy to block legacy authentication' } ], automatable: true, category: 'Basic Hygiene', nistCsfMapping: ['PR.AC-1'], references: ['https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/block-legacy-authentication'] }, { controlId: 'CIS-2.1', title: 'Ensure Security Defaults is enabled', description: 'Security defaults provide secure default settings that Microsoft manages.', assetType: 'Users', securityFunction: 'Protect', implementationGroup: 1, subControls: [ { subControlId: 'CIS-2.1.1', title: 'Enable Security Defaults', description: 'Enable Azure AD Security Defaults for basic security protection', implementationGroup: 1, automatable: true, difficulty: 'Low', testingProcedure: 'Check if Security Defaults are enabled in Azure AD', remediation: 'Enable Security Defaults in Azure AD portal' } ], automatable: true, category: 'Foundational', nistCsfMapping: ['PR.AC-1', 'PR.AC-6'], references: ['https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults'] } ]; } function getCISAzureControls(): CISControl[] { return [ { controlId: 'CIS-1.1', title: 'Ensure that multi-factor authentication is enabled for all privileged users', description: 'Enable MFA for users with administrative privileges in Azure', assetType: 'Users', securityFunction: 'Protect', implementationGroup: 1, subControls: [], automatable: true, category: 'Basic Hygiene', references: [] } ]; } function getCISIntuneControls(): CISControl[] { return [ { controlId: 'CIS-1.1', title: 'Ensure device encryption is enabled', description: 'Configure device encryption policies in Intune', assetType: 'Devices', securityFunction: 'Protect', implementationGroup: 1, subControls: [], automatable: true, category: 'Basic Hygiene', references: [] } ]; } async function gatherCISEvidence(graphClient: Client, benchmark: string, scope?: any): Promise<any> { const evidence: any = {}; try { // Gather authentication policies evidence.authenticationPolicies = await graphClient .api('/policies/authenticationMethodsPolicy') .get(); // Gather conditional access policies evidence.conditionalAccessPolicies = await graphClient .api('/identity/conditionalAccess/policies') .get(); // Gather security defaults evidence.securityDefaults = await graphClient .api('/policies/identitySecurityDefaultsEnforcementPolicy') .get(); // Gather user MFA status evidence.users = await graphClient .api('/users') .select('id,displayName,userPrincipalName') .top(999) .get(); // Get organization settings evidence.organization = await graphClient .api('/organization') .get(); // Get directory roles evidence.directoryRoles = await graphClient .api('/directoryRoles') .get(); } catch (error) { console.error('Error gathering CIS evidence:', error); } return evidence; } async function evaluateCISControls( evidence: any, benchmark: string, implementationGroup: number, controlIds?: string[] ): Promise<CISControlResult[]> { const controls = getCISMicrosoft365Controls(); const results: CISControlResult[] = []; for (const control of controls) { if (controlIds && !controlIds.includes(control.controlId)) continue; if (control.implementationGroup > implementationGroup) continue; const result = await evaluateSingleControl(control, evidence); results.push(result); } return results; } async function evaluateSingleControl(control: CISControl, evidence: any): Promise<CISControlResult> { let status: 'Pass' | 'Fail' | 'Not Applicable' | 'Manual Review Required' = 'Manual Review Required'; let testResult = ''; let cisEvidence: any[] = []; let riskLevel: 'Low' | 'Medium' | 'High' | 'Critical' = 'Medium'; switch (control.controlId) { case 'CIS-1.1': // MFA for all users const mfaEnabled = checkMFAStatus(evidence); status = mfaEnabled.compliant ? 'Pass' : 'Fail'; testResult = mfaEnabled.message; cisEvidence = mfaEnabled.evidence; riskLevel = mfaEnabled.compliant ? 'Low' : 'High'; break; case 'CIS-1.2': // Block legacy authentication const legacyBlocked = checkLegacyAuthentication(evidence); status = legacyBlocked.compliant ? 'Pass' : 'Fail'; testResult = legacyBlocked.message; cisEvidence = legacyBlocked.evidence; riskLevel = legacyBlocked.compliant ? 'Low' : 'High'; break; case 'CIS-2.1': // Security Defaults const securityDefaults = checkSecurityDefaults(evidence); status = securityDefaults.compliant ? 'Pass' : 'Fail'; testResult = securityDefaults.message; cisEvidence = securityDefaults.evidence; riskLevel = securityDefaults.compliant ? 'Low' : 'Medium'; break; default: status = 'Manual Review Required'; testResult = 'Control requires manual review'; } return { controlId: control.controlId, title: control.title, status, score: status === 'Pass' ? 100 : 0, implementationGroup: control.implementationGroup, automatable: control.automatable, testResult, evidence: cisEvidence, riskLevel, remediation: generateControlRemediation(control, status) }; } function checkMFAStatus(evidence: any): { compliant: boolean; message: string; evidence: any[] } { // Check if MFA is enforced through conditional access or security defaults const caPolicy = evidence.conditionalAccessPolicies?.value?.find((p: any) => p.displayName?.toLowerCase().includes('mfa') || p.grantControls?.builtInControls?.includes('mfa') ); const securityDefaultsEnabled = evidence.securityDefaults?.isEnabled; const compliant = !!(caPolicy || securityDefaultsEnabled); return { compliant, message: compliant ? 'MFA is enforced through conditional access policies or security defaults' : 'MFA is not properly enforced for all users', evidence: [ { type: 'Policy', source: 'Conditional Access', value: caPolicy ? 'MFA policy found' : 'No MFA policy found', expected: 'MFA enforcement policy required', collected: new Date().toISOString(), automated: true } ] }; } function checkLegacyAuthentication(evidence: any): { compliant: boolean; message: string; evidence: any[] } { // Check for conditional access policies that block legacy authentication const legacyBlockPolicy = evidence.conditionalAccessPolicies?.value?.find((p: any) => p.conditions?.clientAppTypes?.includes('exchangeActiveSync') && p.grantControls?.operator === 'OR' && p.grantControls?.builtInControls?.includes('block') ); const compliant = !!legacyBlockPolicy; return { compliant, message: compliant ? 'Legacy authentication is blocked by conditional access policy' : 'Legacy authentication is not blocked', evidence: [ { type: 'Policy', source: 'Conditional Access', value: legacyBlockPolicy ? 'Legacy auth block policy found' : 'No legacy auth block policy found', expected: 'Policy blocking legacy authentication required', collected: new Date().toISOString(), automated: true } ] }; } function checkSecurityDefaults(evidence: any): { compliant: boolean; message: string; evidence: any[] } { const isEnabled = evidence.securityDefaults?.isEnabled === true; return { compliant: isEnabled, message: isEnabled ? 'Security Defaults are enabled' : 'Security Defaults are not enabled', evidence: [ { type: 'Configuration', source: 'Azure AD', value: isEnabled.toString(), expected: 'true', collected: new Date().toISOString(), automated: true } ] }; } function generateControlRemediation(control: CISControl, status: string) { if (status === 'Pass') return undefined; const remediationMap: Record<string, any> = { 'CIS-1.1': { title: 'Enable Multi-Factor Authentication', description: 'Configure MFA enforcement for all users', steps: [ 'Go to Azure AD admin center', 'Navigate to Security > Conditional Access', 'Create new policy requiring MFA for all users', 'Test policy with pilot group before full deployment' ], automatable: true, estimatedTime: '30 minutes', difficulty: 'Low', impact: 'Medium', prerequisites: ['Azure AD Premium license', 'Conditional Access'] }, 'CIS-1.2': { title: 'Block Legacy Authentication', description: 'Create conditional access policy to block legacy authentication protocols', steps: [ 'Go to Azure AD admin center', 'Navigate to Security > Conditional Access', 'Create policy targeting legacy authentication clients', 'Set access control to Block', 'Enable policy after testing' ], automatable: true, estimatedTime: '20 minutes', difficulty: 'Medium', impact: 'Medium', prerequisites: ['Azure AD Premium license'] } }; return remediationMap[control.controlId]; } function generateCISRiskSummary(controlResults: CISControlResult[]) { const criticalFindings = controlResults.filter(c => c.riskLevel === 'Critical' && c.status === 'Fail').length; const highRiskFindings = controlResults.filter(c => c.riskLevel === 'High' && c.status === 'Fail').length; const mediumRiskFindings = controlResults.filter(c => c.riskLevel === 'Medium' && c.status === 'Fail').length; const lowRiskFindings = controlResults.filter(c => c.riskLevel === 'Low' && c.status === 'Fail').length; return { criticalFindings, highRiskFindings, mediumRiskFindings, lowRiskFindings, topRisks: controlResults .filter(c => c.status === 'Fail') .sort((a, b) => { const riskOrder = { 'Critical': 4, 'High': 3, 'Medium': 2, 'Low': 1 }; return riskOrder[b.riskLevel] - riskOrder[a.riskLevel]; }) .slice(0, 5) .map(c => ({ controlId: c.controlId, title: c.title, riskLevel: c.riskLevel, impact: 'Security vulnerability', likelihood: 'High', affectedAssets: 100, businessImpact: 'Potential security breach', technicalImpact: 'Unauthorized access' })), riskTrend: [ { date: new Date().toISOString(), overallScore: calculateOverallScore(controlResults), criticalCount: criticalFindings, highCount: highRiskFindings, mediumCount: mediumRiskFindings, lowCount: lowRiskFindings } ] }; } function generateCISRemediationPlan(controlResults: CISControlResult[]): CISRemediationPlan { const failedControls = controlResults.filter(c => c.status === 'Fail'); return { planId: `remediation-${Date.now()}`, generatedDate: new Date().toISOString(), totalTasks: failedControls.length, estimatedTime: `${failedControls.length * 30} minutes`, phases: [ { phase: 1, name: 'Critical and High Risk Items', description: 'Address critical and high-risk security findings first', tasks: failedControls .filter(c => c.riskLevel === 'Critical' || c.riskLevel === 'High') .map(c => ({ taskId: `task-${c.controlId}`, controlId: c.controlId, title: c.remediation?.title || `Remediate ${c.controlId}`, description: c.remediation?.description || c.title, automatable: c.remediation?.automatable || false, estimatedTime: c.remediation?.estimatedTime || '30 minutes', difficulty: c.remediation?.difficulty || 'Medium', impact: c.remediation?.impact || 'Medium', status: 'Pending', dueDate: new Date(Date.now() + 7 * 24 * 3600000).toISOString(), // 1 week prerequisites: c.remediation?.prerequisites || [], validationSteps: ['Verify control implementation', 'Test functionality', 'Document changes'] })), startDate: new Date().toISOString(), endDate: new Date(Date.now() + 7 * 24 * 3600000).toISOString(), priority: 'Critical' } ], dependencies: [] }; } function calculateOverallScore(controlResults: CISControlResult[]): number { if (controlResults.length === 0) return 0; const totalScore = controlResults.reduce((sum, c) => sum + c.score, 0); return Math.round(totalScore / controlResults.length); } function calculateCompliancePercentage(controlResults: CISControlResult[]): number { if (controlResults.length === 0) return 0; const passedControls = controlResults.filter(c => c.status === 'Pass').length; return Math.round((passedControls / controlResults.length) * 100); } async function generateCISReport(graphClient: Client, args: CISComplianceArgs) { // Generate comprehensive CIS compliance report const assessment = await performCISAssessment(graphClient, args); return { reportId: `cis-report-${Date.now()}`, benchmark: args.benchmark, generatedDate: new Date().toISOString(), assessment, summary: { overallCompliance: assessment.compliancePercentage, totalControls: assessment.totalControls, passedControls: assessment.passedControls, failedControls: assessment.failedControls, riskLevel: assessment.riskSummary.criticalFindings > 0 ? 'Critical' : assessment.riskSummary.highRiskFindings > 0 ? 'High' : 'Medium' }, downloadUrl: `/reports/cis-compliance-${Date.now()}.pdf` }; } async function configureCISMonitoring(args: CISComplianceArgs) { // Configure continuous CIS monitoring return { monitoringId: `cis-monitoring-${Date.now()}`, benchmark: args.benchmark, settings: args.settings, schedule: 'daily', alerting: true, status: 'configured', message: 'CIS monitoring configured successfully' }; } async function executeCISRemediation(graphClient: Client, args: CISComplianceArgs) { // Execute automated remediation for specific controls const results = []; if (args.controlIds) { for (const controlId of args.controlIds) { try { const result = await remediateCISControl(graphClient, controlId); results.push(result); } catch (error) { results.push({ controlId, status: 'failed', error: error instanceof Error ? error.message : 'Unknown error' }); } } } return { remediationId: `remediation-${Date.now()}`, results, summary: { attempted: results.length, successful: results.filter(r => r.status === 'success').length, failed: results.filter(r => r.status === 'failed').length } }; } async function remediateCISControl(graphClient: Client, controlId: string) { // Implement automated remediation for specific CIS controls switch (controlId) { case 'CIS-2.1': // Enable Security Defaults try { await graphClient .api('/policies/identitySecurityDefaultsEnforcementPolicy') .patch({ isEnabled: true }); return { controlId, status: 'success', message: 'Security Defaults enabled successfully' }; } catch (error) { throw new Error(`Failed to enable Security Defaults: ${error}`); } default: return { controlId, status: 'manual', message: 'Control requires manual remediation' }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DynamicEndpoints/m365-core-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server