Zero Trust Security: Implementing BeyondCorp Model in Java Applications

Article

BeyondCorp is Google's groundbreaking zero-trust security model that shifts access controls from the network perimeter to individual devices and users. Instead of assuming trust based on network location, BeyondCorp verifies every access request regardless of where it originates. For Java applications, implementing BeyondCorp principles means building security directly into applications rather than relying on network-level protections.

In this guide, we'll explore how to implement BeyondCorp security principles in Java applications, creating zero-trust architectures that verify every request.

Why BeyondCorp for Java Applications?

  • Zero Trust Architecture: Verify every request, never assume trust
  • Device-Centric Security: Base access on device identity and health
  • User-Centric Access: Granular permissions based on user context
  • Network Agnostic: Secure access from any location
  • Continuous Verification: Constantly revalidate security posture
  • Compliance Ready: Meets modern security and compliance requirements

Part 1: BeyondCorp Architecture Overview

1.1 Core BeyondCorp Principles

Access Request → Identity Verification → Device Authentication → Context Evaluation → Policy Decision → Access Grant
↓                 ↓                   ↓                   ↓                 ↓              ↓
Any Network       Multi-Factor        Certificate/       User Role         Fine-Grained    Least Privilege
Location          Authentication      Device Health      Device State      Policies        Access

1.2 Java BeyondCorp Components

Java Application → Access Proxy → Identity Provider → Device Inventory → Policy Engine → Data Sources
↓               ↓               ↓                 ↓                 ↓             ↓
Spring Security   API Gateway    OAuth2/OIDC       Device Cert      ABAC/PBAC      Encryption
Filters           Reverse Proxy  SAML Integration  Health Checks    Risk Engine    Tokenization

1.3 Project Structure

java-beyondcorp-app/
├── src/
│   ├── main/java/com/beyondcorp/
│   │   ├── security/
│   │   │   ├── identity/
│   │   │   ├── device/
│   │   │   ├── context/
│   │   │   └── policy/
│   │   ├── api/
│   │   └── config/
│   └── resources/
├── kubernetes/
│   ├── security/
│   └── policies/
└── deployments/
├── access-proxy/
└── policy-engine/

Part 2: Dependencies and Setup

2.1 Security Dependencies

<!-- pom.xml -->
<properties>
<spring-boot.version>3.1.0</spring-boot.version>
<spring-security.version>6.1.0</spring-security.version>
<nimbus-jose-jwt.version>9.31</nimbus-jose-jwt.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-actuator</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>
<!-- Spring Security OAuth2 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<version>${spring-security.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose-jwt.version}</version>
</dependency>
<!-- Device Certificate -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>1.73</version>
</dependency>
<!-- Risk Engine -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Observability -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.11.5</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
<version>1.1.5</version>
</dependency>
<!-- Caching -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.6</version>
</dependency>
</dependencies>

Part 3: Identity-Centric Security

3.1 Multi-Factor Authentication Service

