Zero Trust Architecture (ZTA) is a security model that requires strict identity verification for every person and device trying to access resources on a private network. This guide provides a comprehensive Java implementation of Zero Trust principles.
Core Zero Trust Principles
- Never Trust, Always Verify
- Assume Breach
- Verify Explicitly
- Least Privilege Access
- Micro-segmentation
Dependencies and Setup
Maven Configuration
<!-- pom.xml --> <project> <modelVersion>4.0.0</modelVersion> <groupId>com.zerotrust</groupId> <artifactId>zero-trust-architecture</artifactId> <version>1.0.0</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <spring-boot.version>3.1.0</spring-boot.version> <keycloak.version>21.1.1</keycloak.version> </properties> <dependencies> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>${spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>${spring-boot.version}</version> </dependency> <!-- OAuth2 and JWT --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> <version>${spring-boot.version}</version> </dependency> <!-- Database --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> </dependency> <!-- Redis for session management --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${spring-boot.version}</version> </dependency> <!-- Monitoring and Observability --> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> <version>1.11.0</version> </dependency> <!-- HTTP Client --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency> <!-- Testing --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <version>6.1.0</version> <scope>test</scope> </dependency> </dependencies> </project> Core Zero Trust Components
Example 1: Identity and Access Management
package com.zerotrust.identity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.stereotype.Component; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @Component public class ZeroTrustIdentityService { private final DeviceVerificationService deviceVerificationService; private final RiskAssessmentService riskAssessmentService; private final AccessPolicyService accessPolicyService; public ZeroTrustIdentityService(DeviceVerificationService deviceVerificationService, RiskAssessmentService riskAssessmentService, AccessPolicyService accessPolicyService) { this.deviceVerificationService = deviceVerificationService; this.riskAssessmentService = riskAssessmentService; this.accessPolicyService = accessPolicyService; } /** * Comprehensive identity verification */ public IdentityContext verifyIdentity(JwtAuthenticationToken authentication, DeviceContext deviceContext, NetworkContext networkContext) { Jwt jwt = authentication.getToken(); // Multi-factor verification VerificationResult verification = performMultiFactorVerification( jwt, deviceContext, networkContext ); if (!verification.isVerified()) { throw new ZeroTrustAuthenticationException("Identity verification failed: " + verification.getFailureReason()); } // Risk assessment RiskAssessment risk = riskAssessmentService.assessRisk( jwt, deviceContext, networkContext ); // Create identity context IdentityContext identityContext = new IdentityContext(); identityContext.setUserId(jwt.getSubject()); identityContext.setUsername(jwt.getClaimAsString("preferred_username")); identityContext.setEmail(jwt.getClaimAsString("email")); identityContext.setDeviceId(deviceContext.getDeviceId()); identityContext.setRiskScore(risk.getRiskScore()); identityContext.setVerificationLevel(verification.getVerificationLevel()); identityContext.setSessionId(UUID.randomUUID().toString()); identityContext.setIssuedAt(Instant.now()); // Set context-aware authorities identityContext.setAuthorities(calculateContextAwareAuthorities( authentication, risk, deviceContext )); return identityContext; } private VerificationResult performMultiFactorVerification(Jwt jwt, DeviceContext deviceContext, NetworkContext networkContext) { VerificationResult result = new VerificationResult(); // 1. Token verification (already done by Spring Security) if (!isTokenValid(jwt)) { result.setVerified(false); result.setFailureReason("Invalid token"); return result; } // 2. Device verification DeviceVerification deviceVerification = deviceVerificationService.verifyDevice(deviceContext); if (!deviceVerification.isTrusted()) { result.setVerified(false); result.setFailureReason("Untrusted device: " + deviceVerification.getFailureReason()); return result; } // 3. Behavioral analysis if (!analyzeUserBehavior(jwt, deviceContext)) { result.setVerified(false); result.setFailureReason("Suspicious behavior detected"); return result; } // 4. Network context verification if (!verifyNetworkContext(networkContext)) { result.setVerified(false); result.setFailureReason("Suspicious network context"); return result; } result.setVerified(true); result.setVerificationLevel(calculateVerificationLevel(deviceVerification, networkContext)); return result; } private Collection<? extends GrantedAuthority> calculateContextAwareAuthorities( JwtAuthenticationToken authentication, RiskAssessment risk, DeviceContext deviceContext) { Set<GrantedAuthority> authorities = new HashSet<>(); // Base authorities from token authorities.addAll(authentication.getAuthorities()); // Risk-based restrictions if (risk.getRiskScore() > 70) { // High risk - restrict access authorities.removeIf(auth -> !auth.getAuthority().equals("ROLE_BASIC_ACCESS")); authorities.add(new SimpleGrantedAuthority("ROLE_RESTRICTED")); } // Device-based restrictions if (!deviceContext.isCorporateDevice()) { authorities.add(new SimpleGrantedAuthority("ROLE_EXTERNAL_DEVICE")); } // Time-based restrictions if (isOutsideWorkingHours()) { authorities.add(new SimpleGrantedAuthority("ROLE_AFTER_HOURS")); } return authorities; } private boolean isTokenValid(Jwt jwt) { return jwt.getExpiresAt() != null && jwt.getExpiresAt().isAfter(Instant.now()) && jwt.getIssuedAt() != null && jwt.getIssuedAt().isBefore(Instant.now()); } private boolean analyzeUserBehavior(Jwt jwt, DeviceContext deviceContext) { // Implement behavioral analysis logic // Check for unusual login patterns, geolocation, etc. return true; // Simplified for example } private boolean verifyNetworkContext(NetworkContext networkContext) { // Verify network is trusted return networkContext.isSecureNetwork() && !networkContext.isVpnInUse() && networkContext.getGeoLocation().isAllowed(); } private boolean isOutsideWorkingHours() { // Check if current time is outside normal working hours Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); return hour < 8 || hour > 18; } private String calculateVerificationLevel(DeviceVerification deviceVerification, NetworkContext networkContext) { if (deviceVerification.isBiometricEnabled() && networkContext.isCorporateNetwork()) { return "HIGH"; } else if (deviceVerification.isCompliant()) { return "MEDIUM"; } else { return "LOW"; } } } // Context classes class IdentityContext { private String userId; private String username; private String email; private String deviceId; private double riskScore; private String verificationLevel; private String sessionId; private Instant issuedAt; private Collection<? extends GrantedAuthority> authorities; // Getters and setters public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getDeviceId() { return deviceId; } public void setDeviceId(String deviceId) { this.deviceId = deviceId; } public double getRiskScore() { return riskScore; } public void setRiskScore(double riskScore) { this.riskScore = riskScore; } public String getVerificationLevel() { return verificationLevel; } public void setVerificationLevel(String verificationLevel) { this.verificationLevel = verificationLevel; } public String getSessionId() { return sessionId; } public void setSessionId(String sessionId) { this.sessionId = sessionId; } public Instant getIssuedAt() { return issuedAt; } public void setIssuedAt(Instant issuedAt) { this.issuedAt = issuedAt; } public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } public void setAuthorities(Collection<? extends GrantedAuthority> authorities) { this.authorities = authorities; } } class DeviceContext { private String deviceId; private String deviceType; private String osVersion; private boolean isCompliant; private boolean isCorporateDevice; private boolean isBiometricEnabled; private String deviceCertificate; private Instant lastSecurityUpdate; // Getters and setters public String getDeviceId() { return deviceId; } public void setDeviceId(String deviceId) { this.deviceId = deviceId; } public String getDeviceType() { return deviceType; } public void setDeviceType(String deviceType) { this.deviceType = deviceType; } public String getOsVersion() { return osVersion; } public void setOsVersion(String osVersion) { this.osVersion = osVersion; } public boolean isCompliant() { return isCompliant; } public void setCompliant(boolean compliant) { isCompliant = compliant; } public boolean isCorporateDevice() { return isCorporateDevice; } public void setCorporateDevice(boolean corporateDevice) { isCorporateDevice = corporateDevice; } public boolean isBiometricEnabled() { return isBiometricEnabled; } public void setBiometricEnabled(boolean biometricEnabled) { isBiometricEnabled = biometricEnabled; } public String getDeviceCertificate() { return deviceCertificate; } public void setDeviceCertificate(String deviceCertificate) { this.deviceCertificate = deviceCertificate; } public Instant getLastSecurityUpdate() { return lastSecurityUpdate; } public void setLastSecurityUpdate(Instant lastSecurityUpdate) { this.lastSecurityUpdate = lastSecurityUpdate; } } class NetworkContext { private String ipAddress; private String geoLocation; private boolean isSecureNetwork; private boolean isVpnInUse; private boolean isCorporateNetwork; private String userAgent; // Getters and setters public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } public String getGeoLocation() { return geoLocation; } public void setGeoLocation(String geoLocation) { this.geoLocation = geoLocation; } public boolean isSecureNetwork() { return isSecureNetwork; } public void setSecureNetwork(boolean secureNetwork) { isSecureNetwork = secureNetwork; } public boolean isVpnInUse() { return isVpnInUse; } public void setVpnInUse(boolean vpnInUse) { isVpnInUse = vpnInUse; } public boolean isCorporateNetwork() { return isCorporateNetwork; } public void setCorporateNetwork(boolean corporateNetwork) { isCorporateNetwork = corporateNetwork; } public String getUserAgent() { return userAgent; } public void setUserAgent(String userAgent) { this.userAgent = userAgent; } } class VerificationResult { private boolean verified; private String failureReason; private String verificationLevel; // Getters and setters public boolean isVerified() { return verified; } public void setVerified(boolean verified) { this.verified = verified; } public String getFailureReason() { return failureReason; } public void setFailureReason(String failureReason) { this.failureReason = failureReason; } public String getVerificationLevel() { return verificationLevel; } public void setVerificationLevel(String verificationLevel) { this.verificationLevel = verificationLevel; } } class RiskAssessment { private double riskScore; private List<String> riskFactors; private String riskLevel; // Getters and setters public double getRiskScore() { return riskScore; } public void setRiskScore(double riskScore) { this.riskScore = riskScore; } public List<String> getRiskFactors() { return riskFactors; } public void setRiskFactors(List<String> riskFactors) { this.riskFactors = riskFactors; } public String getRiskLevel() { return riskLevel; } public void setRiskLevel(String riskLevel) { this.riskLevel = riskLevel; } } // Custom exception class ZeroTrustAuthenticationException extends RuntimeException { public ZeroTrustAuthenticationException(String message) { super(message); } public ZeroTrustAuthenticationException(String message, Throwable cause) { super(message, cause); } } Example 2: Device Verification Service
package com.zerotrust.device; import org.springframework.stereotype.Service; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.*; @Service public class DeviceVerificationService { private final DeviceComplianceService complianceService; private final DeviceCertificateService certificateService; private final ThreatIntelligenceService threatIntelligenceService; // In-memory cache for device trust (use Redis in production) private final Map<String, DeviceTrustCache> deviceTrustCache = new HashMap<>(); public DeviceVerificationService(DeviceComplianceService complianceService, DeviceCertificateService certificateService, ThreatIntelligenceService threatIntelligenceService) { this.complianceService = complianceService; this.certificateService = certificateService; this.threatIntelligenceService = threatIntelligenceService; } public DeviceVerification verifyDevice(DeviceContext deviceContext) { DeviceVerification verification = new DeviceVerification(); // 1. Check device certificate if (!verifyDeviceCertificate(deviceContext.getDeviceCertificate())) { verification.setTrusted(false); verification.setFailureReason("Invalid device certificate"); return verification; } // 2. Check device compliance DeviceCompliance compliance = complianceService.checkCompliance(deviceContext); if (!compliance.isCompliant()) { verification.setTrusted(false); verification.setFailureReason("Device not compliant: " + compliance.getNonComplianceReasons()); return verification; } // 3. Check threat intelligence if (threatIntelligenceService.isDeviceCompromised(deviceContext.getDeviceId())) { verification.setTrusted(false); verification.setFailureReason("Device flagged as compromised"); return verification; } // 4. Check security update status if (!isSecurityUpdateCurrent(deviceContext.getLastSecurityUpdate())) { verification.setTrusted(false); verification.setFailureReason("Security updates not current"); return verification; } // 5. Update device trust cache updateDeviceTrustCache(deviceContext.getDeviceId(), verification); verification.setTrusted(true); verification.setComplianceLevel(compliance.getComplianceLevel()); verification.setBiometricEnabled(deviceContext.isBiometricEnabled()); return verification; } private boolean verifyDeviceCertificate(String deviceCertificate) { if (deviceCertificate == null || deviceCertificate.trim().isEmpty()) { return false; } return certificateService.validateCertificate(deviceCertificate); } private boolean isSecurityUpdateCurrent(Instant lastUpdate) { if (lastUpdate == null) { return false; } // Consider updates older than 30 days as outdated return lastUpdate.isAfter(Instant.now().minus(30, ChronoUnit.DAYS)); } private void updateDeviceTrustCache(String deviceId, DeviceVerification verification) { DeviceTrustCache cacheEntry = new DeviceTrustCache(); cacheEntry.setDeviceId(deviceId); cacheEntry.setLastVerified(Instant.now()); cacheEntry.setTrusted(verification.isTrusted()); cacheEntry.setComplianceLevel(verification.getComplianceLevel()); deviceTrustCache.put(deviceId, cacheEntry); } public boolean isDevicePreVerified(String deviceId) { DeviceTrustCache cacheEntry = deviceTrustCache.get(deviceId); if (cacheEntry == null) { return false; } // Consider cache valid for 1 hour return cacheEntry.isTrusted() && cacheEntry.getLastVerified().isAfter(Instant.now().minus(1, ChronoUnit.HOURS)); } } class DeviceVerification { private boolean trusted; private String failureReason; private String complianceLevel; private boolean biometricEnabled; // Getters and setters public boolean isTrusted() { return trusted; } public void setTrusted(boolean trusted) { this.trusted = trusted; } public String getFailureReason() { return failureReason; } public void setFailureReason(String failureReason) { this.failureReason = failureReason; } public String getComplianceLevel() { return complianceLevel; } public void setComplianceLevel(String complianceLevel) { this.complianceLevel = complianceLevel; } public boolean isBiometricEnabled() { return biometricEnabled; } public void setBiometricEnabled(boolean biometricEnabled) { this.biometricEnabled = biometricEnabled; } } class DeviceTrustCache { private String deviceId; private Instant lastVerified; private boolean trusted; private String complianceLevel; // Getters and setters public String getDeviceId() { return deviceId; } public void setDeviceId(String deviceId) { this.deviceId = deviceId; } public Instant getLastVerified() { return lastVerified; } public void setLastVerified(Instant lastVerified) { this.lastVerified = lastVerified; } public boolean isTrusted() { return trusted; } public void setTrusted(boolean trusted) { this.trusted = trusted; } public String getComplianceLevel() { return complianceLevel; } public void setComplianceLevel(String complianceLevel) { this.complianceLevel = complianceLevel; } } Example 3: Risk Assessment Engine
package com.zerotrust.risk; import org.springframework.stereotype.Service; import java.time.Instant; import java.util.*; @Service public class RiskAssessmentService { private final UserBehaviorService userBehaviorService; private final ThreatIntelligenceService threatIntelligenceService; private final GeoLocationService geoLocationService; public RiskAssessmentService(UserBehaviorService userBehaviorService, ThreatIntelligenceService threatIntelligenceService, GeoLocationService geoLocationService) { this.userBehaviorService = userBehaviorService; this.threatIntelligenceService = threatIntelligenceService; this.geoLocationService = geoLocationService; } public RiskAssessment assessRisk(Object identityToken, DeviceContext deviceContext, NetworkContext networkContext) { RiskAssessment risk = new RiskAssessment(); List<String> riskFactors = new ArrayList<>(); double riskScore = 0.0; // 1. Device risk assessment double deviceRisk = assessDeviceRisk(deviceContext); riskScore += deviceRisk; if (deviceRisk > 20) riskFactors.add("High device risk"); // 2. Network risk assessment double networkRisk = assessNetworkRisk(networkContext); riskScore += networkRisk; if (networkRisk > 20) riskFactors.add("High network risk"); // 3. Behavioral risk assessment double behaviorRisk = assessBehavioralRisk(identityToken, deviceContext, networkContext); riskScore += behaviorRisk; if (behaviorRisk > 20) riskFactors.add("Suspicious behavior"); // 4. Threat intelligence risk double threatRisk = assessThreatIntelligenceRisk(identityToken, deviceContext, networkContext); riskScore += threatRisk; if (threatRisk > 20) riskFactors.add("Threat intelligence match"); // 5. Time-based risk double timeRisk = assessTimeBasedRisk(); riskScore += timeRisk; if (timeRisk > 10) riskFactors.add("Unusual access time"); risk.setRiskScore(Math.min(riskScore, 100.0)); risk.setRiskFactors(riskFactors); risk.setRiskLevel(calculateRiskLevel(riskScore)); return risk; } private double assessDeviceRisk(DeviceContext deviceContext) { double risk = 0.0; if (!deviceContext.isCompliant()) risk += 30; if (!deviceContext.isCorporateDevice()) risk += 20; if (!deviceContext.isBiometricEnabled()) risk += 10; // Check security update age if (deviceContext.getLastSecurityUpdate() != null) { long daysSinceUpdate = ChronoUnit.DAYS.between( deviceContext.getLastSecurityUpdate(), Instant.now() ); if (daysSinceUpdate > 90) risk += 25; else if (daysSinceUpdate > 30) risk += 15; } return risk; } private double assessNetworkRisk(NetworkContext networkContext) { double risk = 0.0; if (!networkContext.isSecureNetwork()) risk += 25; if (networkContext.isVpnInUse()) risk += 15; if (!networkContext.isCorporateNetwork()) risk += 20; // Geo-location risk GeoLocationRisk geoRisk = geoLocationService.assessLocationRisk(networkContext.getGeoLocation()); risk += geoRisk.getRiskScore(); return risk; } private double assessBehavioralRisk(Object identityToken, DeviceContext deviceContext, NetworkContext networkContext) { return userBehaviorService.analyzeBehavior(identityToken, deviceContext, networkContext); } private double assessThreatIntelligenceRisk(Object identityToken, DeviceContext deviceContext, NetworkContext networkContext) { double risk = 0.0; if (threatIntelligenceService.isIpBlacklisted(networkContext.getIpAddress())) { risk += 40; } if (threatIntelligenceService.isDeviceCompromised(deviceContext.getDeviceId())) { risk += 50; } return risk; } private double assessTimeBasedRisk() { Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); // Higher risk outside business hours and weekends if (hour < 8 || hour > 18) { return 15.0; } if (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) { return 20.0; } return 0.0; } private String calculateRiskLevel(double riskScore) { if (riskScore >= 80) return "CRITICAL"; if (riskScore >= 60) return "HIGH"; if (riskScore >= 40) return "MEDIUM"; if (riskScore >= 20) return "LOW"; return "MINIMAL"; } } Example 4: Policy Enforcement Point
package com.zerotrust.policy; import org.springframework.security.access.AccessDecisionVoter; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.core.Authentication; import org.springframework.security.web.FilterInvocation; import org.springframework.stereotype.Component; import java.util.Collection; import java.util.regex.Pattern; @Component public class ZeroTrustAccessDecisionVoter implements AccessDecisionVoter<FilterInvocation> { private final PolicyDecisionPoint policyDecisionPoint; private final ContextAwarePolicyService contextAwarePolicyService; // Micro-segmentation patterns private final Pattern sensitiveDataPattern = Pattern.compile("/api/v1/(users|payments|admin)/.*"); private final Pattern internalApiPattern = Pattern.compile("/internal/.*"); public ZeroTrustAccessDecisionVoter(PolicyDecisionPoint policyDecisionPoint, ContextAwarePolicyService contextAwarePolicyService) { this.policyDecisionPoint = policyDecisionPoint; this.contextAwarePolicyService = contextAwarePolicyService; } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return FilterInvocation.class.isAssignableFrom(clazz); } @Override public int vote(Authentication authentication, FilterInvocation filterInvocation, Collection<ConfigAttribute> attributes) { String requestUrl = filterInvocation.getRequestUrl(); String httpMethod = filterInvocation.getHttpRequest().getMethod(); // Get Zero Trust context ZeroTrustContext zeroTrustContext = extractZeroTrustContext(authentication, filterInvocation); // Apply micro-segmentation if (isSensitiveEndpoint(requestUrl)) { return voteSensitiveAccess(authentication, zeroTrustContext, requestUrl, httpMethod); } if (isInternalEndpoint(requestUrl)) { return voteInternalAccess(authentication, zeroTrustContext, requestUrl, httpMethod); } // Default policy evaluation PolicyDecision decision = policyDecisionPoint.evaluate( authentication, zeroTrustContext, requestUrl, httpMethod ); return decision.isAllowed() ? ACCESS_GRANTED : ACCESS_DENIED; } private ZeroTrustContext extractZeroTrustContext(Authentication authentication, FilterInvocation filterInvocation) { ZeroTrustContext context = new ZeroTrustContext(); // Extract from authentication if (authentication.getPrincipal() instanceof ZeroTrustUser) { ZeroTrustUser user = (ZeroTrustUser) authentication.getPrincipal(); context.setUserContext(user.getUserContext()); } // Extract device context context.setDeviceContext(extractDeviceContext(filterInvocation)); // Extract network context context.setNetworkContext(extractNetworkContext(filterInvocation)); // Extract request context context.setRequestContext(extractRequestContext(filterInvocation)); return context; } private DeviceContext extractDeviceContext(FilterInvocation filterInvocation) { DeviceContext deviceContext = new DeviceContext(); // Extract from headers String userAgent = filterInvocation.getRequest().getHeader("User-Agent"); String deviceId = filterInvocation.getRequest().getHeader("X-Device-ID"); String deviceCertificate = filterInvocation.getRequest().getHeader("X-Device-Certificate"); deviceContext.setUserAgent(userAgent); deviceContext.setDeviceId(deviceId); deviceContext.setDeviceCertificate(deviceCertificate); // Additional device context extraction logic // This would typically involve calling device attestation services return deviceContext; } private NetworkContext extractNetworkContext(FilterInvocation filterInvocation) { NetworkContext networkContext = new NetworkContext(); String ipAddress = filterInvocation.getRequest().getRemoteAddr(); String forwardedFor = filterInvocation.getRequest().getHeader("X-Forwarded-For"); networkContext.setIpAddress(forwardedFor != null ? forwardedFor : ipAddress); networkContext.setUserAgent(filterInvocation.getRequest().getHeader("User-Agent")); // Determine network trust level networkContext.setSecureNetwork(isSecureConnection(filterInvocation)); networkContext.setCorporateNetwork(isCorporateNetwork(ipAddress)); networkContext.setVpnInUse(isVpnConnection(ipAddress)); return networkContext; } private RequestContext extractRequestContext(FilterInvocation filterInvocation) { RequestContext requestContext = new RequestContext(); requestContext.setUrl(filterInvocation.getRequestUrl()); requestContext.setMethod(filterInvocation.getHttpRequest().getMethod()); requestContext.setTimestamp(java.time.Instant.now()); requestContext.setQueryString(filterInvocation.getRequest().getQueryString()); return requestContext; } private int voteSensitiveAccess(Authentication authentication, ZeroTrustContext context, String requestUrl, String httpMethod) { // Enhanced security for sensitive endpoints if (!context.getUserContext().isHighlyAssuredIdentity()) { return ACCESS_DENIED; } if (!context.getDeviceContext().isCorporateDevice()) { return ACCESS_DENIED; } if (context.getRiskAssessment().getRiskScore() > 40) { return ACCESS_DENIED; } // Check time-based access if (!isDuringBusinessHours()) { return ACCESS_DENIED; } return policyDecisionPoint.evaluate(authentication, context, requestUrl, httpMethod) .isAllowed() ? ACCESS_GRANTED : ACCESS_DENIED; } private int voteInternalAccess(Authentication authentication, ZeroTrustContext context, String requestUrl, String httpMethod) { // Internal APIs require corporate network if (!context.getNetworkContext().isCorporateNetwork()) { return ACCESS_DENIED; } // Internal APIs require corporate devices if (!context.getDeviceContext().isCorporateDevice()) { return ACCESS_DENIED; } return policyDecisionPoint.evaluate(authentication, context, requestUrl, httpMethod) .isAllowed() ? ACCESS_GRANTED : ACCESS_DENIED; } private boolean isSensitiveEndpoint(String url) { return sensitiveDataPattern.matcher(url).matches(); } private boolean isInternalEndpoint(String url) { return internalApiPattern.matcher(url).matches(); } private boolean isSecureConnection(FilterInvocation filterInvocation) { return filterInvocation.getRequest().isSecure(); } private boolean isCorporateNetwork(String ipAddress) { // Check if IP belongs to corporate network range return ipAddress.startsWith("10.") || ipAddress.startsWith("192.168.") || ipAddress.startsWith("172.16."); } private boolean isVpnConnection(String ipAddress) { // Check if IP belongs to known VPN ranges // This would typically involve checking against a database return false; } private boolean isDuringBusinessHours() { Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); return hour >= 8 && hour <= 18 && dayOfWeek >= Calendar.MONDAY && dayOfWeek <= Calendar.FRIDAY; } } class ZeroTrustContext { private UserContext userContext; private DeviceContext deviceContext; private NetworkContext networkContext; private RequestContext requestContext; private RiskAssessment riskAssessment; // Getters and setters public UserContext getUserContext() { return userContext; } public void setUserContext(UserContext userContext) { this.userContext = userContext; } public DeviceContext getDeviceContext() { return deviceContext; } public void setDeviceContext(DeviceContext deviceContext) { this.deviceContext = deviceContext; } public NetworkContext getNetworkContext() { return networkContext; } public void setNetworkContext(NetworkContext networkContext) { this.networkContext = networkContext; } public RequestContext getRequestContext() { return requestContext; } public void setRequestContext(RequestContext requestContext) { this.requestContext = requestContext; } public RiskAssessment getRiskAssessment() { return riskAssessment; } public void setRiskAssessment(RiskAssessment riskAssessment) { this.riskAssessment = riskAssessment; } } class RequestContext { private String url; private String method; private Instant timestamp; private String queryString; // Getters and setters public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public Instant getTimestamp() { return timestamp; } public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; } public String getQueryString() { return queryString; } public void setQueryString(String queryString) { this.queryString = queryString; } } class PolicyDecision { private boolean allowed; private String reason; private List<String> obligations; // Getters and setters public boolean isAllowed() { return allowed; } public void setAllowed(boolean allowed) { this.allowed = allowed; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } public List<String> getObligations() { return obligations; } public void setObligations(List<String> obligations) { this.obligations = obligations; } } Example 5: Security Configuration
package com.zerotrust.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.intercept.AuthorizationFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.Arrays; @Configuration @EnableWebSecurity @EnableMethodSecurity(prePostEnabled = true) public class ZeroTrustSecurityConfig { private final ZeroTrustAuthenticationFilter zeroTrustAuthenticationFilter; private final ZeroTrustAccessDecisionManager zeroTrustAccessDecisionManager; public ZeroTrustSecurityConfig(ZeroTrustAuthenticationFilter zeroTrustAuthenticationFilter, ZeroTrustAccessDecisionManager zeroTrustAccessDecisionManager) { this.zeroTrustAuthenticationFilter = zeroTrustAuthenticationFilter; this.zeroTrustAccessDecisionManager = zeroTrustAccessDecisionManager; } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // Zero Trust: No implicit trust .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() // CORS configuration .cors().configurationSource(corsConfigurationSource()) .and() // Add Zero Trust authentication filter .addFilterBefore(zeroTrustAuthenticationFilter, AuthorizationFilter.class) // Authorization .authorizeHttpRequests(authorize -> authorize .requestMatchers("/api/public/**").permitAll() .requestMatchers("/actuator/health").permitAll() .requestMatchers("/internal/**").hasRole("INTERNAL") .anyRequest().authenticated() ) // Use Zero Trust access decision manager .authorizeHttpRequests() .accessDecisionManager(zeroTrustAccessDecisionManager) // OAuth2 Resource Server configuration .and() .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .jwtAuthenticationConverter(new ZeroTrustJwtAuthenticationConverter()) ) ) // Security headers .headers(headers -> headers .contentSecurityPolicy("default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'") .and() .httpStrictTransportSecurity().maxAgeInSeconds(31536000) .and() .xssProtection().block(false) .and() .frameOptions().deny() ); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOriginPatterns(Arrays.asList( "https://*.company.com", "https://company.com" )); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "X-Device-ID", "X-Device-Certificate")); configuration.setExposedHeaders(Arrays.asList("X-Request-ID", "X-Rate-Limit-Remaining")); configuration.setAllowCredentials(true); configuration.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } } // Zero Trust JWT Authentication Converter class ZeroTrustJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> { private final ZeroTrustIdentityService identityService; public ZeroTrustJwtAuthenticationConverter(ZeroTrustIdentityService identityService) { this.identityService = identityService; } @Override public AbstractAuthenticationToken convert(Jwt jwt) { // Extract device and network context from request DeviceContext deviceContext = extractDeviceContext(); NetworkContext networkContext = extractNetworkContext(); // Perform Zero Trust identity verification IdentityContext identityContext = identityService.verifyIdentity( new JwtAuthenticationToken(jwt), deviceContext, networkContext ); // Create Zero Trust authentication token return new ZeroTrustAuthenticationToken(identityContext, jwt); } private DeviceContext extractDeviceContext() { // Extract from current request ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); DeviceContext deviceContext = new DeviceContext(); deviceContext.setDeviceId(request.getHeader("X-Device-ID")); deviceContext.setDeviceCertificate(request.getHeader("X-Device-Certificate")); deviceContext.setUserAgent(request.getHeader("User-Agent")); return deviceContext; } return new DeviceContext(); } private NetworkContext extractNetworkContext() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); NetworkContext networkContext = new NetworkContext(); networkContext.setIpAddress(getClientIpAddress(request)); networkContext.setUserAgent(request.getHeader("User-Agent")); networkContext.setSecureNetwork(request.isSecure()); return networkContext; } return new NetworkContext(); } private String getClientIpAddress(HttpServletRequest request) { String xForwardedFor = request.getHeader("X-Forwarded-For"); if (xForwardedFor != null && !xForwardedFor.isEmpty()) { return xForwardedFor.split(",")[0].trim(); } return request.getRemoteAddr(); } } Example 6: Monitoring and Auditing
package com.zerotrust.monitoring; import org.springframework.stereotype.Component; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import java.time.Instant; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @Component public class ZeroTrustAuditService { private final MeterRegistry meterRegistry; private final AuditLogRepository auditLogRepository; // Metrics private final Counter authenticationSuccessCounter; private final Counter authenticationFailureCounter; private final Counter accessGrantedCounter; private final Counter accessDeniedCounter; private final Timer authenticationTimer; // Real-time threat detection private final ConcurrentMap<String, UserAccessPattern> userAccessPatterns = new ConcurrentHashMap<>(); public ZeroTrustAuditService(MeterRegistry meterRegistry, AuditLogRepository auditLogRepository) { this.meterRegistry = meterRegistry; this.auditLogRepository = auditLogRepository; // Initialize metrics this.authenticationSuccessCounter = Counter.builder("zerotrust.auth.success") .description("Number of successful authentications") .register(meterRegistry); this.authenticationFailureCounter = Counter.builder("zerotrust.auth.failure") .description("Number of failed authentications") .register(meterRegistry); this.accessGrantedCounter = Counter.builder("zerotrust.access.granted") .description("Number of granted access requests") .register(meterRegistry); this.accessDeniedCounter = Counter.builder("zerotrust.access.denied") .description("Number of denied access requests") .register(meterRegistry); this.authenticationTimer = Timer.builder("zerotrust.auth.duration") .description("Time taken for authentication") .register(meterRegistry); } public void logAuthenticationAttempt(AuthenticationAttempt attempt) { AuditLogEntry logEntry = new AuditLogEntry(); logEntry.setTimestamp(Instant.now()); logEntry.setEventType("AUTHENTICATION_ATTEMPT"); logEntry.setUserId(attempt.getUserId()); logEntry.setDeviceId(attempt.getDeviceId()); logEntry.setIpAddress(attempt.getIpAddress()); logEntry.setSuccess(attempt.isSuccess()); logEntry.setRiskScore(attempt.getRiskScore()); logEntry.setDetails(attempt.getDetails()); auditLogRepository.save(logEntry); // Update metrics if (attempt.isSuccess()) { authenticationSuccessCounter.increment(); } else { authenticationFailureCounter.increment(); } // Update access patterns for anomaly detection updateAccessPatterns(attempt); } public void logAccessDecision(AccessDecision decision) { AuditLogEntry logEntry = new AuditLogEntry(); logEntry.setTimestamp(Instant.now()); logEntry.setEventType("ACCESS_DECISION"); logEntry.setUserId(decision.getUserId()); logEntry.setResource(decision.getResource()); logEntry.setAction(decision.getAction()); logEntry.setGranted(decision.isGranted()); logEntry.setRiskScore(decision.getRiskScore()); logEntry.setPolicy(decision.getPolicyName()); logEntry.setDetails(decision.getDetails()); auditLogRepository.save(logEntry); // Update metrics if (decision.isGranted()) { accessGrantedCounter.increment(); } else { accessDeniedCounter.increment(); } } public void logSecurityEvent(SecurityEvent event) { AuditLogEntry logEntry = new AuditLogEntry(); logEntry.setTimestamp(Instant.now()); logEntry.setEventType("SECURITY_EVENT"); logEntry.setSeverity(event.getSeverity()); logEntry.setEventCode(event.getEventCode()); logEntry.setDescription(event.getDescription()); logEntry.setDetails(event.getDetails()); auditLogRepository.save(logEntry); // Alert if high severity if (event.getSeverity().equals("HIGH") || event.getSeverity().equals("CRITICAL")) { triggerSecurityAlert(event); } } private void updateAccessPatterns(AuthenticationAttempt attempt) { String userId = attempt.getUserId(); UserAccessPattern pattern = userAccessPatterns.computeIfAbsent(userId, k -> new UserAccessPattern(userId)); pattern.recordAccess(attempt); // Check for anomalies if (pattern.detectAnomalies()) { SecurityEvent anomalyEvent = new SecurityEvent(); anomalyEvent.setSeverity("MEDIUM"); anomalyEvent.setEventCode("ANOMALOUS_ACCESS_PATTERN"); anomalyEvent.setDescription("Unusual access pattern detected for user: " + userId); anomalyEvent.setDetails(pattern.getAnomalyDetails()); logSecurityEvent(anomalyEvent); } } private void triggerSecurityAlert(SecurityEvent event) { // Implement alerting logic (email, SMS, Slack, etc.) System.err.println("SECURITY ALERT: " + event.getDescription()); // Could integrate with SIEM systems // siemService.sendAlert(event); } public AuthenticationMetrics getAuthenticationMetrics() { AuthenticationMetrics metrics = new AuthenticationMetrics(); metrics.setSuccessCount(authenticationSuccessCounter.count()); metrics.setFailureCount(authenticationFailureCounter.count()); metrics.setSuccessRate(authenticationSuccessCounter.count() / (authenticationSuccessCounter.count() + authenticationFailureCounter.count())); return metrics; } } class AuthenticationAttempt { private String userId; private String deviceId; private String ipAddress; private boolean success; private double riskScore; private String details; private Instant timestamp; // Getters and setters public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getDeviceId() { return deviceId; } public void setDeviceId(String deviceId) { this.deviceId = deviceId; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public double getRiskScore() { return riskScore; } public void setRiskScore(double riskScore) { this.riskScore = riskScore; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public Instant getTimestamp() { return timestamp; } public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; } } class AccessDecision { private String userId; private String resource; private String action; private boolean granted; private double riskScore; private String policyName; private String details; // Getters and setters public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getResource() { return resource; } public void setResource(String resource) { this.resource = resource; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public boolean isGranted() { return granted; } public void setGranted(boolean granted) { this.granted = granted; } public double getRiskScore() { return riskScore; } public void setRiskScore(double riskScore) { this.riskScore = riskScore; } public String getPolicyName() { return policyName; } public void setPolicyName(String policyName) { this.policyName = policyName; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } } class SecurityEvent { private String severity; private String eventCode; private String description; private String details; // Getters and setters public String getSeverity() { return severity; } public void setSeverity(String severity) { this.severity = severity; } public String getEventCode() { return eventCode; } public void setEventCode(String eventCode) { this.eventCode = eventCode; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } } class UserAccessPattern { private String userId; private List<AuthenticationAttempt> recentAttempts = new ArrayList<>(); private Map<String, Integer> locationFrequency = new HashMap<>(); private Map<String, Integer> deviceFrequency = new HashMap<>(); public UserAccessPattern(String userId) { this.userId = userId; } public void recordAccess(AuthenticationAttempt attempt) { recentAttempts.add(attempt); // Keep only last 100 attempts if (recentAttempts.size() > 100) { recentAttempts.remove(0); } // Update frequency maps locationFrequency.merge(attempt.getIpAddress(), 1, Integer::sum); deviceFrequency.merge(attempt.getDeviceId(), 1, Integer::sum); } public boolean detectAnomalies() { if (recentAttempts.size() < 5) { return false; // Not enough data } // Check for rapid successive attempts if (hasRapidSuccessiveAttempts()) { return true; } // Check for unusual location if (hasUnusualLocation()) { return true; } // Check for multiple devices if (hasMultipleDevices()) { return true; } return false; } private boolean hasRapidSuccessiveAttempts() { if (recentAttempts.size() < 2) return false; AuthenticationAttempt last = recentAttempts.get(recentAttempts.size() - 1); AuthenticationAttempt secondLast = recentAttempts.get(recentAttempts.size() - 2); long secondsBetween = java.time.Duration.between( secondLast.getTimestamp(), last.getTimestamp() ).getSeconds(); return secondsBetween < 5; // Less than 5 seconds between attempts } private boolean hasUnusualLocation() { if (locationFrequency.size() < 2) return false; // If user is accessing from many different locations in short time return locationFrequency.size() > 3 && recentAttempts.size() > 10; } private boolean hasMultipleDevices() { return deviceFrequency.size() > 2; } public String getAnomalyDetails() { return String.format("User %s: locations=%d, devices=%d, attempts=%d", userId, locationFrequency.size(), deviceFrequency.size(), recentAttempts.size()); } } Application Configuration
# application.properties # Zero Trust Configuration zerotrust.identity-provider.url=https://auth.company.com zerotrust.device-attestation.enabled=true zerotrust.risk-threshold.medium=40 zerotrust.risk-threshold.high=70 zerotrust.session.timeout-minutes=15 # Security spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.company.com/realms/company spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://auth.company.com/realms/company/protocol/openid-connect/certs # Database spring.datasource.url=jdbc:postgresql://localhost:5432/zerotrust spring.datasource.username=zerotrust_user spring.datasource.password=secure_password # Redis spring.redis.host=localhost spring.redis.port=6379 # Monitoring management.endpoints.web.exposure.include=health,metrics,prometheus management.endpoint.health.show-details=always
Conclusion
This Zero Trust Architecture implementation provides:
Core Components:
- Identity Verification: Multi-factor, context-aware authentication
- Device Trust: Comprehensive device compliance checking
- Risk Assessment: Real-time risk scoring and analysis
- Policy Enforcement: Context-aware access control
- Monitoring & Auditing: Comprehensive logging and anomaly detection
Key Benefits:
- Enhanced Security: No implicit trust, continuous verification
- Adaptive Access: Dynamic permissions based on risk context
- Compliance: Meets regulatory requirements for access control
- Visibility: Complete audit trail and monitoring
Production Considerations:
- Performance: Cache device trust and risk assessments
- Scalability: Use distributed caching (Redis) for session management
- Resilience: Implement circuit breakers for external services
- Compliance: Regular security audits and penetration testing
- Monitoring: Integrate with SIEM systems for security analytics
This implementation provides a solid foundation for Zero Trust Architecture that can be extended based on specific organizational requirements and threat models.