MCP Security Best Practices: Production-Ready Security Implementation
Implementing robust security in Model Context Protocol (MCP) environments requires adherence to proven security principles and industry best practices. This guide provides actionable security practices, implementation checklists, and real-world patterns for production MCP deployments.
Table of Contents
- Security Implementation Checklist
- Authentication Best Practices
- Authorization Patterns
- Data Protection Strategies
- Network Security
- Monitoring and Incident Response
- Compliance and Governance
- Security Testing and Validation
Security Implementation Checklist
Pre-Production Security Checklist
Authentication & Authorization
- [ ] Multi-factor authentication implemented
- [ ] JWT tokens use strong signing algorithms (RS256/ES256)
- [ ] Token expiration and refresh mechanisms configured
- [ ] Role-based access control (RBAC) implemented
- [ ] API key rotation procedures established
- [ ] Service account security configured
- [ ] Password policies enforced (if applicable)
Data Protection
- [ ] Encryption at rest implemented (AES-256 minimum)
- [ ] Encryption in transit enforced (TLS 1.3)
- [ ] Sensitive data identification and classification completed
- [ ] Data masking for non-production environments
- [ ] Secure key management system in place
- [ ] Regular key rotation scheduled
- [ ] Data retention policies implemented
Network Security
- [ ] Firewall rules configured (default deny)
- [ ] IP allowlisting implemented
- [ ] Rate limiting and DDoS protection active
- [ ] Network segmentation in place
- [ ] VPN/private network access only
- [ ] Certificate management automated
- [ ] Security headers configured
Monitoring & Logging
- [ ] Comprehensive audit logging enabled
- [ ] Security event monitoring active
- [ ] Anomaly detection configured
- [ ] Log retention policies established
- [ ] SIEM integration completed
- [ ] Alerting rules configured
- [ ] Incident response procedures documented
Code Security
- [ ] Input validation and sanitization implemented
- [ ] SQL injection prevention measures
- [ ] Cross-site scripting (XSS) protection
- [ ] Dependency vulnerability scanning
- [ ] Static code analysis completed
- [ ] Security code review process established
- [ ] Secrets management implemented
Runtime Security Checklist
Daily Operations
- [ ] Monitor security alerts and logs
- [ ] Review failed authentication attempts
- [ ] Check for unusual access patterns
- [ ] Verify backup and recovery processes
- [ ] Update security dashboards
Weekly Reviews
- [ ] Analyze security metrics and trends
- [ ] Review access permissions and roles
- [ ] Check for expired certificates
- [ ] Validate security configurations
- [ ] Review incident response procedures
Monthly Activities
- [ ] Conduct security assessments
- [ ] Review and update access controls
- [ ] Perform vulnerability scans
- [ ] Update security documentation
- [ ] Test disaster recovery procedures
Authentication Best Practices
Multi-Layered Authentication
class MultiLayerAuth {
private primaryAuth: AuthenticationProvider;
private mfaProvider: MFAProvider;
private deviceTrust: DeviceTrustProvider;
async authenticate(credentials: AuthCredentials): Promise<AuthResult> {
// Step 1: Primary authentication
const primaryResult = await this.primaryAuth.authenticate(credentials);
if (!primaryResult.success) {
await this.auditLogger.logFailedAuth(credentials.identifier, 'PRIMARY_AUTH_FAILED');
throw new AuthenticationError('Primary authentication failed');
}
// Step 2: Multi-factor authentication
const mfaResult = await this.mfaProvider.verify(
primaryResult.userId,
credentials.mfaToken
);
if (!mfaResult.success) {
await this.auditLogger.logFailedAuth(credentials.identifier, 'MFA_FAILED');
throw new AuthenticationError('Multi-factor authentication required');
}
// Step 3: Device trust verification
const deviceResult = await this.deviceTrust.verifyDevice(
credentials.deviceFingerprint,
primaryResult.userId
);
if (!deviceResult.trusted) {
await this.auditLogger.logSuspiciousActivity(
primaryResult.userId,
'UNTRUSTED_DEVICE',
{ device: credentials.deviceFingerprint }
);
// Require additional verification for untrusted devices
await this.requireAdditionalVerification(primaryResult.userId);
}
return {
success: true,
userId: primaryResult.userId,
sessionId: generateSecureId(),
trustLevel: this.calculateTrustLevel(primaryResult, mfaResult, deviceResult)
};
}
private calculateTrustLevel(
primary: AuthResult,
mfa: MFAResult,
device: DeviceResult
): TrustLevel {
let score = 0;
if (primary.strongPassword) score += 20;
if (mfa.success && mfa.method === 'hardware') score += 30;
if (mfa.success && mfa.method === 'app') score += 20;
if (device.trusted) score += 25;
if (device.registered) score += 15;
if (score >= 80) return TrustLevel.HIGH;
if (score >= 60) return TrustLevel.MEDIUM;
if (score >= 40) return TrustLevel.LOW;
return TrustLevel.MINIMAL;
}
}
Secure Token Management
class SecureTokenManager {
private readonly ALGORITHM = 'RS256';
private readonly ACCESS_TOKEN_EXPIRY = '15m';
private readonly REFRESH_TOKEN_EXPIRY = '7d';
async generateTokenPair(userId: string, context: AuthContext): Promise<TokenPair> {
const accessPayload = {
sub: userId,
aud: 'mcp-api',
iss: 'mcp-auth-service',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (15 * 60), // 15 minutes
scope: context.permissions.join(' '),
trust_level: context.trustLevel,
session_id: context.sessionId
};
const refreshPayload = {
sub: userId,
aud: 'mcp-refresh',
iss: 'mcp-auth-service',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (7 * 24 * 60 * 60), // 7 days
session_id: context.sessionId,
token_family: generateTokenFamily()
};
const accessToken = await this.signToken(accessPayload);
const refreshToken = await this.signToken(refreshPayload);
// Store refresh token with revocation capability
await this.storeRefreshToken(refreshToken, userId, context.sessionId);
return { accessToken, refreshToken };
}
async rotateRefreshToken(refreshToken: string): Promise<TokenPair> {
const payload = await this.verifyToken(refreshToken);
// Check if token family is still valid (prevents replay attacks)
const isValidFamily = await this.validateTokenFamily(
payload.token_family,
payload.sub
);
if (!isValidFamily) {
// Potential token theft - revoke all tokens for user
await this.revokeAllUserTokens(payload.sub);
throw new SecurityError('Token family compromised');
}
// Revoke old refresh token
await this.revokeRefreshToken(refreshToken);
// Generate new token pair
const context = await this.getAuthContext(payload.sub, payload.session_id);
return await this.generateTokenPair(payload.sub, context);
}
private async storeRefreshToken(
token: string,
userId: string,
sessionId: string
): Promise<void> {
const tokenHash = crypto.createHash('sha256').update(token).digest('hex');
await this.tokenStore.store({
tokenHash,
userId,
sessionId,
createdAt: new Date(),
lastUsed: new Date(),
isActive: true
});
}
}
Authorization Patterns
Hierarchical Permission Model
interface Permission {
resource: string;
action: string;
conditions?: PermissionCondition[];
effect: 'ALLOW' | 'DENY';
priority: number;
}
class HierarchicalAuthorizor {
private permissionHierarchy: Map<string, string[]> = new Map();
constructor() {
this.setupPermissionHierarchy();
}
private setupPermissionHierarchy() {
// Define permission inheritance
this.permissionHierarchy.set('admin', ['manager', 'user', 'guest']);
this.permissionHierarchy.set('manager', ['user', 'guest']);
this.permissionHierarchy.set('user', ['guest']);
this.permissionHierarchy.set('guest', []);
}
async authorize(
identity: UserIdentity,
resource: string,
action: string,
context?: any
): Promise<AuthorizationResult> {
// Get all applicable permissions including inherited ones
const permissions = await this.getAllPermissions(identity);
// Sort by priority (DENY permissions typically have higher priority)
permissions.sort((a, b) => b.priority - a.priority);
for (const permission of permissions) {
if (this.matchesPermission(permission, resource, action)) {
const conditionResult = await this.evaluateConditions(
permission.conditions || [],
{ identity, resource, action, context }
);
if (conditionResult) {
return {
allowed: permission.effect === 'ALLOW',
reason: `${permission.effect} by permission: ${permission.resource}:${permission.action}`,
appliedPermission: permission
};
}
}
}
return {
allowed: false,
reason: 'No matching permission found'
};
}
private async getAllPermissions(identity: UserIdentity): Promise<Permission[]> {
const allPermissions: Permission[] = [];
// Get direct role permissions
for (const role of identity.roles) {
const rolePermissions = await this.getRolePermissions(role);
allPermissions.push(...rolePermissions);
// Get inherited permissions
const inheritedRoles = this.permissionHierarchy.get(role) || [];
for (const inheritedRole of inheritedRoles) {
const inheritedPermissions = await this.getRolePermissions(inheritedRole);
allPermissions.push(...inheritedPermissions);
}
}
// Get user-specific permissions
const userPermissions = await this.getUserPermissions(identity.userId);
allPermissions.push(...userPermissions);
return this.deduplicatePermissions(allPermissions);
}
private async evaluateConditions(
conditions: PermissionCondition[],
context: any
): Promise<boolean> {
for (const condition of conditions) {
switch (condition.type) {
case 'TIME_RANGE':
if (!this.isWithinTimeRange(condition.value)) return false;
break;
case 'IP_RANGE':
if (!this.isWithinIPRange(context.clientIP, condition.value)) return false;
break;
case 'RESOURCE_OWNER':
if (!await this.isResourceOwner(context.identity.userId, context.resource)) return false;
break;
case 'TRUST_LEVEL':
if (context.identity.trustLevel < condition.value) return false;
break;
default:
return false;
}
}
return true;
}
}
Dynamic Permission Assignment
class DynamicPermissionManager {
async assignTemporaryPermission(
userId: string,
permission: Permission,
duration: number,
justification: string
): Promise<void> {
const temporaryPermission = {
...permission,
userId,
grantedAt: new Date(),
expiresAt: new Date(Date.now() + duration),
justification,
isTemporary: true
};
await this.permissionStore.storeTemporary(temporaryPermission);
// Schedule automatic revocation
setTimeout(async () => {
await this.revokeTemporaryPermission(userId, permission);
}, duration);
// Audit the permission grant
await this.auditLogger.log({
action: 'TEMPORARY_PERMISSION_GRANTED',
userId: userId,
details: {
permission: permission,
duration: duration,
justification: justification
}
});
}
async requestPermissionEscalation(
userId: string,
requestedPermission: Permission,
justification: string
): Promise<EscalationRequest> {
const request = {
id: generateId(),
userId,
requestedPermission,
justification,
requestedAt: new Date(),
status: 'PENDING',
approvers: await this.getRequiredApprovers(requestedPermission)
};
await this.escalationStore.store(request);
// Notify approvers
for (const approver of request.approvers) {
await this.notificationService.notifyApprover(approver, request);
}
return request;
}
async approveEscalation(
requestId: string,
approverId: string,
decision: 'APPROVE' | 'DENY',
comments?: string
): Promise<void> {
const request = await this.escalationStore.get(requestId);
if (!request.approvers.includes(approverId)) {
throw new AuthorizationError('Not authorized to approve this request');
}
request.approvals = request.approvals || [];
request.approvals.push({
approverId,
decision,
timestamp: new Date(),
comments
});
const approvalCount = request.approvals.filter(a => a.decision === 'APPROVE').length;
const requiredApprovals = Math.ceil(request.approvers.length / 2); // Majority
if (decision === 'DENY' || approvalCount >= requiredApprovals) {
request.status = decision === 'DENY' ? 'DENIED' : 'APPROVED';
if (request.status === 'APPROVED') {
await this.assignTemporaryPermission(
request.userId,
request.requestedPermission,
24 * 60 * 60 * 1000, // 24 hours
`Escalation approved: ${requestId}`
);
}
}
await this.escalationStore.update(request);
}
}
Data Protection Strategies
Data Classification and Handling
enum DataClassification {
PUBLIC = 0,
INTERNAL = 1,
CONFIDENTIAL = 2,
RESTRICTED = 3
}
class DataProtectionManager {
private classificationRules: Map<string, DataClassificationRule> = new Map();
async classifyData(data: any, context: DataContext): Promise<DataClassification> {
let maxClassification = DataClassification.PUBLIC;
for (const [pattern, rule] of this.classificationRules) {
if (this.matchesPattern(data, pattern)) {
const classification = await rule.classify(data, context);
if (classification > maxClassification) {
maxClassification = classification;
}
}
}
return maxClassification;
}
async applyDataHandlingPolicies(
data: any,
classification: DataClassification,
operation: string
): Promise<any> {
switch (classification) {
case DataClassification.RESTRICTED:
return await this.handleRestrictedData(data, operation);
case DataClassification.CONFIDENTIAL:
return await this.handleConfidentialData(data, operation);
case DataClassification.INTERNAL:
return await this.handleInternalData(data, operation);
default:
return data;
}
}
private async handleRestrictedData(data: any, operation: string): Promise<any> {
// Encrypt all restricted data
const encrypted = await this.encryptionService.encrypt(data, 'AES-256-GCM');
// Log all access to restricted data
await this.auditLogger.logDataAccess('RESTRICTED', operation, {
dataHash: this.hashData(data),
timestamp: new Date()
});
// Apply additional protection measures
if (operation === 'EXPORT') {
throw new SecurityError('Export of restricted data not permitted');
}
return encrypted;
}
private async handleConfidentialData(data: any, operation: string): Promise<any> {
// Mask sensitive fields for non-authorized operations
if (operation === 'DISPLAY' || operation === 'LOG') {
return this.maskSensitiveFields(data);
}
// Encrypt for storage and transmission
if (operation === 'STORE' || operation === 'TRANSMIT') {
return await this.encryptionService.encrypt(data, 'AES-256-CBC');
}
return data;
}
private maskSensitiveFields(data: any): any {
const sensitivePatterns = [
/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/, // Credit card
/\b\d{3}-\d{2}-\d{4}\b/, // SSN
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/, // Email
];
let maskedData = JSON.stringify(data);
for (const pattern of sensitivePatterns) {
maskedData = maskedData.replace(pattern, '***MASKED***');
}
return JSON.parse(maskedData);
}
}
Secure Data Storage
class SecureDataStore {
private encryptionKeys: Map<string, CryptoKey> = new Map();
async storeSecurely(
data: any,
classification: DataClassification,
metadata: StorageMetadata
): Promise<string> {
// Encrypt data based on classification
const encryptedData = await this.encryptByClassification(data, classification);
// Generate secure storage key
const storageKey = await this.generateStorageKey(metadata);
// Store with integrity protection
const storageRecord = {
data: encryptedData,
metadata: {
...metadata,
classification,
createdAt: new Date(),
integrity: await this.calculateIntegrity(encryptedData)
}
};
await this.storageBackend.store(storageKey, storageRecord);
// Log storage operation
await this.auditLogger.logDataStorage(storageKey, classification, metadata);
return storageKey;
}
async retrieveSecurely(
storageKey: string,
accessContext: AccessContext
): Promise<any> {
const storageRecord = await this.storageBackend.retrieve(storageKey);
if (!storageRecord) {
throw new Error('Data not found');
}
// Verify integrity
const currentIntegrity = await this.calculateIntegrity(storageRecord.data);
if (currentIntegrity !== storageRecord.metadata.integrity) {
throw new SecurityError('Data integrity violation detected');
}
// Check access permissions
const authResult = await this.authorizeDataAccess(
storageRecord.metadata.classification,
accessContext
);
if (!authResult.allowed) {
throw new AuthorizationError(`Access denied: ${authResult.reason}`);
}
// Decrypt data
const decryptedData = await this.decryptByClassification(
storageRecord.data,
storageRecord.metadata.classification
);
// Log access
await this.auditLogger.logDataAccess(storageKey, 'RETRIEVE', accessContext);
return decryptedData;
}
private async encryptByClassification(
data: any,
classification: DataClassification
): Promise<EncryptedData> {
const algorithm = this.getEncryptionAlgorithm(classification);
const key = await this.getEncryptionKey(classification);
return await this.encryptionService.encrypt(data, algorithm, key);
}
private getEncryptionAlgorithm(classification: DataClassification): string {
switch (classification) {
case DataClassification.RESTRICTED:
return 'AES-256-GCM';
case DataClassification.CONFIDENTIAL:
return 'AES-256-CBC';
default:
return 'AES-128-CBC';
}
}
}
Network Security
Secure Communication Patterns
class SecureCommunicationManager {
private tlsConfig: TLSConfig;
private certificateManager: CertificateManager;
async establishSecureConnection(
clientInfo: ClientInfo
): Promise<SecureConnection> {
// Validate client certificate
const certValidation = await this.certificateManager.validateClientCertificate(
clientInfo.certificate
);
if (!certValidation.valid) {
throw new SecurityError(`Invalid client certificate: ${certValidation.reason}`);
}
// Create TLS context with strict security settings
const tlsContext = {
secureProtocol: 'TLSv1_3_method',
ciphers: [
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256',
'TLS_AES_128_GCM_SHA256'
].join(':'),
honorCipherOrder: true,
requestCert: true,
rejectUnauthorized: true,
checkServerIdentity: this.customServerIdentityCheck.bind(this)
};
// Establish connection with mutual TLS
const connection = await this.createMTLSConnection(clientInfo, tlsContext);
// Verify connection security
await this.verifyConnectionSecurity(connection);
return connection;
}
private async verifyConnectionSecurity(connection: SecureConnection): Promise<void> {
const securityInfo = connection.getSecurityInfo();
// Verify TLS version
if (securityInfo.tlsVersion < 'TLSv1.3') {
throw new SecurityError('TLS version must be 1.3 or higher');
}
// Verify cipher strength
if (securityInfo.cipherStrength < 256) {
throw new SecurityError('Cipher strength must be 256 bits or higher');
}
// Verify perfect forward secrecy
if (!securityInfo.perfectForwardSecrecy) {
throw new SecurityError('Perfect forward secrecy required');
}
// Log successful secure connection
await this.auditLogger.logSecureConnection(securityInfo);
}
async implementNetworkSegmentation(): Promise<void> {
const securityZones = [
{
name: 'DMZ',
allowedPorts: [80, 443],
restrictions: ['no_outbound_connections']
},
{
name: 'APPLICATION',
allowedPorts: [8080, 8443],
restrictions: ['database_only']
},
{
name: 'DATABASE',
allowedPorts: [5432, 3306],
restrictions: ['no_internet_access']
}
];
for (const zone of securityZones) {
await this.configureSecurityZone(zone);
}
}
}
API Gateway Security
class SecureAPIGateway {
private rateLimiter: RateLimiter;
private threatDetector: ThreatDetector;
private requestValidator: RequestValidator;
async processRequest(request: APIRequest): Promise<APIResponse> {
// Step 1: Validate request format and headers
await this.requestValidator.validate(request);
// Step 2: Check rate limits
const rateLimitResult = await this.rateLimiter.checkLimit(
request.clientId,
request.endpoint
);
if (!rateLimitResult.allowed) {
throw new RateLimitError('Rate limit exceeded', rateLimitResult.retryAfter);
}
// Step 3: Threat detection
const threatAnalysis = await this.threatDetector.analyzeRequest(request);
if (threatAnalysis.riskLevel > 0.8) {
await this.handleHighRiskRequest(request, threatAnalysis);
throw new SecurityError('Request blocked due to security concerns');
}
// Step 4: Authentication and authorization
const authResult = await this.authenticateAndAuthorize(request);
if (!authResult.authorized) {
throw new AuthorizationError('Access denied');
}
// Step 5: Process request with security context
try {
const response = await this.processSecureRequest(request, authResult.context);
// Step 6: Apply security headers to response
return this.addSecurityHeaders(response);
} catch (error) {
await this.auditLogger.logRequestError(request, error);
throw error;
}
}
private addSecurityHeaders(response: APIResponse): APIResponse {
const securityHeaders = {
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block',
'Content-Security-Policy': "default-src 'self'; script-src 'self'",
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Permissions-Policy': 'geolocation=(), microphone=(), camera=()'
};
response.headers = { ...response.headers, ...securityHeaders };
return response;
}
private async handleHighRiskRequest(
request: APIRequest,
threatAnalysis: ThreatAnalysis
): Promise<void> {
// Log security incident
await this.auditLogger.logSecurityIncident({
type: 'HIGH_RISK_REQUEST',
clientId: request.clientId,
clientIP: request.clientIP,
threat: threatAnalysis,
request: this.sanitizeRequestForLogging(request)
});
// Temporary IP blocking for severe threats
if (threatAnalysis.riskLevel > 0.95) {
await this.ipBlocker.temporaryBlock(request.clientIP, 3600000); // 1 hour
}
// Notify security team
await this.alertManager.sendSecurityAlert({
severity: 'HIGH',
message: 'High-risk request detected',
details: threatAnalysis
});
}
}
Monitoring and Incident Response
Security Event Correlation
class SecurityEventCorrelator {
private eventBuffer: SecurityEvent[] = [];
private correlationRules: CorrelationRule[] = [];
async processSecurityEvent(event: SecurityEvent): Promise<void> {
// Add to event buffer
this.eventBuffer.push(event);
// Keep buffer size manageable
if (this.eventBuffer.length > 10000) {
this.eventBuffer = this.eventBuffer.slice(-5000);
}
// Check correlation rules
await this.checkCorrelationRules(event);
// Store event for long-term analysis
await this.eventStore.store(event);
}
private async checkCorrelationRules(event: SecurityEvent): Promise<void> {
for (const rule of this.correlationRules) {
const correlatedEvents = await this.findCorrelatedEvents(event, rule);
if (correlatedEvents.length >= rule.threshold) {
await this.triggerCorrelationAlert(rule, correlatedEvents);
}
}
}
private async findCorrelatedEvents(
event: SecurityEvent,
rule: CorrelationRule
): Promise<SecurityEvent[]> {
const timeWindow = Date.now() - rule.timeWindowMs;
return this.eventBuffer.filter(e => {
if (e.timestamp.getTime() < timeWindow) return false;
return rule.conditions.every(condition => {
switch (condition.type) {
case 'SAME_SOURCE_IP':
return e.sourceIP === event.sourceIP;
case 'SAME_USER':
return e.userId === event.userId;
case 'EVENT_TYPE':
return condition.values.includes(e.type);
case 'FAILED_ATTEMPTS':
return e.success === false;
default:
return false;
}
});
});
}
private async triggerCorrelationAlert(
rule: CorrelationRule,
events: SecurityEvent[]
): Promise<void> {
const alert: SecurityAlert = {
id: generateId(),
type: 'CORRELATION_ALERT',
rule: rule.name,
severity: rule.severity,
timestamp: new Date(),
correlatedEvents: events,
description: `${rule.description} - ${events.length} events detected`
};
await this.alertManager.sendAlert(alert);
// Auto-response actions
if (rule.autoResponse) {
await this.executeAutoResponse(rule.autoResponse, events);
}
}
private async executeAutoResponse(
response: AutoResponse,
events: SecurityEvent[]
): Promise<void> {
switch (response.action) {
case 'BLOCK_IP':
const sourceIPs = [...new Set(events.map(e => e.sourceIP))];
for (const ip of sourceIPs) {
await this.ipBlocker.temporaryBlock(ip, response.duration || 3600000);
}
break;
case 'DISABLE_USER':
const userIds = [...new Set(events.map(e => e.userId).filter(Boolean))];
for (const userId of userIds) {
await this.userManager.temporarilyDisable(userId, response.duration || 3600000);
}
break;
case 'REQUIRE_MFA':
const mfaUserIds = [...new Set(events.map(e => e.userId).filter(Boolean))];
for (const userId of mfaUserIds) {
await this.authService.requireMFA(userId);
}
break;
}
}
}
Automated Incident Response
class IncidentResponseSystem {
private playbooks: Map<string, ResponsePlaybook> = new Map();
private responseTeam: ResponseTeam;
async handleSecurityIncident(incident: SecurityIncident): Promise<void> {
// Step 1: Classify incident
const classification = await this.classifyIncident(incident);
// Step 2: Execute immediate containment
await this.executeContainment(incident, classification);
// Step 3: Gather evidence
const evidence = await this.gatherEvidence(incident);
// Step 4: Execute response playbook
const playbook = this.playbooks.get(classification.type);
if (playbook) {
await this.executePlaybook(playbook, incident, evidence);
}
// Step 5: Notify stakeholders
await this.notifyStakeholders(incident, classification);
// Step 6: Track response progress
await this.trackIncidentResponse(incident);
}
private async executeContainment(
incident: SecurityIncident,
classification: IncidentClassification
): Promise<void> {
const containmentActions = [];
switch (classification.severity) {
case 'CRITICAL':
// Immediate full isolation
if (incident.affectedSystems) {
for (const system of incident.affectedSystems) {
containmentActions.push(this.isolateSystem(system));
}
}
break;
case 'HIGH':
// Partial isolation and enhanced monitoring
containmentActions.push(this.enhanceMonitoring(incident.affectedSystems));
if (incident.sourceIP) {
containmentActions.push(this.blockIP(incident.sourceIP));
}
break;
case 'MEDIUM':
// Enhanced logging and monitoring
containmentActions.push(this.enhanceLogging(incident.affectedSystems));
break;
}
await Promise.all(containmentActions);
// Log containment actions
await this.auditLogger.logIncidentContainment(incident.id, containmentActions);
}
private async gatherEvidence(incident: SecurityIncident): Promise<Evidence[]> {
const evidence: Evidence[] = [];
// Collect system logs
if (incident.affectedSystems) {
for (const system of incident.affectedSystems) {
const logs = await this.logCollector.collectLogs(
system,
incident.startTime,
incident.endTime || new Date()
);
evidence.push({
type: 'SYSTEM_LOGS',
source: system,
data: logs,
collectedAt: new Date()
});
}
}
// Collect network traffic
if (incident.sourceIP) {
const networkData = await this.networkMonitor.getTrafficData(
incident.sourceIP,
incident.startTime,
incident.endTime || new Date()
);
evidence.push({
type: 'NETWORK_TRAFFIC',
source: incident.sourceIP,
data: networkData,
collectedAt: new Date()
});
}
// Collect authentication logs
const authLogs = await this.authLogger.getAuthenticationEvents(
incident.startTime,
incident.endTime || new Date(),
{ userId: incident.userId, sourceIP: incident.sourceIP }
);
evidence.push({
type: 'AUTHENTICATION_LOGS',
source: 'auth_service',
data: authLogs,
collectedAt: new Date()
});
return evidence;
}
private async executePlaybook(
playbook: ResponsePlaybook,
incident: SecurityIncident,
evidence: Evidence[]
): Promise<void> {
for (const step of playbook.steps) {
try {
await this.executePlaybookStep(step, incident, evidence);
await this.updateIncidentStatus(incident.id, {
status: 'IN_PROGRESS',
lastStep: step.name,
updatedAt: new Date()
});
} catch (error) {
await this.auditLogger.logPlaybookStepFailure(
incident.id,
step.name,
error.message
);
if (step.critical) {
throw new Error(`Critical playbook step failed: ${step.name}`);
}
}
}
}
}
Compliance and Governance
Compliance Framework Implementation
class ComplianceManager {
private complianceFrameworks: Map<string, ComplianceFramework> = new Map();
private controlsRegistry: Map<string, SecurityControl> = new Map();
async validateCompliance(framework: string): Promise<ComplianceReport> {
const complianceFramework = this.complianceFrameworks.get(framework);
if (!complianceFramework) {
throw new Error(`Unknown compliance framework: ${framework}`);
}
const results: ControlResult[] = [];
for (const requirement of complianceFramework.requirements) {
const control = this.controlsRegistry.get(requirement.controlId);
if (!control) {
results.push({
controlId: requirement.controlId,
status: 'NOT_IMPLEMENTED',
evidence: [],
gaps: ['Control not found in registry']
});
continue;
}
const controlResult = await this.validateControl(control, requirement);
results.push(controlResult);
}
return {
framework,
assessmentDate: new Date(),
overallStatus: this.calculateOverallStatus(results),
results,
recommendations: await this.generateRecommendations(results)
};
}
private async validateControl(
control: SecurityControl,
requirement: ComplianceRequirement
): Promise<ControlResult> {
const evidence: Evidence[] = [];
const gaps: string[] = [];
// Check implementation status
const isImplemented = await control.validator();
if (!isImplemented) {
gaps.push('Control not properly implemented');
return {
controlId: control.id,
status: 'NON_COMPLIANT',
evidence,
gaps
};
}
// Collect evidence
if (control.evidenceCollector) {
try {
const controlEvidence = await control.evidenceCollector();
evidence.push(...controlEvidence);
} catch (error) {
gaps.push(`Failed to collect evidence: ${error.message}`);
}
}
// Validate against specific requirements
for (const criterion of requirement.criteria) {
const criterionResult = await this.validateCriterion(criterion, evidence);
if (!criterionResult.passed) {
gaps.push(`Criterion not met: ${criterion.description}`);
}
}
return {
controlId: control.id,
status: gaps.length === 0 ? 'COMPLIANT' : 'NON_COMPLIANT',
evidence,
gaps
};
}
async generateComplianceReport(framework: string): Promise<ComplianceReport> {
const report = await this.validateCompliance(framework);
// Add additional sections
report.executiveSummary = this.generateExecutiveSummary(report);
report.riskAssessment = await this.performRiskAssessment(report);
report.remediationPlan = await this.createRemediationPlan(report);
// Store report for audit trail
await this.reportStore.store(report);
return report;
}
private generateExecutiveSummary(report: ComplianceReport): ExecutiveSummary {
const total = report.results.length;
const compliant = report.results.filter(r => r.status === 'COMPLIANT').length;
const nonCompliant = report.results.filter(r => r.status === 'NON_COMPLIANT').length;
const notImplemented = report.results.filter(r => r.status === 'NOT_IMPLEMENTED').length;
return {
overallComplianceScore: (compliant / total) * 100,
totalControls: total,
compliantControls: compliant,
nonCompliantControls: nonCompliant,
notImplementedControls: notImplemented,
keyFindings: this.extractKeyFindings(report.results),
immediateActions: this.identifyImmediateActions(report.results)
};
}
}
Security Testing and Validation
Automated Security Testing
class SecurityTestSuite {
private testCategories: Map<string, SecurityTest[]> = new Map();
async runSecurityTests(): Promise<SecurityTestReport> {
const results: TestResult[] = [];
for (const [category, tests] of this.testCategories) {
console.log(`Running ${category} tests...`);
for (const test of tests) {
try {
const result = await this.executeTest(test);
results.push(result);
} catch (error) {
results.push({
testId: test.id,
category,
status: 'ERROR',
error: error.message,
timestamp: new Date()
});
}
}
}
return {
timestamp: new Date(),
totalTests: results.length,
passed: results.filter(r => r.status === 'PASS').length,
failed: results.filter(r => r.status === 'FAIL').length,
errors: results.filter(r => r.status === 'ERROR').length,
results
};
}
private setupAuthenticationTests() {
this.testCategories.set('authentication', [
{
id: 'auth_001',
name: 'Test JWT Token Validation',
description: 'Verify JWT tokens are properly validated',
execute: async () => {
// Test invalid signature
const invalidToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.invalid.signature';
try {
await this.authService.validateToken(invalidToken);
return { status: 'FAIL', message: 'Invalid token was accepted' };
} catch {
return { status: 'PASS', message: 'Invalid token correctly rejected' };
}
}
},
{
id: 'auth_002',
name: 'Test Expired Token Rejection',
description: 'Verify expired tokens are rejected',
execute: async () => {
const expiredToken = await this.generateExpiredToken();
try {
await this.authService.validateToken(expiredToken);
return { status: 'FAIL', message: 'Expired token was accepted' };
} catch {
return { status: 'PASS', message: 'Expired token correctly rejected' };
}
}
}
]);
}
private setupAuthorizationTests() {
this.testCategories.set('authorization', [
{
id: 'authz_001',
name: 'Test Permission Escalation Prevention',
description: 'Verify users cannot escalate privileges',
execute: async () => {
const lowPrivUser = await this.createTestUser(['read']);
try {
await this.authorizationService.authorize(
lowPrivUser,
'admin_resource',
'write'
);
return { status: 'FAIL', message: 'Privilege escalation allowed' };
} catch {
return { status: 'PASS', message: 'Privilege escalation prevented' };
}
}
}
]);
}
private setupInputValidationTests() {
this.testCategories.set('input_validation', [
{
id: 'input_001',
name: 'Test SQL Injection Prevention',
description: 'Verify SQL injection attacks are blocked',
execute: async () => {
const maliciousInput = "'; DROP TABLE users; --";
try {
await this.mcpServer.callTool('database_query', {
query: maliciousInput
});
return { status: 'FAIL', message: 'SQL injection not prevented' };
} catch (error) {
if (error.message.includes('Invalid query')) {
return { status: 'PASS', message: 'SQL injection prevented' };
}
return { status: 'ERROR', message: error.message };
}
}
},
{
id: 'input_002',
name: 'Test XSS Prevention',
description: 'Verify XSS attacks are blocked',
execute: async () => {
const xssPayload = '<script>alert("xss")</script>';
const result = await this.inputValidator.sanitize(xssPayload);
if (result.includes('<script>')) {
return { status: 'FAIL', message: 'XSS payload not sanitized' };
}
return { status: 'PASS', message: 'XSS payload correctly sanitized' };
}
}
]);
}
}
Penetration Testing Framework
class PenetrationTestFramework {
private testScenarios: PenTestScenario[] = [];
async runPenetrationTests(): Promise<PenTestReport> {
const results: PenTestResult[] = [];
for (const scenario of this.testScenarios) {
console.log(`Running penetration test: ${scenario.name}`);
const result = await this.executeScenario(scenario);
results.push(result);
// Wait between tests to avoid overwhelming the system
await this.delay(scenario.cooldownMs || 1000);
}
return {
timestamp: new Date(),
scenarios: results,
vulnerabilities: results.filter(r => r.vulnerabilityFound),
riskScore: this.calculateRiskScore(results)
};
}
private setupAttackScenarios() {
this.testScenarios = [
{
name: 'Brute Force Authentication',
description: 'Attempt to brute force user credentials',
category: 'Authentication',
execute: async () => {
const attempts = [];
const username = 'testuser';
const passwords = ['password', '123456', 'admin', 'test'];
for (const password of passwords) {
try {
await this.authService.authenticate({ username, password });
return {
vulnerabilityFound: true,
severity: 'HIGH',
description: 'Weak password allowed successful authentication'
};
} catch (error) {
attempts.push({ password, blocked: true });
}
}
// Check if rate limiting is working
if (attempts.length > 3) {
return {
vulnerabilityFound: false,
description: 'Brute force attempts properly blocked'
};
}
return {
vulnerabilityFound: true,
severity: 'MEDIUM',
description: 'Rate limiting may not be sufficient'
};
}
},
{
name: 'API Endpoint Enumeration',
description: 'Attempt to discover hidden API endpoints',
category: 'Information Disclosure',
execute: async () => {
const commonEndpoints = [
'/admin', '/api/admin', '/debug', '/test',
'/api/v1/users', '/api/internal', '/.env'
];
const discoveries = [];
for (const endpoint of commonEndpoints) {
try {
const response = await this.httpClient.get(endpoint);
if (response.status !== 404) {
discoveries.push({
endpoint,
status: response.status,
exposed: true
});
}
} catch (error) {
// Expected for non-existent endpoints
}
}
return {
vulnerabilityFound: discoveries.length > 0,
severity: discoveries.length > 2 ? 'HIGH' : 'MEDIUM',
description: `${discoveries.length} potentially sensitive endpoints discovered`,
details: discoveries
};
}
}
];
}
}
Security Best Practices Summary
Implementation Priorities
-
Authentication & Authorization (Critical)
- Implement multi-factor authentication
- Use strong token management
- Apply principle of least privilege
- Regular access reviews
-
Data Protection (Critical)
- Encrypt data at rest and in transit
- Implement data classification
- Use secure key management
- Regular key rotation
-
Network Security (High)
- Use TLS 1.3 for all communications
- Implement rate limiting
- Network segmentation
- IP allowlisting
-
Monitoring & Logging (High)
- Comprehensive audit logging
- Real-time threat detection
- Security event correlation
- Incident response procedures
-
Testing & Validation (Medium)
- Regular security testing
- Penetration testing
- Vulnerability scanning
- Code security reviews
Continuous Improvement
- Regular security assessments and updates
- Stay informed about new threats and vulnerabilities
- Participate in security communities and forums
- Maintain incident response procedures
- Regular training for development teams
Next Steps
- Review MCP security guide for detailed implementation
- Implement performance optimization with security in mind
- Explore advanced MCP patterns for enterprise security
- Join the MCP community for security discussions
This comprehensive security best practices guide provides the foundation for building and maintaining secure MCP implementations that protect against modern threats while enabling powerful AI integrations.