// File: src/main/java/com/beyondcorp/security/identity/MultiFactorAuthService.java
package com.beyondcorp.security.identity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Service
public class MultiFactorAuthService {
private static final Logger logger = LoggerFactory.getLogger(MultiFactorAuthService.class);
private final SecureRandom secureRandom = new SecureRandom();
private final Map<String, MFAChallenge> pendingChallenges = new ConcurrentHashMap<>();
@Value("${beyondcorp.mfa.timeout:300}") // 5 minutes
private int mfaTimeoutSeconds;
@Value("${beyondcorp.mfa.code.length:6}")
private int codeLength;
public MFAResult initiateMFA(String userId, String deviceId, AuthContext context) {
try {
// Generate MFA code
String mfaCode = generateMFACode();
String challengeId = generateChallengeId();
// Create challenge
MFAChallenge challenge = new MFAChallenge(
challengeId,
userId,
deviceId,
mfaCode,
Instant.now().plusSeconds(mfaTimeoutSeconds),
context,
MFAStatus.PENDING
);
pendingChallenges.put(challengeId, challenge);
// In production, this would send via SMS, email, or authenticator app
logger.info("MFA code for user {}: {} (Challenge: {})", userId, mfaCode, challengeId);
return new MFAResult(
challengeId,
mfaCode, // In production, don't return the code
mfaTimeoutSeconds,
"MFA challenge created successfully"
);
} catch (Exception e) {
logger.error("Failed to initiate MFA for user: {}", userId, e);
return new MFAResult(null, null, 0, "MFA initiation failed: " + e.getMessage());
}
}
public MFAVerificationResult verifyMFA(String challengeId, String providedCode, 
DeviceContext deviceContext) {
MFAChallenge challenge = pendingChallenges.get(challengeId);
if (challenge == null) {
return new MFAVerificationResult(false, "Invalid challenge ID", null);
}
if (challenge.expiresAt().isBefore(Instant.now())) {
pendingChallenges.remove(challengeId);
return new MFAVerificationResult(false, "MFA challenge expired", null);
}
if (!challenge.mfaCode().equals(providedCode)) {
challenge = challenge.withAttempts(challenge.attempts() + 1);
pendingChallenges.put(challengeId, challenge);
if (challenge.attempts() >= 3) {
pendingChallenges.remove(challengeId);
return new MFAVerificationResult(false, "Too many failed attempts", null);
}
return new MFAVerificationResult(false, "Invalid MFA code", null);
}
// Verify device context matches
if (!challenge.deviceId().equals(deviceContext.deviceId())) {
return new MFAVerificationResult(false, "Device context mismatch", null);
}
// Success - remove challenge and create verified context
pendingChallenges.remove(challengeId);
VerifiedIdentity verifiedIdentity = new VerifiedIdentity(
challenge.userId(),
challenge.deviceId(),
Instant.now(),
Instant.now().plusHours(24), // 24-hour session
challenge.context(),
deviceContext
);
logger.info("MFA verification successful for user: {}", challenge.userId());
return new MFAVerificationResult(true, "MFA verification successful", verifiedIdentity);
}
public MFAStatus checkMFAStatus(String challengeId) {
MFAChallenge challenge = pendingChallenges.get(challengeId);
if (challenge == null) {
return MFAStatus.EXPIRED;
}
return challenge.status();
}
public void cleanupExpiredChallenges() {
Instant now = Instant.now();
pendingChallenges.entrySet().removeIf(entry -> 
entry.getValue().expiresAt().isBefore(now)
);
}
private String generateMFACode() {
int code = secureRandom.nextInt((int) Math.pow(10, codeLength));
return String.format("%0" + codeLength + "d", code);
}
private String generateChallengeId() {
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
// Records
public record MFAChallenge(
String challengeId,
String userId,
String deviceId,
String mfaCode,
Instant expiresAt,
AuthContext context,
MFAStatus status,
int attempts
) {
public MFAChallenge {
attempts = 0;
}
public MFAChallenge withAttempts(int newAttempts) {
return new MFAChallenge(challengeId, userId, deviceId, mfaCode, expiresAt, 
context, status, newAttempts);
}
}
public record MFAResult(String challengeId, String mfaCode, int timeoutSeconds, String message) {}
public record MFAVerificationResult(boolean success, String message, VerifiedIdentity verifiedIdentity) {}
public record VerifiedIdentity(
String userId,
String deviceId,
Instant verifiedAt,
Instant expiresAt,
AuthContext authContext,
DeviceContext deviceContext
) {}
public record AuthContext(
String ipAddress,
String userAgent,
String location,
RiskLevel riskLevel
) {}
public record DeviceContext(
String deviceId,
String deviceCertificate,
String osVersion,
String securityPatchLevel,
boolean encrypted,
boolean jailbroken
) {}
public enum MFAStatus {
PENDING, VERIFIED, EXPIRED, FAILED
}
public enum RiskLevel {
LOW, MEDIUM, HIGH, CRITICAL
}
}

3.2 JWT Token Service with Enhanced Claims

// File: src/main/java/com/beyondcorp/security/identity/JwtTokenService.java
package com.beyondcorp.security.identity;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.security.interfaces.RSAPublicKey;
import java.time.Instant;
import java.util.*;
@Service
public class JwtTokenService {
private static final Logger logger = LoggerFactory.getLogger(JwtTokenService.class);
private final RSAKey rsaKey;
private final JWSSigner signer;
private final JWSVerifier verifier;
@Value("${beyondcorp.jwt.issuer:beyondcorp-app}")
private String issuer;
@Value("${beyondcorp.jwt.access-token.expiration:3600}") // 1 hour
private long accessTokenExpiration;
@Value("${beyondcorp.jwt.refresh-token.expiration:86400}") // 24 hours
private long refreshTokenExpiration;
public JwtTokenService() throws Exception {
// In production, use proper key management (HSM, KMS, etc.)
this.rsaKey = new RSAKeyGenerator(2048)
.keyID(UUID.randomUUID().toString())
.generate();
this.signer = new RSASSASigner(rsaKey.toPrivateKey());
this.verifier = new RSASSAVerifier((RSAPublicKey) rsaKey.toPublicKey());
}
public TokenResponse generateTokens(VerifiedIdentity verifiedIdentity, 
Set<String> roles, 
Map<String, Object> additionalClaims) {
try {
String accessToken = generateAccessToken(verifiedIdentity, roles, additionalClaims);
String refreshToken = generateRefreshToken(verifiedIdentity.userId());
return new TokenResponse(
accessToken,
refreshToken,
"Bearer",
accessTokenExpiration,
Instant.now().plusSeconds(accessTokenExpiration)
);
} catch (Exception e) {
logger.error("Failed to generate tokens for user: {}", verifiedIdentity.userId(), e);
throw new RuntimeException("Token generation failed", e);
}
}
public TokenValidationResult validateToken(String token) {
try {
SignedJWT signedJWT = SignedJWT.parse(token);
if (!signedJWT.verify(verifier)) {
return new TokenValidationResult(false, "Invalid signature", null);
}
JWTClaimsSet claims = signedJWT.getJWTClaimsSet();
// Check expiration
if (claims.getExpirationTime().before(new Date())) {
return new TokenValidationResult(false, "Token expired", null);
}
// Check issuer
if (!issuer.equals(claims.getIssuer())) {
return new TokenValidationResult(false, "Invalid issuer", null);
}
// Extract BeyondCorp specific claims
TokenContext context = extractTokenContext(claims);
return new TokenValidationResult(true, "Token valid", context);
} catch (Exception e) {
logger.error("Token validation failed", e);
return new TokenValidationResult(false, "Token validation failed: " + e.getMessage(), null);
}
}
public String refreshAccessToken(String refreshToken, VerifiedIdentity verifiedIdentity) {
try {
TokenValidationResult refreshValidation = validateToken(refreshToken);
if (!refreshValidation.valid()) {
throw new SecurityException("Invalid refresh token");
}
// Generate new access token
Set<String> roles = refreshValidation.context().roles();
Map<String, Object> additionalClaims = refreshValidation.context().additionalClaims();
return generateAccessToken(verifiedIdentity, roles, additionalClaims);
} catch (Exception e) {
logger.error("Failed to refresh access token", e);
throw new RuntimeException("Token refresh failed", e);
}
}
private String generateAccessToken(VerifiedIdentity identity, Set<String> roles, 
Map<String, Object> additionalClaims) throws Exception {
Instant now = Instant.now();
Instant expiration = now.plusSeconds(accessTokenExpiration);
JWTClaimsSet.Builder claimsBuilder = new JWTClaimsSet.Builder()
.issuer(issuer)
.subject(identity.userId())
.audience("beyondcorp-api")
.issueTime(Date.from(now))
.expirationTime(Date.from(expiration))
.jwtID(UUID.randomUUID().toString())
.claim("roles", roles)
.claim("device_id", identity.deviceId())
.claim("auth_time", identity.verifiedAt().getEpochSecond())
.claim("auth_context", Map.of(
"ip_address", identity.authContext().ipAddress(),
"user_agent", identity.authContext().userAgent(),
"risk_level", identity.authContext().riskLevel().name()
))
.claim("device_context", Map.of(
"os_version", identity.deviceContext().osVersion(),
"security_patch", identity.deviceContext().securityPatchLevel(),
"encrypted", identity.deviceContext().encrypted(),
"jailbroken", identity.deviceContext().jailbroken()
));
// Add additional claims
if (additionalClaims != null) {
additionalClaims.forEach(claimsBuilder::claim);
}
JWTClaimsSet claims = claimsBuilder.build();
SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaKey.getKeyID()).build(),
claims
);
signedJWT.sign(signer);
return signedJWT.serialize();
}
private String generateRefreshToken(String userId) throws Exception {
Instant now = Instant.now();
Instant expiration = now.plusSeconds(refreshTokenExpiration);
JWTClaimsSet claims = new JWTClaimsSet.Builder()
.issuer(issuer)
.subject(userId)
.audience("beyondcorp-refresh")
.issueTime(Date.from(now))
.expirationTime(Date.from(expiration))
.jwtID(UUID.randomUUID().toString())
.claim("token_type", "refresh")
.build();
SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaKey.getKeyID()).build(),
claims
);
signedJWT.sign(signer);
return signedJWT.serialize();
}
private TokenContext extractTokenContext(JWTClaimsSet claims) {
try {
String userId = claims.getSubject();
String deviceId = (String) claims.getClaim("device_id");
@SuppressWarnings("unchecked")
List<String> roles = (List<String>) claims.getClaim("roles");
@SuppressWarnings("unchecked")
Map<String, Object> authContext = (Map<String, Object>) claims.getClaim("auth_context");
@SuppressWarnings("unchecked")
Map<String, Object> deviceContext = (Map<String, Object>) claims.getClaim("device_context");
@SuppressWarnings("unchecked")
Map<String, Object> additionalClaims = (Map<String, Object>) claims.getClaim("additional_claims");
return new TokenContext(
userId,
deviceId,
new HashSet<>(roles),
authContext,
deviceContext,
additionalClaims != null ? additionalClaims : Map.of()
);
} catch (Exception e) {
logger.error("Failed to extract token context", e);
throw new RuntimeException("Token context extraction failed", e);
}
}
// Records
public record TokenResponse(
String accessToken,
String refreshToken,
String tokenType,
long expiresIn,
Instant expiresAt
) {}
public record TokenValidationResult(
boolean valid,
String message,
TokenContext context
) {}
public record TokenContext(
String userId,
String deviceId,
Set<String> roles,
Map<String, Object> authContext,
Map<String, Object> deviceContext,
Map<String, Object> additionalClaims
) {}
}

