Exemples d'Architecture Zero Trust
Exemples complets d'architecture Zero Trust avec authentification, segmentation de réseau et contrôle d'accès
Key Facts
- Category
- Security
- Items
- 3
- Format Families
- sample
Sample Overview
Exemples complets d'architecture Zero Trust avec authentification, segmentation de réseau et contrôle d'accès This sample set belongs to Security and can be used to test related workflows inside Elysia Tools.
💻 Authentification Identité Zero Trust
🔴 complex
⭐⭐⭐⭐⭐
Système multifactor d'authentification avec évaluation adaptative de risque
⏱️ 40 min
🏷️ authentication, mfa, risk-assessment, jwt, session-management
// Zero Trust Identity Authentication System
// Multi-factor authentication with adaptive risk assessment
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const speakeasy = require('speakeasy');
const argon2 = require('argon2');
class ZeroTrustAuthSystem {
constructor(options = {}) {
this.jwtSecret = options.jwtSecret || process.env.JWT_SECRET;
this.tokenBlacklist = new Set();
this.sessionStore = new Map(); // sessionId -> session data
this.riskEngine = new RiskAssessmentEngine(options.risk);
this.mfaProvider = new MFAProvider(options.mfa);
this.config = {
passwordPolicy: {
minLength: 12,
requireUppercase: true,
requireLowercase: true,
requireNumbers: true,
requireSymbols: true,
preventReused: true
},
sessionTimeout: options.sessionTimeout || 15 * 60 * 1000, // 15 minutes
maxFailedAttempts: options.maxFailedAttempts || 5,
lockoutDuration: options.lockoutDuration || 30 * 60 * 1000, // 30 minutes
...options
};
}
async authenticate(credentials, context) {
try {
// Step 1: Validate credentials
const user = await this.validateCredentials(credentials.username, credentials.password);
if (!user) {
throw new Error('Invalid credentials');
}
// Step 2: Risk assessment
const riskScore = await this.riskEngine.assess({
userId: user.id,
credentials,
context,
timestamp: Date.now()
});
console.log(`Risk assessment score: ${riskScore} for user ${user.id}`);
// Step 3: Adaptive authentication based on risk
const authResult = await this.performAdaptiveAuthentication(user, riskScore, context);
if (!authResult.success) {
throw new Error('Authentication failed');
}
// Step 4: Create session with enhanced security
const session = await this.createSecureSession(user, authResult, riskScore, context);
// Step 5: Issue tokens
const tokens = await this.issueTokens(user, session, riskScore);
return {
user: this.sanitizeUser(user),
session: session,
tokens,
riskScore,
mfaRequired: authResult.mfaRequired,
passwordChangeRequired: authResult.passwordChangeRequired
};
} catch (error) {
console.error('Authentication error:', error);
throw error;
}
}
async validateCredentials(username, password) {
// Retrieve user from database (simplified)
const user = await this.getUserByUsername(username);
if (!user) {
return null;
}
// Check if account is locked
if (user.lockUntil && user.lockUntil > Date.now()) {
throw new Error(`Account locked until ${new Date(user.lockUntil).toISOString()}`);
}
// Verify password with secure comparison
const isValid = await argon2.verify(user.passwordHash, password);
if (!isValid) {
await this.handleFailedLogin(user);
return null;
}
// Check if password needs to be changed
if (user.passwordChangeRequired && user.lastPasswordChange) {
const daysSinceChange = (Date.now() - user.lastPasswordChange) / (1000 * 60 * 60 * 24);
if (daysSinceChange > 90) {
user.passwordChangeRequired = true;
}
}
// Reset failed attempts on successful login
user.failedAttempts = 0;
user.lockUntil = null;
await this.updateUser(user);
return user;
}
async performAdaptiveAuthentication(user, riskScore, context) {
const result = {
success: false,
mfaRequired: false,
passwordChangeRequired: false,
additionalVerification: false
};
// Base requirements
if (riskScore < 30) {
// Low risk - standard authentication
result.success = true;
result.passwordChangeRequired = user.passwordChangeRequired || false;
} else if (riskScore < 60) {
// Medium risk - require MFA
if (user.mfaEnabled && context.mfaToken) {
const mfaValid = await this.mfaProvider.verify(user.mfaSecret, context.mfaToken);
if (mfaValid) {
result.success = true;
result.mfaRequired = true;
result.passwordChangeRequired = user.passwordChangeRequired || false;
}
} else {
result.mfaRequired = true;
}
} else {
// High risk - require MFA + additional verification
result.additionalVerification = true;
if (user.mfaEnabled && context.mfaToken) {
const mfaValid = await this.mfaProvider.verify(user.mfaSecret, context.mfaToken);
if (mfaValid) {
// Additional verification: device fingerprint, behavioral analysis, etc.
const additionalValid = await this.performAdditionalVerification(user, context);
if (additionalValid) {
result.success = true;
result.mfaRequired = true;
result.passwordChangeRequired = user.passwordChangeRequired || false;
}
}
}
}
return result;
}
async performAdditionalVerification(user, context) {
// Device fingerprinting
const deviceFingerprint = this.generateDeviceFingerprint(context);
const deviceTrusted = await this.isDeviceTrusted(user.id, deviceFingerprint);
if (!deviceTrusted) {
// Require device registration or additional approval
return false;
}
// Behavioral biometrics (simplified)
const behaviorValid = await this.analyzeBehavior(user.id, context);
return behaviorValid;
}
async createSecureSession(user, authResult, riskScore, context) {
const sessionId = this.generateSecureToken();
const session = {
id: sessionId,
userId: user.id,
username: user.username,
roles: user.roles,
permissions: user.permissions,
riskScore: riskScore,
createdAt: Date.now(),
lastActivity: Date.now(),
expiresAt: Date.now() + this.config.sessionTimeout,
// Security context
ipAddress: context.ipAddress,
userAgent: context.userAgent,
deviceFingerprint: this.generateDeviceFingerprint(context),
// Authentication context
mfaVerified: authResult.mfaRequired,
additionalVerification: authResult.additionalVerification,
// Session security
maxInactiveTime: this.config.sessionTimeout,
requireReauth: riskScore > 70,
// Audit trail
loginTime: Date.now(),
loginMethod: authResult.mfaRequired ? 'mfa' : 'password',
riskLevel: this.getRiskLevel(riskScore)
};
// Store session
this.sessionStore.set(sessionId, session);
// Log session creation
await this.logSecurityEvent('SESSION_CREATED', {
sessionId,
userId: user.id,
riskScore,
context: this.sanitizeContext(context)
});
return session;
}
async issueTokens(user, session, riskScore) {
const now = Math.floor(Date.now() / 1000);
// Access token - short lived
const accessTokenPayload = {
sub: user.id,
username: user.username,
email: user.email,
roles: user.roles,
permissions: user.permissions,
sessionId: session.id,
riskScore: riskScore,
type: 'access',
iat: now,
exp: now + (15 * 60), // 15 minutes
iss: 'zero-trust-auth',
jti: this.generateSecureToken()
};
const accessToken = jwt.sign(accessTokenPayload, this.jwtSecret, {
algorithm: 'HS256'
});
// Refresh token - longer lived
const refreshTokenPayload = {
sub: user.id,
sessionId: session.id,
type: 'refresh',
iat: now,
exp: now + (7 * 24 * 60 * 60), // 7 days
iss: 'zero-trust-auth',
jti: this.generateSecureToken()
};
const refreshToken = jwt.sign(refreshTokenPayload, this.jwtSecret, {
algorithm: 'HS256'
});
// ID token - contains identity information
const idTokenPayload = {
sub: user.id,
name: user.name,
email: user.email,
picture: user.picture,
email_verified: user.emailVerified,
auth_time: now,
session: session.id,
risk_score: riskScore,
type: 'id',
iat: now,
exp: now + (60 * 60), // 1 hour
iss: 'zero-trust-auth',
jti: this.generateSecureToken()
};
const idToken = jwt.sign(idTokenPayload, this.jwtSecret, {
algorithm: 'HS256'
});
return {
accessToken,
refreshToken,
idToken,
expiresIn: 15 * 60
};
}
async validateToken(token, expectedType = null) {
try {
const decoded = jwt.verify(token, this.jwtSecret, {
algorithms: ['HS256']
});
// Check if token is blacklisted
if (this.tokenBlacklist.has(decoded.jti)) {
throw new Error('Token has been revoked');
}
// Check token type if specified
if (expectedType && decoded.type !== expectedType) {
throw new Error(`Expected ${expectedType} token, got ${decoded.type}`);
}
// Validate session
if (decoded.sessionId) {
const session = this.sessionStore.get(decoded.sessionId);
if (!session || session.expiresAt < Date.now()) {
throw new Error('Session expired');
}
// Update last activity
session.lastActivity = Date.now();
this.sessionStore.set(decoded.sessionId, session);
// Check if re-authentication is required
if (session.requireReauth && decoded.exp - Math.floor(Date.now() / 1000) < (5 * 60)) {
throw new Error('Re-authentication required');
}
}
return decoded;
} catch (error) {
console.error('Token validation error:', error);
throw error;
}
}
async revokeToken(token) {
try {
const decoded = jwt.decode(token);
this.tokenBlacklist.add(decoded.jti);
// Remove session if access token
if (decoded.sessionId) {
this.sessionStore.delete(decoded.sessionId);
}
await this.logSecurityEvent('TOKEN_REVOKED', {
jti: decoded.jti,
userId: decoded.sub,
type: decoded.type
});
return true;
} catch (error) {
console.error('Token revocation error:', error);
return false;
}
}
async refreshToken(refreshToken) {
try {
const decoded = jwt.verify(refreshToken, this.jwtSecret, {
algorithms: ['HS256']
});
if (decoded.type !== 'refresh') {
throw new Error('Invalid token type');
}
// Check session validity
const session = this.sessionStore.get(decoded.sessionId);
if (!session || session.expiresAt < Date.now()) {
throw new Error('Session expired');
}
// Get user
const user = await this.getUserById(decoded.sub);
if (!user) {
throw new Error('User not found');
}
// Re-assess risk
const context = this.getSessionContext(session);
const newRiskScore = await this.riskEngine.assess({
userId: user.id,
sessionId: decoded.sessionId,
context,
timestamp: Date.now(),
tokenRefresh: true
});
// Issue new tokens
const newTokens = await this.issueTokens(user, session, newRiskScore);
// Revoke old refresh token
this.tokenBlacklist.add(decoded.jti);
return {
...newTokens,
session: session,
riskScore: newRiskScore
};
} catch (error) {
console.error('Token refresh error:', error);
throw error;
}
}
generateDeviceFingerprint(context) {
const components = [
context.userAgent || '',
context.language || '',
context.timezone || '',
context.screenResolution || '',
context.colorDepth || '',
context.plugins || ''
];
return crypto
.createHash('sha256')
.update(components.join('|'))
.digest('hex');
}
async isDeviceTrusted(userId, deviceFingerprint) {
// Check if device fingerprint is in trusted list
const trustedDevices = await this.getTrustedDevices(userId);
return trustedDevices.includes(deviceFingerprint);
}
async addTrustedDevice(userId, deviceFingerprint, deviceName) {
const trustedDevices = await this.getTrustedDevices(userId);
if (!trustedDevices.includes(deviceFingerprint)) {
trustedDevices.push({
fingerprint: deviceFingerprint,
name: deviceName,
addedAt: Date.now()
});
await this.saveTrustedDevices(userId, trustedDevices);
await this.logSecurityEvent('DEVICE_TRUSTED', {
userId,
deviceFingerprint,
deviceName
});
}
}
generateSecureToken(length = 32) {
return crypto.randomBytes(length).toString('hex');
}
getRiskLevel(riskScore) {
if (riskScore < 30) return 'low';
if (riskScore < 60) return 'medium';
if (riskScore < 80) return 'high';
return 'critical';
}
// Helper methods (would interact with database)
async getUserByUsername(username) {
// Database implementation
return {
id: 'user_123',
username: username,
passwordHash: '$2b$12$LQv3c1yqBWVHxkd0LHAkOYqBmw6DR3Ly.wVmQ.3f/8XIi2lE',
email: '[email protected]',
name: 'John Doe',
roles: ['user'],
permissions: ['read', 'write'],
mfaEnabled: true,
mfaSecret: 'JBSWY3DPEHPK3PXP',
passwordChangeRequired: false,
lastPasswordChange: Date.now() - (30 * 24 * 60 * 60 * 1000),
failedAttempts: 0,
lockUntil: null
};
}
async getUserById(userId) {
// Database implementation
return {
id: userId,
username: 'john_doe',
passwordHash: '$2b$12$LQv3c1yqBWVHxkd0LHAkOYqBmw6DR3Ly.wVmQ.3f/8XIi2lE',
email: '[email protected]',
name: 'John Doe',
roles: ['user'],
permissions: ['read', 'write'],
mfaEnabled: true,
mfaSecret: 'JBSWY3DPEHPK3PXP',
passwordChangeRequired: false,
lastPasswordChange: Date.now() - (30 * 24 * 60 * 60 * 1000),
failedAttempts: 0,
lockUntil: null
};
}
async updateUser(user) {
// Database implementation
console.log('Updating user:', user.id);
}
async handleFailedLogin(user) {
user.failedAttempts++;
if (user.failedAttempts >= this.config.maxFailedAttempts) {
user.lockUntil = Date.now() + this.config.lockoutDuration;
await this.logSecurityEvent('ACCOUNT_LOCKED', {
userId: user.id,
failedAttempts: user.failedAttempts,
lockUntil: user.lockUntil
});
}
await this.updateUser(user);
}
async getTrustedDevices(userId) {
// Database implementation
return [];
}
async saveTrustedDevices(userId, devices) {
// Database implementation
console.log('Saving trusted devices for user:', userId);
}
async logSecurityEvent(event, data) {
// Security logging implementation
const logEntry = {
timestamp: new Date().toISOString(),
event,
data,
severity: this.getEventSeverity(event)
};
console.log('Security event:', logEntry);
// Would send to SIEM, logging service, etc.
}
getEventSeverity(event) {
const severityMap = {
'SESSION_CREATED': 'info',
'TOKEN_REVOKED': 'warning',
'ACCOUNT_LOCKED': 'high',
'DEVICE_TRUSTED': 'info',
'RISK_HIGH': 'high'
};
return severityMap[event] || 'info';
}
sanitizeContext(context) {
const sanitized = { ...context };
// Remove sensitive information
delete sanitized.password;
delete sanitized.token;
delete sanitized.mfaSecret;
return sanitized;
}
sanitizeUser(user) {
const sanitized = { ...user };
// Remove sensitive information
delete sanitized.passwordHash;
delete sanitized.mfaSecret;
return sanitized;
}
getSessionContext(session) {
return {
sessionId: session.id,
userId: session.userId,
ipAddress: session.ipAddress,
userAgent: session.userAgent,
deviceFingerprint: session.deviceFingerprint
};
}
async analyzeBehavior(userId, context) {
// Simplified behavioral analysis
// In practice, this would analyze typing patterns, mouse movements, etc.
return Math.random() > 0.1; // 90% pass rate for demo
}
}
class RiskAssessmentEngine {
constructor(options = {}) {
this.rules = options.rules || this.getDefaultRules();
this.weights = options.weights || { ...this.getDefaultWeights() };
this.model = new MLModel(options.model);
this.enabled = options.enabled !== false;
}
async assess(context) {
if (!this.enabled) {
return 25; // Default medium risk
}
const scores = await Promise.all([
this.assessLocationRisk(context),
this.assessDeviceRisk(context),
this.assessBehavioralRisk(context),
this.assessTemporalRisk(context),
this.assessNetworkRisk(context)
]);
// Apply weights
let weightedScore = 0;
let totalWeight = 0;
for (const [category, score] of Object.entries(scores)) {
const weight = this.weights[category];
weightedScore += score * weight;
totalWeight += weight;
}
// Normalize to 0-100 scale
const normalizedScore = Math.min(100, Math.max(0, (weightedScore / totalWeight) * 100));
// Apply ML model if available
if (this.model && this.model.isTrained()) {
const mlScore = await this.model.predict(context);
return (normalizedScore + mlScore) / 2;
}
return normalizedScore;
}
async assessLocationRisk(context) {
// Assess based on IP geolocation, VPN usage, etc.
return 20;
}
async assessDeviceRisk(context) {
// Assess based on device fingerprint, OS, browser
return 15;
}
async assessBehavioralRisk(context) {
// Assess based on user behavior patterns
return 25;
}
async assessTemporalRisk(context) {
// Assess based on time of day, frequency of requests
const hour = new Date().getHours();
// Higher risk during off-hours
if (hour < 6 || hour > 22) {
return 30;
} else if (hour < 9 || hour > 17) {
return 20;
} else {
return 10;
}
}
async assessNetworkRisk(context) {
// Assess based on network reputation, encryption
return 15;
}
getDefaultRules() {
return {
location: {
suspiciousCountries: ['CN', 'RU', 'KP', 'IR'],
vpns: ['tor', 'proxy', 'vpn'],
datacenters: ['aws', 'gcp', 'azure']
},
device: {
outdatedBrowsers: ['IE', 'Edge Legacy'],
suspiciousUserAgents: ['bot', 'crawler', 'scanner']
},
behavior: {
rapidRequests: 10, // requests per minute
unusualPatterns: ['concurrent', 'distributed']
}
};
}
getDefaultWeights() {
return {
location: 0.3,
device: 0.2,
behavioral: 0.3,
temporal: 0.1,
network: 0.1
};
}
}
class MFAProvider {
constructor(options = {}) {
this.config = options;
this.issuer = options.issuer || 'ZeroTrust';
}
async generateSecret(user) {
const secret = speakeasy.generateSecret({
name: `ZeroTrust MFA - ${user.username}`,
issuer: this.issuer,
length: 32
});
// Save secret to user profile
user.mfaSecret = secret;
await this.updateUser(user);
// Return provisioning URI and QR code
return {
secret: secret,
provisioningUri: speakeasy.otpauthURL({
secret: secret,
label: `${user.username}@${this.issuer}`,
issuer: this.issuer
})
};
}
async verify(secret, token) {
const verified = speakeasy.totp.verify({
secret: secret,
encoding: 'base32',
token: token,
window: 2 // Allow 2 time steps before/after current time
});
return verified;
}
async updateUser(user) {
// Database implementation
console.log('Updating user MFA settings:', user.id);
}
}
class MLModel {
constructor(options = {}) {
this.isModelTrained = false;
this.model = null;
// Would load pre-trained model here
}
isTrained() {
return this.isModelTrained;
}
async predict(context) {
if (!this.isTrained) {
return 25; // Default prediction
}
// Use model for risk prediction
// This would integrate with actual ML model
return Math.random() * 100;
}
}
// Usage example
const authSystem = new ZeroTrustAuthSystem({
jwtSecret: 'your-super-secret-jwt-key',
sessionTimeout: 15 * 60 * 1000, // 15 minutes
maxFailedAttempts: 5,
lockoutDuration: 30 * 60 * 1000, // 30 minutes
riskEngine: {
enabled: true,
model: {
enabled: false // Disable ML for demo
}
},
mfa: {
issuer: 'ZeroTrust'
}
});
// Authentication middleware
const authenticate = async (req, res, next) => {
try {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing or invalid authorization header' });
}
const token = authHeader.substring(7);
const decoded = await authSystem.validateToken(token);
// Add user info to request
req.user = decoded;
req.session = authSystem.sessionStore.get(decoded.sessionId);
next();
} catch (error) {
console.error('Authentication error:', error);
return res.status(401).json({ error: 'Invalid or expired token' });
}
};
// Authorization middleware
const authorize = (requiredPermissions) => {
return (req, res, next) => {
if (!req.user || !req.user.permissions) {
return res.status(403).json({ error: 'No permissions available' });
}
const userPermissions = req.user.permissions;
const hasPermission = requiredPermissions.every(permission =>
userPermissions.includes(permission) || userPermissions.includes('admin')
);
if (!hasPermission) {
return res.status(403).json({
error: 'Insufficient permissions',
required: requiredPermissions,
current: userPermissions
});
}
next();
};
};
// Example route with Zero Trust
app.get('/api/secure-data', authenticate, authorize(['read']), (req, res) => {
res.json({ message: 'Secure data accessed successfully' });
});
// Session management endpoint
app.post('/api/refresh', async (req, res) => {
try {
const { refreshToken } = req.body;
const result = await authSystem.refreshToken(refreshToken);
res.json(result);
} catch (error) {
res.status(401).json({ error: 'Invalid refresh token' });
}
});
// Logout endpoint
app.post('/api/logout', authenticate, async (req, res) => {
try {
const authHeader = req.headers.authorization;
const token = authHeader.substring(7);
await authSystem.revokeToken(token);
res.json({ message: 'Logged out successfully' });
} catch (error) {
res.status(400).json({ error: 'Logout failed' });
}
});
// MFA enrollment endpoint
app.post('/api/mfa/enroll', authenticate, async (req, res) => {
try {
const mfaSetup = await authSystem.mfaProvider.generateSecret(req.user);
res.json(mfaSetup);
} catch (error) {
res.status(500).json({ error: 'MFA enrollment failed' });
}
});
💻 Segmentation de Réseau Zero Trust
🔴 complex
⭐⭐⭐⭐⭐
Segmentation réseau avancée avec micro-segmentation et politiques dynamiques
⏱️ 50 min
🏷️ network-segmentation, micro-segmentation, firewall, iptables, security
// Zero Trust Network Segmentation Implementation
// Advanced segmentation with micro-segmentation and dynamic policies
const express = require('express');
const iptables = require('iptables');
const winston = require('winston');
const crypto = require('crypto');
class ZeroTrustNetworkSegmentation {
constructor(options = {}) {
this.app = express();
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'network-segmentation.log' }),
new winston.transports.Console()
]
});
this.segmentEngine = new SegmentEngine(options.segmentation);
this.policyEngine = new PolicyEngine(options.policies);
this.enforcementEngine = new EnforcementEngine(options.enforcement);
this.config = {
defaultPolicy: 'deny-all',
inspectionEnabled: options.inspectionEnabled !== false,
loggingEnabled: options.loggingEnabled !== false,
realTimeUpdates: options.realTimeUpdates !== false,
...options
};
this.segments = new Map();
this.policies = new Map();
this.connections = new Map();
this.initialize();
}
initialize() {
this.setupMiddleware();
this.setupRoutes();
this.loadConfiguration();
}
setupMiddleware() {
// Request logging and analysis
this.app.use((req, res, next) => {
this.analyzeRequest(req);
next();
});
// Header injection for inspection
this.app.use((req, res, next) => {
if (this.config.inspectionEnabled) {
req.ztHeaders = this.generateInspectionHeaders(req);
}
next();
});
// Connection tracking
this.app.use((req, res, next) => {
const connectionId = this.getConnectionId(req);
this.trackConnection(connectionId, req);
next();
});
}
setupRoutes() {
// Segmentation management
this.app.post('/api/segments', this.createSegment.bind(this));
this.app.get('/api/segments', this.listSegments.bind(this));
this.app.put('/api/segments/:id', this.updateSegment.bind(this));
this.app.delete('/api/segments/:id', this.deleteSegment.bind(this));
// Policy management
this.app.post('/api/policies', this.createPolicy.bind(this));
this.app.get('/api/policies', this.listPolicies.bind(this));
this.app.put('/api/policies/:id', this.updatePolicy.bind(this));
this.app.delete('/api/policies/:id', this.deletePolicy.bind(this));
// Enforcement
this.app.post('/api/enforce/:segmentId', this.enforcePolicy.bind(this));
this.app.post('/api/enforce/connections', this.enforceOnConnections.bind(this));
// Monitoring and analytics
this.app.get('/api/analytics/segments', this.getSegmentAnalytics.bind(this));
this.app.get('/api/analytics/connections', this.getConnectionAnalytics.bind(this));
this.app.get('/api/analytics/violations', this.getViolationAnalytics.bind(this));
}
async loadConfiguration() {
try {
// Load default segments
const defaultSegments = await this.loadDefaultSegments();
for (const segment of defaultSegments) {
await this.segmentEngine.createSegment(segment);
}
// Load default policies
const defaultPolicies = await this.loadDefaultPolicies();
for (const policy of defaultPolicies) {
await this.policyEngine.createPolicy(policy);
}
this.logger.info('Zero Trust network segmentation configuration loaded');
} catch (error) {
this.logger.error('Failed to load configuration:', error);
}
}
async createSegment(req, res) {
try {
const segmentData = {
...req.body,
id: this.generateId(),
createdAt: Date.now(),
createdBy: req.user?.id || 'system'
};
// Validate segment configuration
this.validateSegmentConfig(segmentData);
// Create segment
const segment = await this.segmentEngine.createSegment(segmentData);
// Apply default policies
await this.applyDefaultPolicies(segment);
res.status(201).json(segment);
this.logger.info(`Created segment: ${segment.id}`);
} catch (error) {
this.logger.error('Failed to create segment:', error);
res.status(400).json({ error: error.message });
}
}
async updateSegment(req, res) {
try {
const { id } = req.params;
const updateData = req.body;
const segment = await this.segmentEngine.getSegment(id);
if (!segment) {
return res.status(404).json({ error: 'Segment not found' });
}
// Validate updates
this.validateSegmentConfig(updateData);
const updatedSegment = await this.segmentEngine.updateSegment(id, updateData);
// Re-apply policies
await this.reapplySegmentPolicies(updatedSegment);
res.json(updatedSegment);
this.logger.info(`Updated segment: ${id}`);
} catch (error) {
this.logger.error('Failed to update segment:', error);
res.status(400).json({ error: error.message });
}
}
async deleteSegment(req, res) {
try {
const { id } = req.params;
await this.segmentEngine.deleteSegment(id);
// Clean up associated policies
await this.cleanupSegmentPolicies(id);
res.status(204).send();
this.logger.info(`Deleted segment: ${id}`);
} catch (error) {
this.logger.error('Failed to delete segment:', error);
res.status(400).json({ error: error.message });
}
}
async listSegments(req, res) {
try {
const segments = await this.segmentEngine.listSegments();
res.json(segments);
} catch (error) {
this.logger.error('Failed to list segments:', error);
res.status(500).json({ error: error.message });
}
}
async createPolicy(req, res) {
try {
const policyData = {
...req.body,
id: this.generateId(),
createdAt: Date.now(),
createdBy: req.user?.id || 'system'
};
// Validate policy configuration
this.validatePolicyConfig(policyData);
const policy = await this.policyEngine.createPolicy(policyData);
res.status(201).json(policy);
this.logger.info(`Created policy: ${policy.id}`);
} catch (error) {
this.logger.error('Failed to create policy:', error);
res.status(400).json({ error: error.message });
}
}
async updatePolicy(req, res) {
try {
const { id } = req.params;
const updateData = req.body;
const policy = await this.policyEngine.getPolicy(id);
if (!policy) {
return res.status(404).json({ error: 'Policy not found' });
}
const updatedPolicy = await this.policyEngine.updatePolicy(id, updateData);
// Update enforcement for affected segments
await this.updatePolicyEnforcement(updatedPolicy);
res.json(updatedPolicy);
this.logger.info(`Updated policy: ${id}`);
} catch (error) {
this.logger.error('Failed to update policy:', error);
res.status(400).json({ error: error.message });
}
}
async deletePolicy(req, res) {
try {
const { id } = req.params;
await this.policyEngine.deletePolicy(id);
// Remove policy from segments
await this.removePolicyFromSegments(id);
res.status(204).send();
this.logger.info(`Deleted policy: ${id}`);
} catch (error) {
this.logger.error('Failed to delete policy:', error);
res.status(400).json({ error: error.message });
}
}
async listPolicies(req, res) {
try {
const policies = await this.policyEngine.listPolicies();
res.json(policies);
} catch (error) {
this.logger.error('Failed to list policies:', error);
res.status(500).json({ error: error.message });
}
}
async enforcePolicy(req, res) {
try {
const { segmentId } = req.params;
const { target, action } = req.body;
const segment = await this.segmentEngine.getSegment(endcodedURIComponent(segmentId));
if (!segment) {
return res.status(404).json({ error: 'Segment not found' });
}
const result = await this.enforcementEngine.enforcePolicy(segment, target, action);
res.json(result);
this.logger.info(`Enforced policy on segment ${segmentId}: ${action} on ${target}`);
} catch (error) {
this.logger.error('Failed to enforce policy:', error);
res.status(500).json({ error: error.message });
}
}
async enforceOnConnections(req, res) {
try {
const { connections } = req.body;
const results = [];
for (const connection of connections) {
const result = await this.enforcePolicyOnConnection(connection);
results.push(result);
}
res.json({ results });
this.logger.info(`Enforced policies on ${connections.length} connections`);
} catch (error) {
this.logger.error('Failed to enforce policies on connections:', error);
res.status(500).json({ error: error.message });
}
}
async getSegmentAnalytics(req, res) {
try {
const analytics = await this.segmentEngine.getAnalytics();
res.json(analytics);
} catch (error) {
this.logger.error('Failed to get segment analytics:', error);
res.status(500).json({ error: error.message });
}
}
async getConnectionAnalytics(req, res) {
try {
const analytics = await this.enforcementEngine.getConnectionAnalytics();
res.json(analytics);
} catch (error) {
this.logger.error('Failed to get connection analytics:', error);
res.status(500).json({ error: error.message });
}
}
async getViolationAnalytics(req, res) {
try {
const violations = await this.enforcementEngine.getViolationAnalytics();
res.json(violations);
} catch (error) {
this.logger.error('Failed to get violation analytics:', error);
res.status(500).json({ error: error.message });
}
}
async analyzeRequest(req) {
const analysis = {
timestamp: Date.now(),
method: req.method,
url: req.url,
headers: this.sanitizeHeaders(req.headers),
ip: req.ip,
userAgent: req.get('User-Agent'),
connectionId: this.getConnectionId(req)
};
// Run through policy engine
const decision = await this.policyEngine.evaluateRequest(analysis);
if (decision.action === 'block') {
this.logger.warn(`Request blocked: ${analysis.url} from ${analysis.ip}`, decision);
}
// Store for analytics
this.storeRequestAnalytics(analysis, decision);
}
generateInspectionHeaders(req) {
const timestamp = Date.now();
const requestId = this.generateId();
return {
'X-ZT-Timestamp': timestamp,
'X-ZT-Request-ID': requestId,
'X-ZT-Segmentation': 'pending',
'X-ZT-Risk-Score': '0',
'X-ZT-Inspection': 'enabled'
};
}
getConnectionId(req) {
// Generate consistent connection ID from request characteristics
const components = [
req.ip,
req.get('User-Agent') || '',
req.get('X-Forwarded-For') || ''
];
return crypto
.createHash('sha256')
.update(components.join('|'))
.digest('hex')
.substring(0, 16);
}
trackConnection(connectionId, req) {
if (!this.connections.has(connectionId)) {
this.connections.set(connectionId, {
id: connectionId,
firstSeen: Date.now(),
lastSeen: Date.now(),
requestCount: 0,
bytesReceived: 0,
bytesSent: 0,
userAgent: req.get('User-Agent'),
ip: req.ip
});
}
const connection = this.connections.get(connectionId);
connection.lastSeen = Date.now();
connection.requestCount++;
connection.bytesReceived += req.socket.bytesRead || 0;
}
async enforcePolicyOnConnection(connection) {
try {
// Identify segment for connection
const segment = await this.identifyConnectionSegment(connection);
// Get applicable policies
const policies = await this.getApplicablePolicies(segment);
// Enforce policies
const results = [];
for (const policy of policies) {
const result = await this.enforcementEngine.enforcePolicy(
segment,
`connection:${connection.id}`,
'allow'
);
results.push({
policyId: policy.id,
result
});
}
return {
connectionId: connection.id,
segmentId: segment.id,
policies: results,
overall: results.every(r => r.result.action === 'allow') ? 'allow' : 'block'
};
} catch (error) {
this.logger.error('Failed to enforce policy on connection:', error);
return {
connectionId: connection.id,
error: error.message,
overall: 'error'
};
}
}
async identifyConnectionSegment(connection) {
// Use various heuristics to identify segment
const segmentRules = [
{
name: 'internal-traffic',
condition: (conn) => this.isInternalIP(conn.ip)
},
{
name: 'external-traffic',
condition: (conn) => !this.isInternalIP(conn.ip)
},
{
name: 'vpn-traffic',
condition: (conn) => this.isVPNConnection(conn)
},
{
name: 'admin-access',
condition: (conn) => conn.userAgent.includes('admin') || this.isAdminIP(conn.ip)
}
];
for (const rule of segmentRules) {
if (rule.condition(connection)) {
return { id: rule.name, name: rule.name };
}
}
return { id: 'default', name: 'Default Segment' };
}
async getApplicablePolicies(segment) {
return await this.policyEngine.getPoliciesForSegment(segment.id);
}
validateSegmentConfig(config) {
const requiredFields = ['name', 'type', 'description'];
for (const field of requiredFields) {
if (!config[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
// Validate network configurations
if (config.network) {
if (config.network.cidr && !this.isValidCIDR(config.network.cidr)) {
throw new Error('Invalid CIDR format');
}
}
}
validatePolicyConfig(config) {
const requiredFields = ['name', 'type', 'action'];
for (const field of requiredFields) {
if (!config[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
// Validate action
const validActions = ['allow', 'deny', 'log', 'alert'];
if (!validActions.includes(config.action)) {
throw new Error(`Invalid action. Must be one of: ${validActions.join(', ')}`);
}
// Validate target
const validTargets = ['any', 'ip', 'port', 'protocol', 'user', 'device'];
if (config.target && !validTargets.includes(config.target.type)) {
throw new Error(`Invalid target type. Must be one of: ${validTargets.join(', ')}`);
}
}
generateId() {
return crypto.randomBytes(16).toString('hex');
}
isInternalIP(ip) {
const internalRanges = [
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16',
'127.0.0.0/8'
];
return internalRanges.some(range => this.ipInCIDR(ip, range));
}
isVPNConnection(connection) {
// Check for common VPN indicators
const vpnIndicators = [
'vpn',
'tunnel',
'proxy'
];
return vpnIndicators.some(indicator =>
connection.userAgent?.toLowerCase().includes(indicator) ||
connection.ip?.includes(indicator)
);
}
isAdminIP(ip) {
const adminIPs = ['192.168.1.100', '10.0.0.1']; // Would load from config
return adminIPs.includes(ip);
}
isValidCIDR(cidr) {
// Simplified CIDR validation
const cidrPattern = /^(d{1,3}.){3}d{1,3}/d{1,2}$/;
return cidrPattern.test(cidr);
}
ipInCIDR(ip, cidr) {
const [network, prefixLength] = cidr.split('/');
const [networkStart] = network.split('.').map(Number);
const [ipStart] = ip.split('.').map(Number);
// Convert to 32-bit integers
const networkNum = (networkStart[0] << 24) + (networkStart[1] << 16) + (networkStart[2] << 8) + networkStart[3];
const ipNum = (ipStart[0] << 24) + (ipStart[1] << 16) + (ipStart[2] << 8) + ipStart[3]);
const mask = (0xFFFFFFFF << (32 - parseInt(prefixLength))) >>> 0;
return (networkNum & mask) === (ipNum & mask);
}
sanitizeHeaders(headers) {
const sanitized = {};
for (const [key, value] of Object.entries(headers)) {
if (!key.toLowerCase().includes('password') &&
!key.toLowerCase().includes('secret') &&
!key.toLowerCase().includes('token')) {
sanitized[key] = value;
}
}
return sanitized;
}
storeRequestAnalytics(analysis, decision) {
// Store in analytics database
this.logger.info('Request analyzed', {
analysis,
decision,
severity: decision.action === 'block' ? 'warning' : 'info'
});
}
async loadDefaultSegments() {
return [
{
name: 'critical-infrastructure',
type: 'infrastructure',
description: 'Critical infrastructure servers and systems',
network: {
cidr: '10.0.1.0/24',
ports: [22, 443, 3389, 5432, 8080],
protocols: ['ssh', 'https', 'mysql', 'postgres']
},
policies: ['strict-security', 'monitoring'],
tags: ['infrastructure', 'critical']
},
{
name: 'developer-workstations',
type: 'workstation',
description: 'Developer workstations and dev environments',
network: {
cidr: '192.168.1.0/24',
ports: [22, 80, 443, 3000, 8080, 9000],
protocols: ['ssh', 'http', 'https', 'websocket']
},
policies: ['developer-access', 'build-tools'],
tags: ['development', 'workstation']
},
{
name: 'guest-wifi',
type: 'guest',
description: 'Guest WiFi network with restricted access',
network: {
cidr: '172.16.32.0/22',
ports: [80, 443],
protocols: ['http', 'https']
},
policies: ['guest-access', 'web-only'],
tags: ['guest', 'wifi']
},
{
name: 'iot-devices',
type: 'iot',
description: 'IoT devices and sensors',
network: {
cidr: '10.10.0.0/16',
ports: [80, 443, 1883, 8883],
protocols: ['http', 'https', 'mqtt', 'coap']
},
policies: ['iot-security', 'device-communication'],
tags: ['iot', 'sensors']
}
];
}
async loadDefaultPolicies() {
return [
{
name: 'deny-all',
type: 'default',
action: 'deny',
description: 'Default deny all traffic',
priority: 1,
rules: [
{
target: { type: 'any' },
action: 'deny',
log: true
}
]
},
{
name: 'allow-internal-dns',
type: 'network',
action: 'allow',
description: 'Allow internal DNS queries',
priority: 10,
rules: [
{
target: { type: 'protocol', value: 'dns' },
action: 'allow',
log: false
},
{
target: { type: 'ip', value: '10.0.1.1' },
action: 'allow',
log: false
},
{
target: { type: 'ip', value: '8.8.8.8' },
action: 'allow',
log: false
}
]
},
{
name: 'block-suspicious-ips',
type: 'security',
action: 'deny',
description: 'Block known malicious IP addresses',
priority: 100,
rules: [],
threatIntelFeed: true // Would integrate with threat intel feeds
},
{
name: 'require-mfa-for-admin',
type: 'security',
action: 'deny',
description: 'Require MFA for admin access',
priority: 50,
rules: [
{
condition: 'user.role == admin',
target: { type: 'any' },
action: 'deny',
unless: 'user.mfaVerified',
log: true
}
]
},
{
name: 'rate-limit-api-calls',
type: 'security',
action: 'deny',
description: 'Rate limit API calls',
priority: 30,
rules: [
{
target: { type: 'protocol', value: 'http' },
action: 'limit',
rate: { requests: 100, window: '60s' },
log: true
}
]
},
{
name: 'log-all-traffic',
type: 'logging',
action: 'allow',
description: 'Log all network traffic for analysis',
priority: 1,
rules: [
{
target: { type: 'any' },
action: 'allow',
log: true
}
]
}
];
}
async applyDefaultPolicies(segment) {
const defaultPolicies = await this.loadDefaultPolicies();
for (const policy of defaultPolicies) {
try {
await this.segmentEngine.addPolicyToSegment(segment.id, policy.id);
} catch (error) {
this.logger.error(`Failed to apply default policy ${policy.id} to segment ${segment.id}:`, error);
}
}
}
async reapplySegmentPolicies(segment) {
// Remove existing policies
await this.segmentEngine.removeAllPoliciesFromSegment(segment.id);
// Re-apply policies
await this.applyDefaultPolicies(segment);
}
async cleanupSegmentPolicies(segmentId) {
const policies = await this.policyEngine.getPoliciesForSegment(segmentId);
for (const policy of policies) {
try {
await this.segmentEngine.removePolicyFromSegment(segmentId, policy.id);
} catch (error) {
this.logger.error(`Failed to remove policy ${policy.id} from segment ${segmentId}:`, error);
}
}
}
async updatePolicyEnforcement(policy) {
// Get segments using this policy
const segments = await this.segmentEngine.getSegmentsUsingPolicy(policy.id);
for (const segment of segments) {
await this.enforcementEngine.updatePolicyEnforcement(segment, policy);
}
}
async removePolicyFromSegments(policyId) {
const segments = await this.segmentEngine.getSegmentsUsingPolicy(policyId);
for (const segment of segments) {
await this.enforcementEngine.removePolicyEnforcement(segment, policyId);
}
}
}
class SegmentEngine {
constructor(options = {}) {
this.segments = new Map();
this.segmentPolicies = new Map(); // segmentId -> Set of policyIds
}
async createSegment(segmentData) {
this.segments.set(segmentData.id, segmentData);
this.segmentPolicies.set(segmentData.id, new Set());
return segmentData;
}
async getSegment(id) {
return this.segments.get(id);
}
async updateSegment(id, updateData) {
const segment = this.segments.get(id);
if (!segment) {
throw new Error('Segment not found');
}
Object.assign(segment, updateData);
segment.updatedAt = Date.now();
return segment;
}
async deleteSegment(id) {
this.segments.delete(id);
this.segmentPolicies.delete(id);
}
async listSegments() {
return Array.from(this.segments.values());
}
async addPolicyToSegment(segmentId, policyId) {
const policies = this.segmentPolicies.get(segmentId);
policies.add(policyId);
}
async removePolicyFromSegment(segmentId, policyId) {
const policies = this.segmentPolicies.get(segmentId);
policies.delete(policyId);
}
async removeAllPoliciesFromSegment(segmentId) {
this.segmentPolicies.set(segmentId, new Set());
}
async getSegmentsUsingPolicy(policyId) {
const segments = [];
for (const [segmentId, policyIds] of this.segmentPolicies.entries()) {
if (policyIds.has(policyId)) {
const segment = await this.getSegment(segmentId);
if (segment) {
segments.push(segment);
}
}
}
return segments;
}
async getAnalytics() {
return {
totalSegments: this.segments.size,
segmentsWithPolicies: Array.from(this.segmentPolicies.entries()).filter(([_, policies]) => policies.size > 0).length,
averagePoliciesPerSegment: this.calculateAveragePolicies(),
segmentTypes: this.getSegmentTypeDistribution()
};
}
calculateAveragePolicies() {
const totalPolicies = Array.from(this.segmentPolicies.values()).reduce((sum, policies) => sum + policies.size, 0);
return this.segments.size > 0 ? totalPolicies / this.segments.size : 0;
}
getSegmentTypeDistribution() {
const distribution = {};
for (const segment of this.segments.values()) {
distribution[segment.type] = (distribution[segment.type] || 0) + 1;
}
return distribution;
}
}
class PolicyEngine {
constructor(options = {}) {
this.policies = new Map();
this.defaultPolicy = options.defaultPolicy || 'deny-all';
}
async createPolicy(policyData) {
this.policies.set(policyData.id, policyData);
return policyData;
}
async getPolicy(id) {
return this.policies.get(id);
}
async updatePolicy(id, updateData) {
const policy = this.policies.get(id);
if (!policy) {
throw new Error('Policy not found');
}
Object.assign(policy, updateData);
policy.updatedAt = Date.now();
return policy;
}
async deletePolicy(id) {
this.policies.delete(id);
}
async listPolicies() {
return Array.from(this.policies.values());
}
async getPoliciesForSegment(segmentId) {
const policies = [];
for (const policy of this.policies.values()) {
if (policy.segments && policy.segments.includes(segmentId)) {
policies.push(policy);
}
}
return policies;
}
async evaluateRequest(request) {
// Evaluate request against all policies
let decision = { action: 'allow' };
for (const policy of this.policies.values()) {
const policyDecision = await this.evaluatePolicy(request, policy);
// Use most restrictive decision
if (policyDecision.action === 'deny') {
decision = policyDecision;
break; // Deny takes precedence
}
}
return decision;
}
async evaluatePolicy(request, policy) {
for (const rule of policy.rules) {
const matches = await this.evaluateRule(request, rule);
if (matches) {
return {
action: rule.action,
policyId: policy.id,
rule: rule,
matchedCondition: rule.condition
};
}
}
// Default to policy action
return {
action: policy.action,
policyId: policy.id
};
}
async evaluateRule(request, rule) {
if (rule.condition) {
return await this.evaluateCondition(request, rule.condition);
}
return false;
}
async evaluateCondition(request, condition) {
// Handle different condition types
if (typeof condition === 'string') {
// String condition - parse and evaluate
return await this.evaluateStringCondition(request, condition);
} else if (typeof condition === 'object' && condition.type) {
// Object condition
return this.evaluateObjectCondition(request, condition);
}
return false;
}
async evaluateStringCondition(request, condition) {
// Simple string-based evaluation
// In practice, this would use a proper expression parser
const context = {
user: request.user,
ip: request.ip,
userAgent: request.userAgent,
method: request.method,
url: request.url
};
try {
// Use Function constructor for safe evaluation
const func = new Function('context', `return ${condition}`);
return func(context);
} catch (error) {
console.error(`Error evaluating condition '${condition}':`, error);
return false;
}
}
evaluateObjectCondition(request, condition) {
const context = {
user: request.user,
ip: request.ip,
userAgent: request.userAgent,
method: request.method,
url: request.url
};
switch (condition.type) {
case 'equals':
return this.compareValues(context, condition.field, condition.value, '==');
case 'not-equals':
return this.compareValues(context, condition.field, condition.value, '!=');
case 'contains':
return String(context[condition.field]).toLowerCase().includes(String(condition.value).toLowerCase());
case 'regex':
const regex = new RegExp(condition.pattern, condition.flags || '');
return regex.test(String(context[condition.field]));
case 'in':
return Array.isArray(condition.value) &&
condition.value.includes(context[condition.field]);
default:
return false;
}
}
compareValues(context, field, value, operator) {
const contextValue = this.getNestedValue(context, field);
const conditionValue = value;
switch (operator) {
case '==':
return contextValue === conditionValue;
case '!=':
return contextValue !== conditionValue;
case '>':
return Number(contextValue) > Number(conditionValue);
case '<':
return Number(contextValue) < Number(conditionValue);
case '>=':
return Number(contextValue) >= Number(conditionValue);
case '<=':
return Number(contextValue) <= Number(conditionValue);
default:
return false;
}
}
getNestedValue(obj, path) {
return path.split('.').reduce((current, key) => current?.[ key ], obj);
}
}
class EnforcementEngine {
constructor(options = {}) {
this.enforcementRules = new Map();
this.violations = [];
this.connectionAnalytics = new Map();
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
)
});
}
async enforcePolicy(segment, target, action) {
const rule = {
target,
action,
timestamp: Date.now(),
segmentId: segment.id,
policyId: 'unknown'
};
try {
// Implement enforcement based on target type
const result = await this.enforceRule(rule, segment);
if (result.action === 'block') {
this.logViolation(rule);
}
return result;
} catch (error) {
this.logger.error('Policy enforcement error:', error);
return {
action: 'error',
error: error.message
};
}
}
async enforceRule(rule, segment) {
switch (rule.target.type) {
case 'ip':
return await this.enforceIPRule(rule, segment);
case 'port':
return await this.enforcePortRule(rule, segment);
case 'protocol':
return await this.enforceProtocolRule(rule, segment);
case 'user':
return await this.enforceUserRule(rule, segment);
case 'device':
return await this.enforceDeviceRule(rule, segment);
default:
return { action: 'allow', message: 'Unknown target type' };
}
}
async enforceIPRule(rule, segment) {
// Implement IP-based enforcement using iptables
return await this.enforceWithIPTable(rule, segment);
}
async enforcePortRule(rule, segment) {
// Implement port-based enforcement
return await this.enforceWithIPTable(rule, segment);
}
async enforceProtocolRule(rule, segment) {
// Implement protocol-based enforcement
return await this.enforceWithIPTable(rule, segment);
}
async enforceUserRule(rule, segment) {
// User-based enforcement handled at application level
return { action: 'allow', message: 'User enforcement requires application integration' };
}
async enforceDeviceRule(rule, segment) {
// Device-based enforcement handled at application level
return { action: 'allow', message: 'Device enforcement requires application integration' };
}
async enforceWithIPTable(rule, segment) {
// Implement actual iptables enforcement
const command = this.generateIPTableCommand(rule, segment);
try {
await this.executeShellCommand(command);
return {
action: rule.action,
message: `Rule enforced: ${command}`,
command: command
};
} catch (error) {
this.logger.error('iptables enforcement error:', error);
return {
action: 'error',
error: error.message
};
}
}
generateIPTableCommand(rule, segment) {
let command = 'iptables';
switch (rule.target.type) {
case 'ip':
command += ` -s ${segment.network.cidr}`;
if (rule.action === 'deny') {
command += ' -j DROP';
} else {
command += ' -j ACCEPT';
}
command += ` -s ${rule.target.value}`;
break;
case 'port':
command += ` -p ${rule.target.value} -j ${rule.action}`;
if (segment.network.cidr) {
command += ` -s ${segment.network.cidr}`;
}
break;
case 'protocol':
command += ` -p ${rule.target.value} -j ${rule.action}`;
break;
default:
throw new Error(`Unsupported target type: ${rule.target.type}`);
}
command += ` -m comment "Zero Trust: ${rule.policyId}"`;
return command;
}
async executeShellCommand(command) {
return new Promise((resolve, reject) => {
const { spawn } = require('child_process');
const process = spawn(command, { shell: true });
let stdout = '';
let stderr = '';
process.stdout.on('data', (data) => {
stdout += data;
});
process.stderr.on('data', (data) => {
stderr += data;
});
process.on('close', (code) => {
if (code === 0) {
resolve({ stdout, stderr, code });
} else {
reject(new Error(`Command failed with exit code ${code}`));
}
});
process.on('error', (error) => {
reject(error);
});
});
}
logViolation(rule) {
const violation = {
id: this.generateId(),
timestamp: rule.timestamp,
segmentId: rule.segmentId,
policyId: rule.policyId,
target: rule.target,
action: rule.action,
reason: rule.message || 'Policy violation',
context: this.getContextInfo()
};
this.violations.push(violation);
this.logger.warn('Policy violation detected', violation);
// Could send alerts to SIEM
this.sendSecurityAlert(violation);
}
sendSecurityAlert(violation) {
// Send security alert to SIEM or monitoring system
console.log('Security Alert:', JSON.stringify(violation, null, 2));
}
getContextInfo() {
return {
timestamp: Date.now(),
hostname: require('os').hostname(),
platform: process.platform,
nodeVersion: process.version,
memory: process.memoryUsage()
};
}
getConnectionAnalytics() {
return {
totalConnections: this.connectionAnalytics.size,
activeConnections: Array.from(this.connectionAnalytics.values())
.filter(conn => Date.now() - conn.lastSeen < 30000) // Last 30 seconds
.length,
averageRequestCount: this.calculateAverageRequestCount(),
totalBytes: this.calculateTotalBytes()
};
}
getViolationAnalytics() {
return {
totalViolations: this.violations.length,
violationsByType: this.getViolationsByType(),
violationsByPolicy: this.getViolationsByPolicy(),
recentViolations: this.getRecentViolations(),
topViolations: this.getTopViolations()
};
}
calculateAverageRequestCount() {
const connections = Array.from(this.connectionAnalytics.values());
if (connections.length === 0) return 0;
const totalRequests = connections.reduce((sum, conn) => sum + conn.requestCount, 0);
return totalRequests / connections.length;
}
calculateTotalBytes() {
const connections = Array.from(this.connectionAnalytics.values());
return connections.reduce((sum, conn) => sum + (conn.bytesReceived + conn.bytesSent), 0);
}
getViolationsByType() {
const types = {};
for (const violation of this.violations) {
const type = violation.target?.type || 'unknown';
types[type] = (types[type] || 0) + 1;
}
return types;
}
getViolationsByPolicy() {
const policies = {};
for (const violation of this.violations) {
const policyId = violation.policyId || 'unknown';
policies[policyId] = (policies[policyId] || 0) + 1;
}
return policies;
}
getRecentViolations() {
const oneHourAgo = Date.now() - (60 * 60 * 1000);
return this.violations.filter(v => v.timestamp > oneHourAgo);
}
getTopViolations() {
const counts = {};
for (const violation of this.violations) {
const key = `${violation.policyId}:${violation.target?.type}`;
counts[key] = (counts[key] || 0) + 1;
}
return Object.entries(counts)
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
.map(([key, count]) => {
const [policyId, target] = key.split(':');
return {
policyId,
target,
count
};
});
}
generateId() {
require('crypto').randomBytes(16).toString('hex');
}
}
// Usage example
const segmentation = new ZeroTrustNetworkSegmentation({
segmentation: {
defaultPolicy: 'deny-all',
inspectionEnabled: true,
realTimeUpdates: true
},
policies: {
defaultPolicy: 'deny-all',
loggingEnabled: true
},
enforcement: {
defaultAction: 'block',
enableLogging: true,
enableAlerts: true
}
});
// Start the segmentation service
const port = process.env.PORT || 3001;
segmentation.app.listen(port, () => {
console.log(`Zero Trust Network Segmentation API listening on port ${port}`);
});
// Graceful shutdown
process.on('SIGINT', () => {
console.log('Shutting down...');
process.exit(0);
});
💻 Micro-Segmentation de Réseau Zero Trust
🔴 complex
⭐⭐⭐⭐⭐
Segmentation micro avec granularité au niveau des applications
⏱️ 45 min
🏷️ micro-segmentation, kubernetes, docker, container-security, zero-trust
// Zero Trust Micro-Segmentation Implementation
// Granular segmentation for containers and applications
const express = require('express');
const { EventEmitter } = require('events');
const Docker = require('dockerode');
const Kubernetes = require('@kubernetes/client');
const winston = require('winston');
class ZeroTrustMicroSegmentation extends EventEmitter {
constructor(options = {}) {
super();
this.config = {
// Container orchestration
orchestration: options.orchestration || 'kubernetes',
dockerApi: options.dockerApi || '/var/run/docker.sock',
kubernetesConfig: options.kubernetesConfig,
// Segmentation strategy
strategy: options.strategy || 'application-based',
defaultPolicy: 'deny-all',
// Runtime settings
enableRuntimePolicies: options.enableRuntimePolicies !== false,
enableAPIAccess: options.enableAPIAccess !== false,
realTimeUpdates: options.realTimeUpdates !== false,
// Analytics
enableAnalytics: options.enableAnalytics !== false,
analyticsRetention: options.analyticsRetention || '24h',
...options
};
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json(),
winston.format.colorize(),
winston.format.simple()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'micro-segmentation.log' })
]
});
this.segments = new Map();
this.microSegments = new Map();
this.workloadProfiles = new Map();
this.runtimePolicies = new Map();
this.orchestrator = null;
this.client = null;
this.initialize();
}
async initialize() {
await this.setupOrchestrator();
await this.setupClients();
await this.loadInitialConfiguration();
this.logger.info('Zero Trust micro-segmentation initialized');
this.emit('initialized');
}
async setupOrchestration() {
switch (this.config.orchestration) {
case 'kubernetes':
await this.setupKubernetes();
break;
case 'docker':
await this.setupDocker();
break;
default:
throw new Error(`Unsupported orchestration: ${this.config.orchestration}`);
}
}
async setupKubernetes() {
try {
const kc = new Kubernetes.KubeConfig(this.config.kubernetesConfig);
this.client = new Kubernetes.CoreV1Api(kc);
this.orchestrator = new Kubernetes.CoreV1Api(kc);
this.logger.info('Kubernetes client initialized');
} catch (error) {
this.logger.error('Failed to initialize Kubernetes client:', error);
throw error;
}
}
async setupDocker() {
try {
this.orchestrator = new Docker.Docker({ socketPath: this.config.dockerApi });
await this.orchestrator.ping();
this.logger.info('Docker client initialized');
} catch (error) {
this.logger.error('docker connection failed:', error);
throw error;
}
}
setupClients() {
if (this.config.enableAPIAccess) {
this.setupAPIRoutes();
}
// Setup real-time updates
if (this.config.realTimeUpdates) {
this.setupRealTimeUpdates();
}
}
setupAPIRoutes() {
this.app.use(express.json());
this.logger.info('API routes configured');
}
setupRealTimeUpdates() {
// WebSocket for real-time updates
const WebSocket = require('ws');
this.wss = new WebSocket.Server({ port: 8081 });
this.wss.on('connection', (ws) => {
ws.on('message', (data) => {
try {
const message = JSON.parse(data);
this.handleRealTimeUpdate(message);
} catch (error) {
this.logger.error('Real-time update error:', error);
}
});
});
this.logger.info('WebSocket server started on port 8081');
}
handleRealTimeUpdate(message) {
switch (message.type) {
case 'segment-updated':
this.broadcastSegmentUpdate(message.data);
break;
case 'policy-updated':
this.broadcastPolicyUpdate(message.data);
break;
case 'workload-detected':
this.handleWorkloadDetection(message.data);
break;
default:
this.logger.warn('Unknown real-time update type:', message.type);
}
}
broadcastSegmentUpdate(segmentData) {
if (this.wss) {
const message = {
type: 'segment-updated',
data: segmentData
};
this.wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(message));
}
});
}
}
async loadInitialConfiguration() {
try {
// Load workload profiles
await this.loadWorkloadProfiles();
// Load runtime policies
if (this.config.enableRuntimePolicies) {
await this.loadRuntimePolicies();
}
// Create initial segments based on discovered workloads
await this.createInitialSegments();
} catch (error) {
this.logger.error('Failed to load initial configuration:', error);
}
}
async loadWorkloadProfiles() {
const profiles = [
{
name: 'web-server',
type: 'application',
description: 'Web server workloads',
resourceRequirements: {
cpu: '500m',
memory: '1Gi',
bandwidth: '100Mbps'
},
securityRequirements: {
networkAccess: ['http', 'https'],
databaseAccess: true,
filesystemAccess: false
},
complianceRequirements: {
dataClassification: 'confidential',
retentionPeriod: '30d',
auditLogging: true
}
},
{
name: 'database-server',
type: 'application',
description: 'Database server workloads',
resourceRequirements: {
cpu: '2vCPU',
memory: '4Gi',
bandwidth: '1Gbps',
storage: '100Gi'
},
securityRequirements: {
networkAccess: ['postgres', 'mysql'],
databaseAccess: true,
filesystemAccess: true
},
complianceRequirements: {
dataClassification: 'sensitive',
retentionPeriod: '90d',
auditLogging: true,
encryptionAtRest: true
}
},
{
name: 'api-gateway',
type: 'application',
description: 'API gateway workloads',
resourceRequirements: {
cpu: '1vCPU',
memory: '2Gi',
bandwidth: '500Mbps'
},
securityRequirements: {
networkAccess: ['http', 'https'],
databaseAccess: true,
filesystemAccess: false
},
complianceRequirements: {
dataClassification: 'restricted',
retentionPeriod: '7d'
}
},
{
name: 'batch-processing',
type: 'application',
description: 'Batch processing workloads',
resourceRequirements: {
cpu: '4vCPU',
memory: '8Gi',
bandwidth: '2Gbps'
},
securityRequirements: {
networkAccess: ['sftp', 'ssh'],
databaseAccess: true,
filesystemAccess: true
},
complianceRequirements: {
dataClassification: 'confidential',
retentionPeriod: '60d'
}
}
];
for (const profile of profiles) {
this.workloadProfiles.set(profile.name, profile);
}
this.logger.info(`Loaded ${profiles.length} workload profiles`);
}
async loadRuntimePolicies() {
const policies = [
{
name: 'container-runtime-protection',
type: 'security',
description: 'Container runtime security policies',
rules: [
{
name: 'block-privileged-containers',
condition: {
field: 'runtime.privileged',
operator: '==',
value: true
},
action: 'deny',
severity: 'high'
},
{
name: 'require-read-only-filesystem',
condition: {
field: 'runtime.readOnlyRootfs',
operator: '!=',
value: true
},
action: 'deny',
severity: 'medium'
},
{
'name: 'restrict-cap-drop',
condition: {
field: 'runtime.capDrop',
operator: '==',
value: true
},
action: 'deny',
severity: 'high'
},
{
'name: 'no-new-privileges',
condition: {
field: 'runtime.noNewPrivileges',
operator: '!=',
value: true
},
action: 'deny',
severity: 'medium'
}
]
},
{
name: 'network-access-control',
type: 'network',
description: 'Network access control for containers',
rules: [
{
name: 'block-external-requests-by-default',
condition: {
field: 'network.defaultExternalAccess',
operator: '!=',
value: true
},
action: 'deny',
severity: 'high'
},
{
'name: 'allow-dns-resolution',
condition: {
field: 'network.dnsAccess',
operator: '==',
value: true
},
action: 'allow',
severity: 'low'
},
{
name: 'rate-limit-outbound-connections',
condition: {
field: 'network.maxOutboundConnections',
operator: '>',
value: 100
},
action: 'limit',
severity: 'medium'
}
]
},
{
name: 'application-security',
type: 'application',
description: 'Application-level security controls',
rules: [
{
name: 'disable-insecure-protocols',
condition: {
field: 'application.insecureProtocols',
operator: 'includes',
value: ['telnet', 'ftp', 'rsh', 'rlogin']
},
action: 'deny',
severity: 'high'
},
{
name: 'scan-for-secrets',
condition: {
field: 'application.scanSecrets',
operator: '==',
value: true
},
action: 'deny',
severity: 'medium'
},
{
'enforce-read-only-filesystem',
condition: {
field: 'application.readOnlyRootfs',
operator: '==',
value: true
},
action: 'deny',
severity: 'medium'
}
]
}
];
for (const policy of policies) {
this.runtimePolicies.set(policy.name, policy);
}
this.logger.info(`Loaded ${policies.length} runtime policies`);
}
async createInitialSegments() {
try {
// Auto-create segments for discovered workloads
for (const profile of this.workloadProfiles.values()) {
const segment = await this.createMicroSegment({
name: profile.name,
workloadId: profile.name,
type: profile.type,
target: 'container',
parent: 'default'
});
this.logger.info(`Created micro-segment for workload: ${profile.name}`);
}
// Create network-level segments
await this.createNetworkSegments();
} catch (error) {
this.logger.error('Failed to create initial segments:', error);
}
}
async createMicroSegment(segmentConfig) {
const segment = {
id: this.generateId(),
name: segmentConfig.name,
type: segmentConfig.type,
workloadId: segmentConfig.workloadId,
target: segmentConfig.target,
parent: segmentConfig.parent || 'default',
// Network configuration
network: {
cidr: '10.0.0.0/24',
ports: [],
protocols: []
},
// Security configuration
security: {
policies: ['container-runtime-protection', 'network-access-control'],
enforcementMode: 'strict'
},
// Resource limits
resources: {
cpu: segmentConfig.resourceRequirements?.cpu || '500m',
memory: segmentConfig.resourceRequirements?.memory || '1Gi',
ephemeral: segmentConfig.ephemeral || false
},
// Labels for identification
labels: {
workload: segmentConfig.workloadId,
type: 'micro-segment',
environment: process.env.NODE_ENV || 'production'
},
// Metadata
createdAt: Date.now(),
updatedAt: Date.now(),
createdBy: 'auto-creation',
status: 'active'
};
// Configure network based on target type
this.configureSegmentNetwork(segment, segmentConfig);
// Apply security policies
await this.applySegmentSecurityPolicies(segment);
// Store segment
this.microSegments.set(segment.id, segment);
this.segments.set(segment.id, segment);
this.emit('segmentCreated', segment);
return segment;
}
async createNetworkSegments() {
const networkSegments = [
{
name: 'critical-infrastructure',
type: 'network',
network: {
cidr: '10.0.1.0/24'
},
policies: ['network-access-control'],
enforcementMode: 'strict'
},
{
name: 'development-network',
type: 'network',
network: {
cidr: '192.168.1.0/24'
},
policies: ['network-access-control'],
enforcementMode: 'permissive'
},
{
name: 'guest-network',
type: 'network',
network: {
cidr: '172.16.0.0/22'
},
policies: ['network-access-control', 'guest-access'],
enforcementMode: 'restrictive'
}
];
for (const networkSegment of networkSegments) {
const segment = {
id: this.generateId(),
name: networkSegment.name,
type: networkSegment.type,
target: 'network',
network: networkSegment.network,
policies: networkSegment.policies,
enforcementMode: networkSegment.enforcementMode,
createdAt: Date.now(),
updatedAt: Date.now(),
createdBy: 'auto-creation',
status: 'active'
};
this.segments.set(segment.id, segment);
this.logger.info(`Created network segment: ${segment.name}`);
}
}
configureNetwork(segment, config) {
if (config.type === 'container') {
// Container-specific network configuration
if (config.network?.cidr) {
segment.network.cidr = config.network.cidr;
}
// Auto-detect ports from workload
if (config.ports && config.ports.length > 0) {
segment.network.ports = config.ports;
}
// Auto-detect protocols
if (config.protocols && config.protocols.length > 0) {
segment.network.protocols = config.protocols;
}
} else if (config.type === 'network') {
// Network-level configuration is already set
// No additional configuration needed
}
}
async applySegmentPolicies(segment) {
if (segment.security && segment.security.policies) {
for (const policyName of segment.security.policies) {
try {
const policy = this.runtimePolicies.get(policyName);
if (policy) {
await this.applyPolicyToSegment(segment, policy);
}
} catch (error) {
this.logger.error(`Failed to apply policy ${policyName} to segment ${segment.name}:`, error);
}
}
}
}
async applyPolicyToSegment(segment, policy) {
const segmentId = segment.id;
switch (policy.type) {
case 'container-runtime-protection':
await this.applyContainerRuntimeProtection(segment, policy);
break;
case 'network-access-control':
await this.applyNetworkAccessControl(segment, policy);
break;
case 'application-security':
await this.applyApplicationSecurity(segment, policy);
break;
default:
this.logger.warn(`Unknown policy type: ${policy.type}`);
}
}
async applyContainerRuntimeProtection(segment, policy) {
if (!this.orchestrator) return;
try {
// Configure container runtime protection
if (policy.rules) {
for (const rule of policy.rules) {
if (rule.name === 'block-privileged-containers') {
await this.applyContainerPolicy(segment, {
security: {
privileged: false
}
});
}
}
}
} catch (error) {
this.logger.error(`Failed to apply container runtime protection: ${error.message}`);
}
}
async applyNetworkAccessControl(segment, policy) {
if (!this.orchestrator) return;
try {
// Apply network access control at orchestration level
if (policy.rules) {
for (const rule of policy.rules) {
if (rule.name === 'block-external-requests-by-default') {
await this.applyNetworkPolicy(segment, {
network: {
defaultExternalAccess: false
}
});
} else if (rule.name === 'allow-dns-resolution') {
await this.applyNetworkPolicy(segment, {
network: {
dnsAccess: true
}
});
}
}
}
} catch (error) {
this.logger.error(`Failed to apply network access control: ${error.message}`);
}
}
async applyApplicationSecurity(segment, policy) {
if (!this.orchestrator) return;
try {
// Apply application security
if (policy.rules) {
for (const rule of policy.rules) {
if (rule.name === 'disable-insecure-protocols') {
await this.applyApplicationPolicy(segment, {
security: {
insecureProtocols: []
}
});
}
}
}
} catch (error) {
this.logger.error(`Failed to apply application security: ${error.message}`);
}
}
async applyContainerPolicy(segment, updates) {
if (!this.orchestrator) return;
try {
const containers = await this.getContainersForSegment(segment.id);
for (const container of containers) {
if (updates.security) {
await this.updateContainerSecurity(container, updates.security);
}
}
} catch (error) {
this.logger.error(`Failed to apply container policy: ${error.message}`);
}
}
async applyNetworkPolicy(segment, updates) {
if (!this.orchestrator) return;
try {
// Apply network policies at orchestration level
// This would integrate with network policies at the orchestration platform level
this.logger.info(`Applying network policy updates to segment ${segment.id}`);
} catch (error) {
this.logger.error(`Failed to apply network policy: ${error.message}`);
}
}
async applyApplicationPolicy(segment, updates) {
if (!this.orchestrator) return;
try {
// Apply application policies at orchestration level
this.logger.info(`Applying application policy updates to segment ${segment.id}`);
} catch (error) {
this.logger.error(`Failed to apply application policy: ${error.message}`);
}
}
async getContainersForSegment(segmentId) {
if (!this.orchestrator) return [];
try {
const containers = await this.orchestrator.listContainers({
label: `workload=${segmentId}`
});
return containers.containers || [];
} catch (error) {
this.logger.error(`Failed to get containers for segment ${segmentId}:`, error);
return [];
}
}
async updateContainerSecurity(container, securityUpdates) {
try {
// Update container security settings
if (securityUpdates.privileged !== undefined) {
// Update privileged mode
}
if (securityUpdates.readOnlyRootfs !== undefined) {
// Update read-only root filesystem
}
this.logger.info(`Updated container security for container ${container.Id}`);
} catch (error) {
this.logger.error(`Failed to update container security: ${error.message}`);
}
}
async analyzeWorkload(workloadId) {
// Analyze workload characteristics
const profile = this.workloadProfiles.get(workloadId);
if (!profile) {
return null;
}
const characteristics = {
resourceUtilization: await this.getResourceUtilization(workloadId),
securityScore: await this.calculateSecurityScore(workloadId),
riskLevel: this.assessRiskLevel(workloadId),
complianceScore: this.assessCompliance(workloadId)
};
return {
profile,
characteristics,
recommendations: this.generateRecommendations(characteristics)
};
}
async getResourceUtilization(workloadId) {
try {
const containers = await this.getContainersForSegment(workloadId);
if (containers.length === 0) {
return { cpu: 0, memory: 0, bandwidth: 0 };
}
let totalCPU = 0;
let totalMemory = 0;
let totalBandwidth = 0;
for (const container of containers) {
const stats = await this.getContainerStats(container.Id);
if (stats) {
totalCPU += stats.cpu || 0;
totalMemory += stats.memory || 0;
totalBandwidth += stats.network?.bytesReceived || 0;
}
}
return {
cpu: totalCPU,
memory: totalMemory,
bandwidth: totalBandwidth,
containers: containers.length
};
} catch (error) {
this.logger.error(`Failed to get resource utilization: ${error.message}`);
return { cpu: 0, memory: metrics.memoryUsage.heapUsed };
}
}
calculateSecurityScore(workloadId) {
let score = 50; // Base score
try {
const profile = this.workloadProfiles.get(workloadId);
// Check compliance requirements
if (profile.complianceRequirements) {
if (profile.complianceRequirements.dataClassification === 'sensitive') {
score -= 30;
}
}
// Check security requirements
if (profile.securityRequirements) {
if (!profile.securityRequirements.databaseAccess) {
score -= 20;
}
}
} catch (error) {
this.logger.error(`Failed to calculate security score: ${error.message}`);
}
return Math.max(0, score);
}
assessRiskLevel(workloadId) {
let riskScore = 25; // Default medium risk
try {
const profile = this.workloadProfiles.get(workloadId);
// Higher risk for external network access
if (profile.securityRequirements.networkAccess.length > 2) {
riskScore += 20;
}
// Higher risk for filesystem access
if (profile.securityRequirements.filesystemAccess) {
riskScore += 15;
}
// Higher risk for privileged containers
if (profile.resourceRequirements.cpu.includes('vCPU')) {
riskScore += 10;
}
} catch (error) {
this.logger.error(`Failed to assess risk level: ${error.message}`);
}
if (riskScore > 75) return 'critical';
if (riskScore > 50) return 'high';
if (riskScore > 25) return 'medium';
return 'low';
}
assessCompliance(workloadId) {
let score = 0;
try {
const profile = this.workloadTypes.get(workloadId);
if (profile.complianceRequirements) {
// Score based on compliance level
if (profile.complianceRequirements.dataClassification === 'public') score += 25;
if (profile.complianceRequirements.dataClassification === 'internal') score += 50;
if (profile.complianceRequirements.dataClassification === 'confidential') score += 75;
if (profile.complianceRequirements.dataClassification === 'restricted') score += 90;
if (profile.complianceRequirements.dataClassification === 'top-secret') score += 100;
}
} catch (error) {
this.logger.error(`Failed to assess compliance: ${error.message}`);
}
return Math.min(100, score);
}
generateRecommendations(characteristics) {
const recommendations = [];
// Resource optimization recommendations
if (characteristics.resourceUtilization.cpu > 80) {
recommendations.push({
type: 'optimization',
priority: 'high',
title: 'High CPU utilization detected',
description: 'Consider scaling or optimizing CPU usage',
suggestion: 'Implement horizontal scaling or CPU optimization'
});
}
// Security recommendations
if (characteristics.securityScore < 50) {
recommendations.push({
type: 'security',
priority: 'high',
title: 'Security score below threshold',
description: 'Security score below 50% requires attention',
suggestion: 'Review security policies and configurations'
});
}
// Risk recommendations
if (characteristics.riskLevel === 'critical') {
recommendations.push({
type: 'security',
priority: 'critical',
title: 'Critical risk level detected',
description: 'Workload presents critical security risks',
suggestion: 'Review and implement additional security controls'
});
}
// Compliance recommendations
if (characteristics.complianceScore < 60) {
recommendations.push({
type: 'compliance',
priority: 'medium',
title: 'Compliance score needs improvement',
description: 'Compliance score below 60%',
suggestion: 'Review and update compliance controls'
});
}
return recommendations;
}
async enforcePolicy(segmentId, target, action) {
try {
const segment = this.segments.get(segmentId);
if (!segment) {
throw new Error(`Segment not found: ${segmentId}`);
}
const result = await this.enforcementEngine.enforcePolicy(segment, { target, action });
this.emit('policyEnforced', {
segmentId,
target,
action: result.action,
reason: result.message || 'Policy enforced'
});
return result;
} catch (error) {
this.logger.error(`Policy enforcement failed: ${error.message}`);
return { action: 'error', error: error.message };
}
}
updateSegment(segmentId, updates) {
const segment = this.segments.get(segmentId);
if (!segment) {
throw new Error(`Segment not found: ${segmentId}`);
}
Object.assign(segment, updates);
segment.updatedAt = Date.now();
this.segments.set(segmentId, segment);
this.emit('segmentUpdated', segment);
}
deleteSegment(segmentId) {
this.segments.delete(segmentId);
this.microSegments.delete(segmentId);
this.emit('segmentDeleted', { segmentId });
}
// Analytics and monitoring
getSegmentAnalytics() {
const segmentAnalytics = {
total: this.segments.size,
microSegments: this.microSegments.size,
activeSegments: Array.from(this.segments.values()).filter(s => s.status === 'active').length,
segmentTypes: this.getSegmentTypeDistribution(),
securityPosture: this.getSecurityPostureDistribution(),
resourceUtilization: await this.getOverallResourceUtilization(),
violationTrends: this.getViolationTrends()
};
return segmentAnalytics;
}
getConnectionAnalytics() {
const connectionAnalytics = {
total: this.connectionAnalytics.size,
activeConnections: this.connectionAnalytics.size,
connectionTypes: this.getConnectionTypeDistribution(),
averageSessionDuration: this.getAverageSessionDuration(),
geographicDistribution: this.getGeographicDistribution()
};
return connectionAnalytics;
}
getViolationAnalytics() {
return {
total: this.violations.length,
byType: this.getViolationsByType(),
byPolicy: this.getViolationsByPolicy(),
recent: this.getRecentViolations(),
trends: this.getViolationTrends(),
bySeverity: this.getViolationsBySeverity()
};
}
getSegmentTypeDistribution() {
const distribution = {};
for (const segment of this.segments.values()) {
distribution[segment.type] = (distribution[segment.type] || 0) + 1;
}
return distribution;
}
getSecurityPostureDistribution() {
const postures = {
strict: 0,
permissive: 0,
restrictive: 0
};
for (const segment of this.segments.values()) {
if (segment.security) {
const mode = segment.security.enforcementMode || 'default';
postures[mode] = (postures[mode] || 0) + 1;
}
}
return postures;
}
async getOverallResourceUtilization() {
try {
const segments = Array.from(this.segments.values());
let totalCPU = 0;
let totalMemory = 0;
let totalBandwidth = 0;
for (const segment of segments) {
const utilization = await this.getResourceUtilization(segment.id);
totalCPU += utilization.cpu;
totalMemory += utilization.memory;
totalBandwidth += utilization.bandwidth;
}
return {
cpu: totalCPU,
memory: totalMemory,
bandwidth: totalBandwidth,
efficiency: this.calculateEfficiency(totalCPU, totalMemory, totalBandwidth)
};
} catch (error) {
this.logger.error(`Failed to get resource utilization: ${error.message}`);
return { cpu: 0, memory: metrics.memoryUsage.heapUsed, bandwidth: 0 };
}
}
calculateEfficiency(cpu, memory, bandwidth) {
// Calculate efficiency score based on resource utilization
const cpuEfficiency = cpu > 0 ? (100 - (cpu / (cpu + memory + bandwidth / 100)) : 50) : 50;
return Math.min(100, cpuEfficiency);
}
getConnectionTypeDistribution() {
const distribution = {};
for (const connection of this.connectionAnalytics.values()) {
const type = this.determineConnectionType(connection);
distribution[type] = (distribution[type] || 0) + 1;
}
return distribution;
}
getAverageSessionDuration() {
const connections = Array.from(this.connectionAnalytics.values());
const sessionDurations = connections.map(conn =>
(Date.now() - (conn.firstSeen) / 1000) // milliseconds
);
return sessionDurations.length > 0
? sessionDurations.reduce((sum, duration) => sum + duration, 0) / sessionDurations.length
: 0;
}
getGeographicDistribution() {
const distribution = {};
for (const connection of this.connectionAnalytics.values()) {
const geoInfo = this.getGeoLocation(connection.ip);
const location = ${geoInfo.country || 'unknown}`;
distribution[location] = (distribution[location] || 0) + 1);
}
return distribution;
}
getViolationsByType() {
const types = {};
for (const violation of this.violations) {
const type = violation.policy?.name || 'unknown';
types[type] = (types[type] || 0) + 1);
}
return types;
}
getViolationsByPolicy() {
const policies = {};
for (const violation of this.violations) {
const policyId = violation.policyId || 'unknown';
policies[policyId] = (policies[policyId] || 0) + 1);
}
return policies;
}
getRecentViolations() {
const oneHourAgo = Date.now() - (60 * 60 * 1000); // 1 hour ago
return this.violations.filter(v => v.timestamp > oneHourAgo);
}
getViolationsBySeverity() {
const severities = { critical: 0, high: 0, medium: 0, low: 0 };
for (const violation of this.violations) {
const severity = violation.severity || 'low';
severities[severity] = (severities[severity] || 0) + 1;
}
return severities;
}
getGeoLocation(ip) {
// Simplified geo-location lookup
return {
country: 'unknown',
city: 'unknown',
region: 'unknown',
org: 'unknown'
};
}
generateId() {
require('crypto').randomBytes(16).toString('hex');
}
// Analytics and monitoring
startPeriodicAnalytics() {
setInterval(() => {
this.updateAnalytics();
}, 60000); // Every minute
setInterval(() => {
this.cleanupOldData();
}, 300000); // Every 5 minutes
}
updateAnalytics() {
const segmentAnalytics = this.getSegmentAnalytics();
const connectionAnalytics = this.getConnectionAnalytics();
const violationAnalytics = this.getViolationAnalytics();
this.logger.info('Analytics update', {
segments: segmentAnalytics,
connections: connectionAnalytics,
violations: violationAnalytics
});
// Update dashboards
this.updateDashboards(segmentAnalytics, connectionAnalytics, violationAnalytics);
}
updateDashboards(segmentAnalytics, connectionAnalytics, violationAnalytics) {
// Update dashboard data sources
if (this.config.enableAnalytics) {
this.updateDashboardData('segments', segmentAnalytics);
this.updateDashboardData('connections', connectionAnalytics);
this.updateDashboardData('violations', violationAnalytics);
}
}
updateDashboardData(type, data) {
// Update external dashboard systems
console.log(
--- Dashboard Update [${type}] ---`);
console.log(JSON.stringify(data, null, 2));
}
cleanupOldData() {
// Clean up old analytics data
const oneHourAgo = Date.now() - (60 * 60 * 1000);
// Remove old violations
this.violations = this.violations.filter(v => v.timestamp > oneHourAgo);
// Remove inactive connections
for (const [id, connection] of this.connectionAnalytics.entries()) {
if (connection.lastSeen < oneHourAgo) {
this.connectionAnalytics.delete(id);
}
}
// Remove old session data
this.sessionStore.cleanup();
console.log('Cleanup completed');
}
}
// Workload Profile and Application Integration
class WorkloadManager {
constructor(segmentationEngine) {
this.segmentationEngine = segmentationEngine;
}
async registerWorkload(profile) {
const workload = {
...profile,
id: this.generateId(),
registeredAt: Date.now(),
status: 'registered'
};
// Save to workload profiles
this.segmentationEngine.workloadProfiles.set(profile.name, workload);
// Create corresponding micro-segment
const segment = await this.segmentationEngine.createMicroSegment({
name: profile.name,
workloadId: profile.name,
type: profile.type,
target: 'container',
parent: 'default'
});
this.segmentationEngine.emit('workload-registered', workload);
return segment;
}
async detectWorkload(containerId) {
// Detect workload type from container metadata
try {
if (this.segmentationEngine.orchestrator) {
const container = await this.segmentationEngine.orchestrator.getContainer(containerId);
if (container) {
const labels = container.Labels || {};
// Match workload profile by labels
for (const [workloadId, profile] of this.segmentationEngine.workloadProfiles.entries()) {
if (workloadId === labels.workload) {
return {
workload: profile,
confidence: this.matchConfidence(container, profile)
};
}
}
// If no direct match, try pattern matching
const match = this.matchWorkloadProfile(container, this.segmentationEngine.workloadProfiles);
if (match) {
return {
workload: match.workload,
confidence: match.confidence,
detected: true
};
}
}
}
} catch (error) {
console.error(`Workload detection failed: ${error.message}`);
}
return null;
}
matchWorkloadProfile(container, profiles) {
let bestMatch = null;
let highestConfidence = 0;
for (const [workloadId, profile] of profiles.entries()) {
const confidence = this.matchConfidence(container, profile);
if (confidence > highestConfidence) {
bestMatch = workload;
highestConfidence = confidence;
}
}
return bestMatch ? bestMatch.workload : null;
}
matchConfidence(container, profile) {
let confidence = 0;
let factors = 0;
// Match by name
if (container.Labels && container.Labels.workload === profile.name) {
confidence += 50;
factors++;
}
// Match by resource requirements
if (profile.resourceRequirements) {
factors += 3;
if (container.Resources) {
// Compare CPU requirements
if (profile.resourceRequirements.cpu && container.Resources.limits?.cpu) {
const requiredCPU = this.parseCPURequirement(profile.resourceRequirements.cpu);
const availableCPU = this.parseCPURequirement(container.Resources.limits?.cpu);
if (availableCPU >= requiredCPU) {
confidence += 20;
factors++;
}
}
// Compare memory requirements
if (profile.resourceRequirements.memory && container.Resources.limits?.memory) {
const requiredMemory = this.parseMemoryRequirement(profile.resourceRequirements.memory);
availableMemory = this.parseMemoryRequirement(container.Resources.limits?.memory);
if (availableMemory >= requiredMemory) {
confidence += 20;
factors++;
}
}
}
}
return factors > 0 ? confidence / factors : 0;
}
parseCPURequirement(cpuSpec) {
if (typeof cpuSpec === 'string') {
const match = cpuSpec.match(/(\d+)([mgtG]?)/);
if (match) {
const value = parseFloat(match[1]);
return value * (match[2] === 'M' ? 1000 : 1);
}
}
return 0;
}
parseMemoryRequirement(memorySpec) {
if (typeof memorySpec === 'string') {
const match = memorySpec.match(/(\d+)([GM]i[Bb]?)$/);
if (match) {
const value = parseFloat(match[1]);
return value * (match[2] === 'G' || match[2] === 'i' ? 1024 : 1) * 1024 : 1));
}
}
return 0;
}
async getWorkloadSummary() {
const profiles = Array.from(this.segmentationEngine.workloadProfiles.values());
const summary = {
totalWorkloads: profiles.length,
byType: this.getWorkloadTypeDistribution(profiles),
averageSecurityScore: this.calculateAverageSecurityScore(profiles),
averageRiskLevel: this.calculateAverageRiskLevel(profiles),
complianceStatus: this.getOverallComplianceStatus(profiles)
};
return summary;
}
getWorkloadTypeDistribution(profiles) {
const distribution = {};
for (const profile of profiles) {
distribution[profile.type] = (distribution[profile.type] || 0) + 1);
}
return distribution;
}
calculateAverageSecurityScore(profiles) {
if (profiles.length === 0) return 50;
const scores = profiles.map(profile =>
this.segmentationEngine.calculateSecurityScore(profile.id)
);
return scores.reduce((sum, score) => sum + score, 0) / scores.length;
}
calculateAverageRiskLevel(profiles) {
if (profiles.length === 0) return 'medium';
const riskLevels = profiles.map(profile =>
this.segmentationEngine.assessRiskLevel(profile.id)
);
const riskLevelCounts = {
critical: 0,
high: 0,
medium: 0,
low: 0
};
for (const level of riskLevels) {
riskLevelCounts[level]++;
}
// Return the highest risk level with the least matches
const riskLevelsOrdered = ['critical', 'high', 'medium', 'low'];
for (const level of riskLevelsOrdered) {
if (riskLevelCounts[level] > 0) {
return level;
}
}
return 'low';
}
getOverallComplianceStatus(profiles) {
if (profiles.length === 0) return 100;
const scores = profiles.map(profile =>
this.segmentationEngine.assessCompliance(profile.id)
);
return scores.reduce((sum, score) => sum + score, 0) / scores.length;
}
}
// Container and application integration
class ContainerManager {
constructor(segmentationEngine) {
this.segmentationEngine = segmentationEngine;
}
async updateContainer(containerId, updates) {
if (!this.segmentationEngine.orchestrator) return;
try {
const container = await this.segmentationEngine.orchestrator.getContainer(containerId);
if (container && updates.security) {
await this.segmentationEngine.applyContainerPolicy(container, updates.security);
}
// Update segment with new container information
await this.updateContainerInSegment(containerId, updates);
} catch (error) {
console.error(`Failed to update container ${containerId}:`, error);
}
}
async updateContainerInSegment(containerId, updates) {
const container = await this.segmentationEngine.orchestrator.getContainer(containerId);
if (!container) return;
// Find associated segment
const segment = await this.findSegmentByContainer(containerId);
if (segment) {
// Update segment with new container metadata
segment.containerCount = (segment.containerCount || 0) + 1;
segment.lastUpdated = Date.now();
// Re-apply policies if needed
await this.segmentationEngine.applySegmentPolicies(segment);
this.segmentationEngine.updateSegment(segment.id, segment);
}
}
async findSegmentByContainer(containerId) {
for (const [segmentId, segment] of this.segmentationEngine.segments.entries()) {
const containers = await this.segmentationEngine.getContainersForSegment(segmentId);
if (containers.find(c => c.Id === containerId)) {
return segment;
}
}
return null;
}
}
// Application integration example
class Application {
constructor(segmentationEngine, app) {
this.segmentationEngine = segmentationEngine;
this.app = app;
// Setup Zero Trust middleware
this.setupMiddleware();
this.setupRoutes();
}
setupMiddleware() {
// Request analysis
this.app.use(async (req, res, next) => {
this.segmentationEngine.analyzeRequest(req);
next();
});
// Policy enforcement
this.app.use(async (req, res, next) => {
const decision = await this.segmentationEngine.evaluateRequest(req);
if (decision.action === 'block') {
return res.status(403).json({
error: 'Access denied by policy'
});
}
next();
});
// Session validation
this.app.use(async (req, res, next) => {
if (req.headers.authorization) {
try {
const decoded = await this.segmentationEngine.validateToken(req.headers.authorization);
if (decoded.exp < Date.now() / 1000) {
return res.status(401).json({ error: 'Token expired' });
}
req.user = decoded;
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
}
// Validate session
if (decoded && decoded.sessionId) {
const session = this.segmentationEngine.sessionStore.get(decoded.sessionId);
if (!session || session.expiresAt < Date.now()) {
return res.status(401).json({ error: 'Session expired' });
}
req.session = session;
}
next();
});
}
setupRoutes() {
// Admin endpoints
this.app.get('/api/segments', authenticate, authorize(['admin']), this.listSegments.bind(this));
this.app.post('/api/segments', authenticate, authorize(['admin']), this.createSegment.bind(this));
this.app.put('/api/segments/:id', authenticate, authorize(['admin']), this.updateSegment.bind(this));
this.app.delete('/api/segments/:id', authenticate, authorize(['admin']), this.deleteSegment.bind(this));
// Developer endpoints
this.app.get('/api/workloads', authenticate, this.listWorkloads.bind(this));
this.app.post('/api/workloads/:id/security-scan', authenticate, this.performSecurityScan.bind(this)));
// Analytics endpoints
this.app.get('/api/analytics', authenticate, authorize(['admin']), this.getAnalytics.bind(this));
// Dynamic policy enforcement
this.app.post('/api/enforce/:segmentId', authenticate, this.enforcePolicyOnConnection.bind(this)));
// Workload detection
this.app.post('/api/detect-workload', authenticate, this.detectWorkload.bind(this)));
// Real-time updates
this.app.get('/api/ws', authenticate, this.setupWebSocket.bind(this));
}
listSegments(req, res) {
const segments = await this.segmentationEngine.listSegments();
res.json(segments);
}
createSegment(req, res) {
const segmentData = {
...req.body,
id: this.segmentationEngine.generateId(),
createdAt: Date.now()
};
try {
const segment = await this.segmentationEngine.createSegment(segmentData);
res.status(201).json(segment);
this.logger.info(`Created segment: ${segment.name}`);
} catch (error) {
this.logger.error('Failed to create segment:', error);
res.status(400).json({ error: error.message });
}
}
updateSegment(req, res) {
const { id } = req.params;
const updates = req.body;
try {
const segment = await this.segmentationEngine.updateSegment(id, updates);
res.json(segment);
this.logger.info(`Updated segment: ${segment.name}`);
} catch (error) {
this.logger.error('Failed to update segment:', error);
res.status(400).json({ error: error.message });
}
}
deleteSegment(req, res) {
const { id } = req.params;
try {
await this.segmentationEngine.deleteSegment(id);
res.status(204).send();
this.logger.info(`Deleted segment: ${id}`);
} catch (error) {
this.logger.error('Failed to delete segment:', error);
res.status(400).json({ error: error.message });
}
}
listWorkloads(req, res) {
const profiles = Array.from(this.segmentationEngine.workloadProfiles.values());
res.json(profiles);
}
performSecurityScan(req, res) {
const { id } = req.params;
try {
const analysis = await this.segmentationEngine.analyzeWorkload(id);
res.json(analysis);
} catch (error) {
this.logger.error('Security scan failed:', error);
res.status(500).json({ error: error.message });
}
}
enforcePolicyOnConnection(req, res) {
const { segmentId, target, action } = req.params;
try {
const result = await this.segmentationEngine.enforcePolicy(segmentId, target, action);
res.json(result);
} catch (error) {
this.logger.error('Policy enforcement failed:', error);
res.status(500).json({ error: error.message });
}
}
detectWorkload(req, res) {
const { connectionId } = req.connectionId || this.getConnectionId(req);
try {
const workload = await this.segmentationEngine.analyzeWorkload(connectionId);
res.json({
workload,
connectionId,
detected: workload !== null
});
} catch (error) {
this.logger.error('Workload detection failed:', error);
res.status(500).json({ error: error.message });
}
}
setupWebSocket(ws, req, res) {
ws.on('connection', (ws, req) => {
const connectionId = this.getConnectionId(req);
// Store connection reference for context
this.connections.set(ws, {
connectionId,
ip: req.ip,
userAgent: req.headers['user-agent'],
headers: req.headers,
socket: ws
});
});
ws.on('message', (ws, data) => {
this.handleWebSocketMessage(ws, data);
});
ws.on('close', () => {
const connection = this.connections.get(ws);
if (connection) {
this.connections.delete(ws);
this.logger.info(`Connection closed: ${connection.connectionId}`);
}
});
res.status(200).json({
message: 'WebSocket connected',
connectionId
});
}
handleWebSocketMessage(ws, data) {
try {
const message = JSON.parse(data);
switch (message.type) {
case 'connection-migration':
this.handleConnectionMigration(ws, message.data);
break;
case 'risk-update':
this.handleRiskUpdate(ws, message.data);
break;
case 'segment-update':
this.handleSegmentUpdate(ws, message.data);
break;
}
} catch (error) {
this.logger.error('WebSocket message error:', error);
}
}
handleConnectionMigration(ws, data) {
const connection = this.connections.get(ws);
if (connection) {
// Update connection with new security context
connection.security = {
requiresReauth: data.requiresReauth,
trustScore: data.trustScore || 0
};
this.logger.info(`Connection migration required: ${connection.requiresReauth ? 'Yes' : 'No'}`);
}
}
handleRiskUpdate(ws, data) {
// Update connection risk score
const connection = this.connections.get(ws);
if (connection) {
connection.security.riskScore = data.riskScore || 0;
if (connection.security.riskScore > 70) {
// Trigger additional verification
this.logger.warn(`High risk score for connection ${connection.connectionId}: ${connection.security.riskScore}`);
}
}
}
handleSegmentUpdate(ws, data) {
// Update segment information
const connection = this.connections.get(ws);
if (connection) {
connection.segmentId = data.segmentId;
connection.security.requiresReauth = data.requiresReauth;
}
}
getConnectionId(req) {
const connectionId = req.ztConnectionId ||
req.ip ||
req.connectionId ||
this.generateId();
return connectionId;
}
}
// Start the micro-segmentation service
const port = process.env.PORT || 3000;
const app = express();
const segmentation = new ZeroTrustNetworkSegmentation({
orchestration: 'kubernetes',
enableAPIAccess: true,
realTimeUpdates: true,
analytics: {
enabled: true,
retention: '24h'
},
logging: {
level: 'info'
}
});
// Start the service
app.listen(port, () => {
console.log(`Zero Trust Micro-Segmentation API listening on port ${port}`);
});
// Add routes to application
const app2 = express();
const app2Router = express.Router();
app2.use('/api/v2', app2Router);
app2Router.use(authenticate);
app2Router.use(authorize(['admin']));
app2Router.get('/workloads', authenticate, async (req, res) => {
const summary = await segmentation.getWorkloadSummary();
res.json(summary);
});
app2Router.post('/workloads/:id/security-scan', authenticate, async (req, res) => {
const analysis = await segmentation.analyzeWorkload(req.params.id);
res.json(analysis);
});
// Graceful shutdown
process.on('SIGINT', () => {
console.log('Shutting down Zero Trust Micro-Segmentation Service...');
segmentation.stop();
app.close();
process.exit(0);
});