Part 4: Device-Centric Security

4.1 Device Identity and Health Service

// File: src/main/java/com/beyondcorp/security/device/DeviceIdentityService.java
package com.beyondcorp.security.device;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class DeviceIdentityService {
private static final Logger logger = LoggerFactory.getLogger(DeviceIdentityService.class);
private final Map<String, DeviceRecord> deviceRegistry = new ConcurrentHashMap<>();
private final Map<String, Instant> deviceRevocationList = new ConcurrentHashMap<>();
public DeviceEnrollmentResult enrollDevice(String deviceId, X509Certificate deviceCertificate, 
DeviceMetadata metadata) {
try {
// Validate device certificate
if (!validateDeviceCertificate(deviceCertificate)) {
return new DeviceEnrollmentResult(false, "Invalid device certificate", null);
}
// Check if device is already enrolled
if (deviceRegistry.containsKey(deviceId)) {
return new DeviceEnrollmentResult(false, "Device already enrolled", null);
}
// Create device record
DeviceRecord record = new DeviceRecord(
deviceId,
deviceCertificate,
metadata,
DeviceStatus.ENROLLED,
Instant.now(),
Instant.now().plusDays(365), // 1-year enrollment
0
);
deviceRegistry.put(deviceId, record);
logger.info("Device enrolled successfully: {}", deviceId);
return new DeviceEnrollmentResult(true, "Device enrolled successfully", record);
} catch (Exception e) {
logger.error("Device enrollment failed: {}", deviceId, e);
return new DeviceEnrollmentResult(false, "Enrollment failed: " + e.getMessage(), null);
}
}
public DeviceVerificationResult verifyDevice(String deviceId, DeviceHealth healthReport) {
DeviceRecord record = deviceRegistry.get(deviceId);
if (record == null) {
return new DeviceVerificationResult(false, "Device not enrolled", null);
}
if (deviceRevocationList.containsKey(deviceId)) {
return new DeviceVerificationResult(false, "Device revoked", null);
}
if (record.enrollmentExpiresAt().isBefore(Instant.now())) {
return new DeviceVerificationResult(false, "Device enrollment expired", null);
}
// Verify device health
HealthStatus healthStatus = assessDeviceHealth(healthReport);
if (healthStatus != HealthStatus.HEALTHY) {
record = record.withHealthStatus(healthStatus);
deviceRegistry.put(deviceId, record);
return new DeviceVerificationResult(false, 
"Device health check failed: " + healthStatus, null);
}
// Update last verification time
record = record.withLastVerified(Instant.now());
deviceRegistry.put(deviceId, record);
DeviceContext context = new DeviceContext(
deviceId,
record.certificate(),
record.metadata().osVersion(),
record.metadata().securityPatchLevel(),
healthReport.encrypted(),
healthReport.jailbroken(),
healthStatus
);
return new DeviceVerificationResult(true, "Device verified successfully", context);
}
public void revokeDevice(String deviceId, String reason) {
deviceRevocationList.put(deviceId, Instant.now());
DeviceRecord record = deviceRegistry.get(deviceId);
if (record != null) {
record = record.withStatus(DeviceStatus.REVOKED);
deviceRegistry.put(deviceId, record);
}
logger.warn("Device revoked: {} - Reason: {}", deviceId, reason);
}
public DeviceHealthReport getDeviceHealth(String deviceId) {
DeviceRecord record = deviceRegistry.get(deviceId);
if (record == null) {
return new DeviceHealthReport(deviceId, HealthStatus.UNKNOWN, 
"Device not enrolled", Map.of());
}
Map<String, Object> healthDetails = Map.of(
"enrollment_status", record.status(),
"enrollment_expires", record.enrollmentExpiresAt(),
"last_verified", record.lastVerified(),
"verification_count", record.verificationCount()
);
return new DeviceHealthReport(deviceId, record.healthStatus(), 
"Device health report", healthDetails);
}
private boolean validateDeviceCertificate(X509Certificate certificate) {
try {
// Check certificate validity
certificate.checkValidity();
// Verify certificate chain (in production)
// Verify certificate is issued by trusted CA
// Check certificate extensions for device-specific constraints
return true;
} catch (Exception e) {
logger.error("Device certificate validation failed", e);
return false;
}
}
private HealthStatus assessDeviceHealth(DeviceHealth healthReport) {
if (healthReport.jailbroken()) {
return HealthStatus.COMPROMISED;
}
if (!healthReport.encrypted()) {
return HealthStatus.INSECURE;
}
if (healthReport.securityPatchLevel().compareTo("2023-01-01") < 0) {
return HealthStatus.OUTDATED;
}
// Add more health checks as needed
return HealthStatus.HEALTHY;
}
// Records
public record DeviceRecord(
String deviceId,
X509Certificate certificate,
DeviceMetadata metadata,
DeviceStatus status,
Instant enrolledAt,
Instant enrollmentExpiresAt,
Instant lastVerified,
int verificationCount,
HealthStatus healthStatus
) {
public DeviceRecord {
lastVerified = enrolledAt;
verificationCount = 0;
healthStatus = HealthStatus.HEALTHY;
}
public DeviceRecord withLastVerified(Instant newLastVerified) {
return new DeviceRecord(deviceId, certificate, metadata, status, enrolledAt,
enrollmentExpiresAt, newLastVerified, verificationCount + 1, healthStatus);
}
public DeviceRecord withStatus(DeviceStatus newStatus) {
return new DeviceRecord(deviceId, certificate, metadata, newStatus, enrolledAt,
enrollmentExpiresAt, lastVerified, verificationCount, healthStatus);
}
public DeviceRecord withHealthStatus(HealthStatus newHealthStatus) {
return new DeviceRecord(deviceId, certificate, metadata, status, enrolledAt,
enrollmentExpiresAt, lastVerified, verificationCount, newHealthStatus);
}
}
public record DeviceMetadata(
String deviceType,
String osVersion,
String securityPatchLevel,
String manufacturer,
String model,
String serialNumber
) {}
public record DeviceHealth(
String deviceId,
String osVersion,
String securityPatchLevel,
boolean encrypted,
boolean jailbroken,
Map<String, Object> additionalHealthData
) {}
public record DeviceEnrollmentResult(boolean success, String message, DeviceRecord deviceRecord) {}
public record DeviceVerificationResult(boolean success, String message, DeviceContext deviceContext) {}
public record DeviceHealthReport(String deviceId, HealthStatus status, String message, 
Map<String, Object> details) {}
public enum DeviceStatus {
ENROLLED, ACTIVE, SUSPENDED, REVOKED, EXPIRED
}
public enum HealthStatus {
HEALTHY, OUTDATED, INSECURE, COMPROMISED, UNKNOWN
}
}

Part 5: Policy Engine and Context-Aware Access

5.1 Attribute-Based Access Control (ABAC)

```java
// File: src/main/java/com/beyondcorp/security/policy/PolicyEngine.java
package com.beyondcorp.security.policy;

import com.beyondcorp.security.identity.VerifiedIdentity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class PolicyEngine {

private static final Logger logger = LoggerFactory.getLogger(PolicyEngine.class);
private final Map<String, AccessPolicy> policies = new ConcurrentHashMap<>();
public PolicyEngine() {
initializeDefaultPolicies();
}
public PolicyDecision evaluateAccess(VerifiedIdentity identity, 
AccessRequest request, 
EnvironmentContext environment) {
try {
// Collect all context data
AccessContext context = new AccessContext(identity, request, environment);
// Find applicable policies
Set<AccessPolicy> applicablePolicies = findApplicablePolicies(context);
// Evaluate policies
PolicyDecision decision = evaluatePolicies(applicablePolicies, context);
logger.info("Access decision for user {}: {} - {}", 
identity.userId(), decision.decision(), decision.reason());
return decision;
} catch (Exception e) {
logger.error("Policy evaluation failed for user: {}", identity.userId(), e);
return new PolicyDecision(Decision.DENY, "Policy evaluation failed: " + e.getMessage());
}
}
public void addPolicy(AccessPolicy policy) {
policies.put(policy.id(), policy);
logger.info("Added policy: {}", policy.id());
}
public void removePolicy(String policyId) {
policies.remove(policyId);
logger.info("Removed policy: {}", policyId);
}
private Set<AccessPolicy> findApplicablePolicies(AccessContext context) {
return policies.values().stream()
.filter(policy -> isPolicyApplicable(policy, context))
.collect(java.util.stream.Collectors.toSet());
}
private boolean isPolicyApplicable(AccessPolicy policy, AccessContext context) {
// Check if policy applies to this user
if (!policy.targetUsers().contains("ALL") && 
!policy.targetUsers().contains(context.identity().userId())) {
return false;
}
// Check if policy applies to this resource
if (!policy.targetResources().contains("ALL") && 
!policy.targetResources().contains(context.request().resource())) {
return false;
}
// Check if policy applies to this action
if (!policy.targetActions().contains("ALL") && 
!policy.targetActions().contains(context.request().action())) {
return false;
}
return true;
}
private PolicyDecision evaluatePolicies(Set<AccessPolicy> policies, AccessContext context) {
// Default deny
if (policies.isEmpty()) {
return new PolicyDecision(Decision.DENY, "No applicable policies found");
}
// Evaluate each policy
for (AccessPolicy policy : policies) {
PolicyEvaluationResult result = evaluatePolicy(policy, context);
if (result.decision() == Decision.DENY) {
return new PolicyDecision(Decision.DENY, 
"Policy " + policy.id() + " denied access: " + result.reason());
}
}
// If no policy denied, allow access
return new PolicyDecision(Decision.ALLOW, "All policies allowed access");
}
private PolicyEvaluationResult evaluatePolicy(AccessPolicy policy, AccessContext context) {
try {
// Evaluate conditions
for (PolicyCondition condition : policy.conditions()) {
boolean conditionMet = evaluateCondition(condition, context);
if (!conditionMet) {
return new PolicyEvaluationResult(Decision.DENY, 
"Condition not met: " + condition.description());
}
}
return new PolicyEvaluationResult(Decision.ALLOW, "All conditions met");
} catch (Exception e) {
logger.error("Policy evaluation failed: {}", policy.id(), e);
return new PolicyEvaluationResult(Decision.DENY, "Policy evaluation error: " + e.getMessage());
}
}
private boolean evaluateCondition(PolicyCondition condition, AccessContext context) {
return switch (condition.type()) {
case TIME_BASED -> evaluateTimeCondition(condition, context);
case LOCATION_BASED -> evaluateLocationCondition(condition, context);
case DEVICE_BASED -> evaluateDeviceCondition(condition, context);
case RISK_BASED -> evaluateRiskCondition(condition, context);
case ROLE_BASED -> evaluateRoleCondition(condition, context);
default -> false;
};
}
private boolean evaluateTimeCondition(PolicyCondition condition, AccessContext context) {
LocalDateTime now = LocalDateTime.now();
LocalTime currentTime = now.toLocalTime();
// Check if current time is within allowed hours
String allowedHours = (String) condition.parameters().get("allowed_hours");
if (allowedHours != null) {
String[] hours = allowedHours.split("-");
LocalTime start = LocalTime.parse(hours[0]);
LocalTime end = LocalTime.parse(hours[1]);
if (currentTime.isBefore(start) || currentTime.isAfter(end)) {
return false;
}
}
// Check day restrictions
String allowedDays = (String) condition.parameters().get("allowed_days");
if (allowedDays != null) {
String currentDay = now.getDayOfWeek().name().substring(0, 3).toUpperCase();
if (!allowedDays.contains(currentDay)) {
return false;
}
}
return true;
}
private boolean evaluateLocationCondition(PolicyCondition condition, AccessContext context) {
String allowedCountries = (String) condition.parameters().get("allowed_countries");
if (allowedCountries != null) {
String userCountry = context.identity().authContext().location();
if (!allowedCountries.contains(userCountry)) {
return false;
}
}
return true;
}
private boolean evaluateDeviceCondition(PolicyCondition condition, AccessContext context) {
// Check device health
Boolean requireHealthyDevice = (Boolean) condition.parameters().get("require_healthy_device");
if (requireHealthyDevice != null && requireHealthyDevice) {
if (context.identity().deviceContext().jailbroken()) {
return false;
}
if (!context.identity().deviceContext().encrypted()) {
return false;
}
}
// Check OS version
String minOsVersion = (String) condition.parameters().get("min_os_version");
if (minOsVersion != null) {
String deviceOsVersion = context.identity().deviceContext().osVersion();
if (deviceOsVersion.compareTo(minOsVersion) < 0) {
return false;
}
}
return true;
}
private boolean evaluateRiskCondition(PolicyCondition condition, AccessContext context) {
String maxRiskLevel = (String) condition.parameters().get("max_risk_level");
if (maxRiskLevel != null) {
String currentRiskLevel = context.identity().authContext().riskLevel().name();
if (currentRiskLevel.compareTo(maxRiskLevel) > 0) {
return false;
}
}
return true;
}
private boolean evaluateRoleCondition(PolicyCondition condition, AccessContext context) {
String requiredRole = (String) condition.parameters().get("required_role");
if (requiredRole != null) {
// This would check against user roles from identity provider
// For now, return true as a placeholder
return true;
}
return true;
}
private void initializeDefaultPolicies() {
// Default deny-all policy
AccessPolicy denyAllPolicy = new AccessPolicy(
"DENY_ALL",
"Default deny all access",
Set.of("ALL"),
Set.of("ALL"),
Set.of("ALL"),
Set.of(new PolicyCondition(
ConditionType.ALWAYS_DENY,
"Always deny access",
Map.of()
)),
Decision.DENY
);
policies.put(denyAllPolicy.id(), denyAllPolicy);
// Example: Working hours policy
AccessPolicy workingHoursPolicy = new AccessPolicy(
"WORKING_HOURS",
"Allow access only during working hours

Java Logistics, Shipping Integration & Enterprise Inventory Automation (Tracking, ERP, RFID & Billing Systems)

https://macronepal.com/blog/aftership-tracking-in-java-enterprise-package-visibility/
Explains how to integrate AfterShip tracking services into Java applications to provide real-time shipment visibility, delivery status updates, and centralized tracking across multiple courier services.

https://macronepal.com/blog/shipping-integration-using-fedex-api-with-java-for-logistics-automation/
Explains how to integrate the FedEx API into Java systems to automate shipping tasks such as creating shipments, calculating delivery costs, generating shipping labels, and tracking packages.

https://macronepal.com/blog/shipping-and-logistics-integrating-ups-apis-with-java-applications/
Explains UPS API integration in Java to enable automated shipping operations including rate calculation, shipment scheduling, tracking, and delivery confirmation management.

https://macronepal.com/blog/generating-and-reading-qr-codes-for-products-in-java/
Explains how Java applications generate and read QR codes for product identification, tracking, and authentication, supporting faster inventory handling and product verification processes.

https://macronepal.com/blog/designing-a-robust-pick-and-pack-workflow-in-java/
Explains how to design an efficient pick-and-pack workflow in Java warehouse systems, covering order processing, item selection, packaging steps, and logistics preparation to improve fulfillment efficiency.

https://macronepal.com/blog/rfid-inventory-management-system-in-java-a-complete-guide/
Explains how RFID technology integrates with Java applications to automate inventory tracking, reduce manual errors, and enable real-time stock monitoring in warehouses and retail environments.

https://macronepal.com/blog/erp-integration-with-odoo-in-java/
Explains how Java applications connect with Odoo ERP systems to synchronize inventory, orders, customer records, and financial data across enterprise systems.

https://macronepal.com/blog/automated-invoice-generation-creating-professional-excel-invoices-with-apache-poi-in-java/
Explains how to automatically generate professional Excel invoices in Java using Apache POI, enabling structured billing documents and automated financial record creation.

https://macronepal.com/blog/enterprise-financial-integration-using-quickbooks-api-in-java-applications/
Explains QuickBooks API integration in Java to automate financial workflows such as invoice management, payment tracking, accounting synchronization, and financial reporting.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper