Introduction to GCP Confidential Computing
Google Cloud Platform (GCP) Confidential Computing provides hardware-based memory encryption and isolation using AMD SEV-SNP and Intel TDX technologies. This enables processing of sensitive data in memory without exposing it to the host system, cloud provider, or other tenants.
System Architecture Overview
GCP Confidential Computing Stack ├── Hardware Security │ ├ - AMD SEV-SNP (Secure Encrypted Virtualization) │ ├ - Intel TDX (Trust Domain Extensions) │ └ - AMD SEV-ES (Encrypted State) ├── GCP Services │ ├ - Confidential VMs │ ├ - Confidential GKE Nodes │ ├ - Confidential Space │ └ - Confidential Computing Attestation ├── Java Integration │ ├ - Enclave Runtime │ ├ - Attestation Verification │ └ - Secure Channel Setup └── Application Security ├ - Data-in-Use Protection ├ - Secure Key Management └ - Trusted Execution Environments
Core Implementation
1. Maven Dependencies
<properties>
<google.cloud.version>2.34.0</google.cloud.version>
<grpc.version>1.61.1</grpc.version>
<protobuf.version>3.25.1</protobuf.version>
<tink.version>1.12.0</tink.version>
</properties>
<dependencies>
<!-- Google Cloud Confidential Computing -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-confidentialcomputing</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Google Cloud KMS -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-kms</artifactId>
<version>${google.cloud.version}</version>
</dependency>
<!-- Google Cloud Secret Manager -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-secret-manager</artifactId>
<version>${google.cloud.version}</version>
</dependency>
<!-- Tink Cryptography -->
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>${tink.version}</version>
</dependency>
<!-- gRPC for attestation service -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- Enclave SDK (for Intel SGX/AMD SEV) -->
<dependency>
<groupId>com.intel.sgx</groupId>
<artifactId>sgx-sdk</artifactId>
<version>2.19</version>
</dependency>
<!-- Open Enclave (for cross-platform) -->
<dependency>
<groupId>com.microsoft.openenclave</groupId>
<artifactId>openenclave-java</artifactId>
<version>0.19.0</version>
</dependency>
<!-- Asynchronous operations -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.5.11</version>
</dependency>
<!-- Secure logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
2. Confidential VM Configuration Service
package com.gcp.confidential;
import com.google.cloud.confidentialcomputing.v1.*;
import com.google.cloud.kms.v1.*;
import com.google.cloud.secretmanager.v1.*;
import com.google.protobuf.ByteString;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.nio.file.*;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.*;
@Service
public class ConfidentialComputingService {
private static final Logger logger = LoggerFactory.getLogger(ConfidentialComputingService.class);
// GCP Service endpoints
private static final String ATTESTATION_SERVICE = "confidentialcomputing.googleapis.com:443";
private static final String KMS_SERVICE = "cloudkms.googleapis.com:443";
// TEE Types
public enum TEEType {
AMD_SEV_SNP,
INTEL_TDX,
AMD_SEV_ES,
INTEL_SGX
}
private final ConfidentialComputingClient ccClient;
private final KeyManagementServiceClient kmsClient;
private final SecretManagerServiceClient secretClient;
private final SecureRandom secureRandom;
private final Map<String, EnclaveSession> activeSessions = new ConcurrentHashMap<>();
private final Map<String, AttestationResult> attestationCache = new ConcurrentHashMap<>();
public ConfidentialComputingService() throws Exception {
// Initialize GCP clients
this.ccClient = ConfidentialComputingClient.create();
this.kmsClient = KeyManagementServiceClient.create();
this.secretClient = SecretManagerServiceClient.create();
// Initialize secure random
this.secureRandom = SecureRandom.getInstanceStrong();
logger.info("Confidential Computing Service initialized");
}
/**
* Verify TEE attestation
*/
public AttestationResult verifyAttestation(String challenge,
String teeEvidence,
TEEType teeType)
throws ConfidentialException {
try {
// Build attestation request
VerifyAttestationRequest request = VerifyAttestationRequest.newBuilder()
.setChallenge(ByteString.copyFromUtf8(challenge))
.setGcpCredentials(createGcpCredentials())
.setTeeEvidence(teeEvidence)
.setConfidentialSpaceInfo(buildConfidentialSpaceInfo())
.build();
// Call attestation service
VerifyAttestationResponse response = ccClient.verifyAttestation(request);
// Process response
AttestationResult result = processAttestationResponse(response);
// Cache result
attestationCache.put(challenge, result);
logger.info("Attestation verified successfully for TEE: {}", teeType);
return result;
} catch (Exception e) {
throw new ConfidentialException("Attestation verification failed", e);
}
}
/**
* Create Confidential VM instance
*/
public ConfidentialVM createConfidentialVM(VMConfig config)
throws ConfidentialException {
try {
// Generate attestation challenge
String challenge = generateAttestationChallenge();
// Create VM with confidential computing features
ComputeEngineConfig vmConfig = buildVMConfig(config);
// Enable AMD SEV-SNP or Intel TDX
enableConfidentialFeatures(vmConfig, config.getTeeType());
// Attach shielded instance config
applyShieldedInstanceConfig(vmConfig);
// Create the VM
ConfidentialVM vm = createVMInstance(vmConfig);
// Store attestation challenge
vm.setAttestationChallenge(challenge);
logger.info("Created Confidential VM: {}", vm.getInstanceId());
return vm;
} catch (Exception e) {
throw new ConfidentialException("Failed to create Confidential VM", e);
}
}
/**
* Setup secure enclave session
*/
public EnclaveSession createEnclaveSession(String sessionId,
EnclaveConfig config)
throws ConfidentialException {
try {
// Generate session key
SecretKey sessionKey = generateSessionKey();
// Create secure channel
SecureChannel channel = createSecureChannel(config, sessionKey);
// Perform mutual attestation
MutualAttestation attestation = performMutualAttestation(channel, config);
// Create enclave session
EnclaveSession session = new EnclaveSession(
sessionId, channel, attestation, sessionKey
);
// Store session
activeSessions.put(sessionId, session);
logger.info("Created enclave session: {}", sessionId);
return session;
} catch (Exception e) {
throw new ConfidentialException("Failed to create enclave session", e);
}
}
/**
* Encrypt data for confidential processing
*/
public ConfidentialData encryptForConfidentialProcessing(byte[] plaintext,
String keyId,
Map<String, String> context)
throws ConfidentialException {
try {
// Get encryption key from KMS
SecretKey encryptionKey = getEncryptionKey(keyId);
// Generate initialization vector
byte[] iv = generateIV();
// Encrypt data
byte[] ciphertext = encryptData(plaintext, encryptionKey, iv, context);
// Create metadata
EncryptionMetadata metadata = createEncryptionMetadata(keyId, iv, context);
return new ConfidentialData(ciphertext, metadata);
} catch (Exception e) {
throw new ConfidentialException("Data encryption failed", e);
}
}
/**
* Decrypt data after confidential processing
*/
public byte[] decryptAfterConfidentialProcessing(ConfidentialData confidentialData)
throws ConfidentialException {
try {
EncryptionMetadata metadata = confidentialData.getMetadata();
// Get decryption key from KMS
SecretKey decryptionKey = getDecryptionKey(metadata.getKeyId());
// Verify attestation context
verifyDecryptionContext(metadata);
// Decrypt data
return decryptData(
confidentialData.getCiphertext(),
decryptionKey,
metadata.getIv(),
metadata.getContext()
);
} catch (Exception e) {
throw new ConfidentialException("Data decryption failed", e);
}
}
/**
* Execute confidential computation
*/
public ComputationResult executeConfidentialComputation(
String sessionId,
byte[] encryptedInput,
ComputationTask task)
throws ConfidentialException {
EnclaveSession session = activeSessions.get(sessionId);
if (session == null) {
throw new ConfidentialException("Session not found: " + sessionId);
}
try {
// Send encrypted input to enclave
byte[] encryptedOutput = sendToEnclave(
session, encryptedInput, task
);
// Verify computation attestation
verifyComputationAttestation(session, task, encryptedOutput);
// Return result
return new ComputationResult(encryptedOutput, session.getAttestation());
} catch (Exception e) {
throw new ConfidentialException("Confidential computation failed", e);
}
}
/**
* Setup confidential storage
*/
public ConfidentialStorage setupConfidentialStorage(StorageConfig config)
throws ConfidentialException {
try {
// Create encrypted storage volume
StorageVolume volume = createEncryptedVolume(config);
// Generate storage keys
StorageKeys keys = generateStorageKeys(config);
// Configure access policies
AccessPolicy policy = configureAccessPolicies(config);
// Mount encrypted volume
mountEncryptedVolume(volume, keys);
return new ConfidentialStorage(volume, keys, policy);
} catch (Exception e) {
throw new ConfidentialException("Failed to setup confidential storage", e);
}
}
/**
* Monitor confidential computing metrics
*/
public ConfidentialMetrics getConfidentialMetrics()
throws ConfidentialException {
try {
ConfidentialMetrics metrics = new ConfidentialMetrics();
// Get TEE health status
metrics.setTeeHealthStatus(getTEEHealthStatus());
// Get memory encryption status
metrics.setMemoryEncryptionStatus(getMemoryEncryptionStatus());
// Get attestation metrics
metrics.setAttestationMetrics(getAttestationMetrics());
// Get performance metrics
metrics.setPerformanceMetrics(getPerformanceMetrics());
// Get security events
metrics.setSecurityEvents(getSecurityEvents());
return metrics;
} catch (Exception e) {
throw new ConfidentialException("Failed to get confidential metrics", e);
}
}
/**
* Generate key in Cloud KMS with confidential protection
*/
public CryptoKey createConfidentialKey(String keyRingId,
String keyId,
KeyProtectionLevel protectionLevel)
throws ConfidentialException {
try {
// Create crypto key with specific protection level
CryptoKey key = CryptoKey.newBuilder()
.setPurpose(CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT)
.setVersionTemplate(CryptoKeyVersionTemplate.newBuilder()
.setProtectionLevel(mapProtectionLevel(protectionLevel))
.setAlgorithm(CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION)
.build())
.putLabels("confidential", "true")
.build();
// Create key in KMS
CryptoKey createdKey = kmsClient.createCryptoKey(
keyRingId, keyId, key
);
// Configure IAM policy for confidential access
configureConfidentialKeyPolicy(createdKey);
logger.info("Created confidential key: {}", keyId);
return createdKey;
} catch (Exception e) {
throw new ConfidentialException("Failed to create confidential key", e);
}
}
/**
* Perform remote attestation with GCP service
*/
public RemoteAttestation performRemoteAttestation(AttestationRequest request)
throws ConfidentialException {
try {
// Generate nonce for freshness
byte[] nonce = generateNonce(32);
// Collect platform evidence
PlatformEvidence evidence = collectPlatformEvidence(request.getTeeType());
// Build attestation document
AttestationDocument document = buildAttestationDocument(evidence, nonce);
// Send to GCP attestation service
RemoteAttestation attestation = sendToAttestationService(document);
// Verify service response
verifyAttestationResponse(attestation, nonce);
return attestation;
} catch (Exception e) {
throw new ConfidentialException("Remote attestation failed", e);
}
}
/**
* Secure memory allocation for confidential data
*/
public SecureMemory allocateSecureMemory(long size, MemoryProtection protection)
throws ConfidentialException {
try {
// Allocate encrypted memory region
MemoryRegion region = allocateEncryptedMemory(size);
// Set memory protection
setMemoryProtection(region, protection);
// Generate encryption key for this memory region
SecretKey memoryKey = generateMemoryEncryptionKey();
// Configure memory encryption
configureMemoryEncryption(region, memoryKey);
return new SecureMemory(region, memoryKey, protection);
} catch (Exception e) {
throw new ConfidentialException("Failed to allocate secure memory", e);
}
}
// Helper methods
private String generateAttestationChallenge() {
byte[] challenge = new byte[32];
secureRandom.nextBytes(challenge);
return Base64.getEncoder().encodeToString(challenge);
}
private SecretKey generateSessionKey() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
return keyGen.generateKey();
}
private byte[] generateIV() {
byte[] iv = new byte[12]; // 96 bits for GCM
secureRandom.nextBytes(iv);
return iv;
}
private byte[] encryptData(byte[] plaintext, SecretKey key,
byte[] iv, Map<String, String> context)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
// Add associated data for authentication
if (context != null) {
byte[] aad = serializeContext(context);
cipher.updateAAD(aad);
}
return cipher.doFinal(plaintext);
}
private byte[] decryptData(byte[] ciphertext, SecretKey key,
byte[] iv, Map<String, String> context)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
// Add associated data for authentication
if (context != null) {
byte[] aad = serializeContext(context);
cipher.updateAAD(aad);
}
return cipher.doFinal(ciphertext);
}
private byte[] serializeContext(Map<String, String> context) {
// Simple serialization - in production use Protobuf or similar
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : context.entrySet()) {
sb.append(entry.getKey()).append(":").append(entry.getValue()).append(";");
}
return sb.toString().getBytes();
}
private void verifyDecryptionContext(EncryptionMetadata metadata)
throws ConfidentialException {
// Check if the context matches expected values
Map<String, String> context = metadata.getContext();
// Verify attestation token if present
if (context.containsKey("attestation_token")) {
String token = context.get("attestation_token");
if (!attestationCache.containsKey(token)) {
throw new ConfidentialException("Invalid attestation context");
}
}
// Check timestamp for freshness
if (context.containsKey("timestamp")) {
long timestamp = Long.parseLong(context.get("timestamp"));
long currentTime = System.currentTimeMillis();
if (currentTime - timestamp > 300000) { // 5 minutes
throw new ConfidentialException("Decryption context expired");
}
}
}
// Data classes
public static class ConfidentialVM {
private String instanceId;
private TEEType teeType;
private String attestationChallenge;
private Map<String, String> confidentialFeatures;
private Date creationTime;
// getters and setters
}
public static class EnclaveSession {
private final String sessionId;
private final SecureChannel channel;
private final MutualAttestation attestation;
private final SecretKey sessionKey;
private final Date creationTime;
private volatile boolean active;
public EnclaveSession(String sessionId, SecureChannel channel,
MutualAttestation attestation, SecretKey sessionKey) {
this.sessionId = sessionId;
this.channel = channel;
this.attestation = attestation;
this.sessionKey = sessionKey;
this.creationTime = new Date();
this.active = true;
}
// getters
}
public static class ConfidentialData {
private final byte[] ciphertext;
private final EncryptionMetadata metadata;
public ConfidentialData(byte[] ciphertext, EncryptionMetadata metadata) {
this.ciphertext = ciphertext;
this.metadata = metadata;
}
// getters
}
public static class EncryptionMetadata {
private String keyId;
private byte[] iv;
private Map<String, String> context;
private Date encryptionTime;
// getters and setters
}
public static class AttestationResult {
private boolean verified;
private TEEType teeType;
private String measurement;
private X509Certificate attestationCertificate;
private Date verificationTime;
// getters and setters
}
public static class ConfidentialException extends Exception {
public ConfidentialException(String message) { super(message); }
public ConfidentialException(String message, Throwable cause) {
super(message, cause);
}
}
public enum KeyProtectionLevel {
SOFTWARE,
HSM,
EXTERNAL,
EXTERNAL_VPC
}
public enum MemoryProtection {
READ_ONLY,
READ_WRITE,
EXECUTE_ONLY,
NO_ACCESS
}
}
3. Attestation Service Integration
package com.gcp.confidential.attestation;
import com.google.cloud.confidentialcomputing.v1.*;
import com.google.protobuf.ByteString;
import io.grpc.*;
import org.springframework.stereotype.Service;
import java.security.*;
import java.security.cert.*;
import java.util.*;
@Service
public class AttestationService {
private final ConfidentialComputingClient ccClient;
private final KeyStore trustStore;
public AttestationService() throws Exception {
this.ccClient = ConfidentialComputingClient.create();
this.trustStore = loadTrustStore();
}
/**
* Generate attestation challenge
*/
public AttestationChallenge generateChallenge(String workloadId) {
byte[] nonce = new byte[32];
new SecureRandom().nextBytes(nonce);
return AttestationChallenge.newBuilder()
.setNonce(ByteString.copyFrom(nonce))
.setWorkloadId(workloadId)
.setTimestamp(System.currentTimeMillis())
.build();
}
/**
* Verify AMD SEV-SNP attestation
*/
public SnpAttestationResult verifySnpAttestation(String attestationReport,
String vcekCert,
AttestationChallenge challenge)
throws AttestationException {
try {
// Parse SNP attestation report
SnpAttestationReport report = parseSnpReport(attestationReport);
// Verify VCEK certificate chain
verifyVcekCertificateChain(vcekCert);
// Verify report signature
verifyReportSignature(report, vcekCert);
// Verify report measurements
verifyReportMeasurements(report, challenge);
// Check TCB version
verifyTcbVersion(report);
return new SnpAttestationResult(report, true);
} catch (Exception e) {
throw new AttestationException("SEV-SNP attestation failed", e);
}
}
/**
* Verify Intel TDX attestation
*/
public TdxAttestationResult verifyTdxAttestation(String quote,
String pckCertChain,
AttestationChallenge challenge)
throws AttestationException {
try {
// Parse TDX quote
TdxQuote tdxQuote = parseTdxQuote(quote);
// Verify PCK certificate chain
verifyPckCertificateChain(pckCertChain);
// Verify quote signature
verifyQuoteSignature(tdxQuote, pckCertChain);
// Verify quote measurements
verifyQuoteMeasurements(tdxQuote, challenge);
// Verify TDX module attributes
verifyTdxAttributes(tdxQuote);
return new TdxAttestationResult(tdxQuote, true);
} catch (Exception e) {
throw new AttestationException("TDX attestation failed", e);
}
}
/**
* Perform GCP Confidential Space attestation
*/
public ConfidentialSpaceAttestation verifyConfidentialSpace(
String containerImageDigest,
String kmsKeyName,
AttestationChallenge challenge)
throws AttestationException {
try {
// Build Confidential Space request
ConfidentialSpaceInfo spaceInfo = ConfidentialSpaceInfo.newBuilder()
.setContainerImageDigest(containerImageDigest)
.setKmsKeyName(kmsKeyName)
.build();
// Create attestation request
VerifyAttestationRequest request = VerifyAttestationRequest.newBuilder()
.setChallenge(ByteString.copyFrom(challenge.getNonce().toByteArray()))
.setConfidentialSpaceInfo(spaceInfo)
.build();
// Call GCP service
VerifyAttestationResponse response = ccClient.verifyAttestation(request);
// Parse response
return parseConfidentialSpaceResponse(response);
} catch (Exception e) {
throw new AttestationException("Confidential Space attestation failed", e);
}
}
/**
* Verify attestation token from GCP service
*/
public TokenVerificationResult verifyAttestationToken(String token,
String expectedAudience)
throws AttestationException {
try {
// Parse JWT token
AttestationToken attestationToken = parseAttestationToken(token);
// Verify signature
verifyTokenSignature(attestationToken);
// Verify claims
verifyTokenClaims(attestationToken, expectedAudience);
// Check token expiration
verifyTokenExpiration(attestationToken);
// Extract TEE evidence
TeeEvidence evidence = extractTeeEvidence(attestationToken);
return new TokenVerificationResult(attestationToken, evidence, true);
} catch (Exception e) {
throw new AttestationException("Token verification failed", e);
}
}
/**
* Build attestation policy
*/
public AttestationPolicy buildAttestationPolicy(PolicyConfig config) {
return AttestationPolicy.newBuilder()
.setMinimumTcbVersion(config.getMinimumTcbVersion())
.setAllowedMeasurements(config.getAllowedMeasurements())
.setRequireFreshAttestation(config.isRequireFreshAttestation())
.setMaximumAttestationAge(config.getMaximumAttestationAge())
.setAllowedTeeTypes(config.getAllowedTeeTypes())
.build();
}
/**
* Validate attestation against policy
*/
public PolicyValidation validateAgainstPolicy(AttestationResult result,
AttestationPolicy policy) {
PolicyValidation validation = new PolicyValidation();
// Check TEE type
if (!policy.getAllowedTeeTypes().contains(result.getTeeType())) {
validation.addViolation("TEE type not allowed: " + result.getTeeType());
}
// Check TCB version
if (result.getTcbVersion() < policy.getMinimumTcbVersion()) {
validation.addViolation("TCB version too low: " + result.getTcbVersion());
}
// Check measurement
if (!policy.getAllowedMeasurements().contains(result.getMeasurement())) {
validation.addViolation("Measurement not allowed: " + result.getMeasurement());
}
// Check attestation age
if (policy.isRequireFreshAttestation()) {
long age = System.currentTimeMillis() - result.getTimestamp();
if (age > policy.getMaximumAttestationAge()) {
validation.addViolation("Attestation too old: " + age + "ms");
}
}
validation.setValid(validation.getViolations().isEmpty());
return validation;
}
private KeyStore loadTrustStore() throws Exception {
KeyStore ks = KeyStore.getInstance("PKCS12");
// Load GCP CA certificates
try (InputStream is = getClass().getResourceAsStream("/gcp-ca.p12")) {
ks.load(is, "changeit".toCharArray());
}
// Load AMD/Intel root certificates
loadVendorCertificates(ks);
return ks;
}
private void verifyVcekCertificateChain(String vcekCert)
throws CertificateException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, KeyStoreException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)
cf.generateCertificate(new ByteArrayInputStream(vcekCert.getBytes()));
// Build certificate chain
CertPath certPath = cf.generateCertPath(Arrays.asList(certificate));
// Validate chain
PKIXParameters params = new PKIXParameters(trustStore);
params.setRevocationEnabled(false); // OCSP not available in TEE
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
validator.validate(certPath, params);
}
// Data classes
public static class SnpAttestationReport {
private byte[] reportData;
private byte[] measurement;
private long tcbVersion;
private byte[] signature;
private Map<String, Object> attributes;
// getters and setters
}
public static class TdxQuote {
private byte[] reportData;
private byte[] mrEnclave;
private byte[] mrSigner;
private long tdxModuleAttributes;
private byte[] signature;
// getters and setters
}
public static class AttestationChallenge {
private ByteString nonce;
private String workloadId;
private long timestamp;
// getters and setters
}
public static class AttestationException extends Exception {
public AttestationException(String message) { super(message); }
public AttestationException(String message, Throwable cause) {
super(message, cause);
}
}
}
4. Secure Enclave Runtime
package com.gcp.confidential.enclave;
import com.google.crypto.tink.*;
import com.google.crypto.tink.aead.AeadConfig;
import com.google.crypto.tink.signature.SignatureConfig;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.*;
import java.util.*;
@Service
public class EnclaveRuntime {
static {
try {
// Initialize Tink
AeadConfig.register();
SignatureConfig.register();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Failed to initialize Tink", e);
}
}
private final Map<String, EnclaveInstance> enclaves = new ConcurrentHashMap<>();
private final SecureRandom secureRandom = new SecureRandom();
/**
* Create Java enclave instance
*/
public EnclaveInstance createJavaEnclave(EnclaveManifest manifest)
throws EnclaveException {
try {
String enclaveId = UUID.randomUUID().toString();
// Create secure classloader
SecureClassLoader classLoader = createSecureClassLoader(manifest);
// Load enclave class
Class<?> enclaveClass = classLoader.loadClass(manifest.getMainClass());
// Create enclave instance
Object enclaveInstance = enclaveClass.getDeclaredConstructor().newInstance();
// Generate enclave keys
KeyPair attestationKey = generateAttestationKeyPair();
KeysetHandle sealingKey = generateSealingKey();
// Create enclave instance
EnclaveInstance instance = new EnclaveInstance(
enclaveId, enclaveInstance, attestationKey, sealingKey, manifest
);
// Initialize enclave
initializeEnclave(instance);
enclaves.put(enclaveId, instance);
logger.info("Created Java enclave: {}", enclaveId);
return instance;
} catch (Exception e) {
throw new EnclaveException("Failed to create enclave", e);
}
}
/**
* Execute method inside enclave
*/
public EnclaveResponse executeInEnclave(String enclaveId,
String methodName,
Class<?>[] parameterTypes,
Object[] args)
throws EnclaveException {
EnclaveInstance enclave = enclaves.get(enclaveId);
if (enclave == null) {
throw new EnclaveException("Enclave not found: " + enclaveId);
}
try {
// Seal input data
byte[] sealedInput = sealData(args, enclave.getSealingKey());
// Get method
Method method = enclave.getInstance().getClass()
.getMethod(methodName, parameterTypes);
// Verify method is allowed
verifyMethodAccess(method, enclave.getManifest());
// Execute method
Object result = method.invoke(enclave.getInstance(), args);
// Seal output data
byte[] sealedOutput = sealData(new Object[]{result}, enclave.getSealingKey());
// Generate execution proof
ExecutionProof proof = generateExecutionProof(
enclaveId, methodName, sealedInput, sealedOutput
);
return new EnclaveResponse(sealedOutput, proof);
} catch (Exception e) {
throw new EnclaveException("Enclave execution failed", e);
}
}
/**
* Generate enclave attestation
*/
public EnclaveAttestation generateAttestation(String enclaveId,
byte[] challenge)
throws EnclaveException {
EnclaveInstance enclave = enclaves.get(enclaveId);
if (enclave == null) {
throw new EnclaveException("Enclave not found: " + enclaveId);
}
try {
// Get enclave measurement
byte[] measurement = calculateEnclaveMeasurement(enclave);
// Sign challenge with enclave key
byte[] signature = signWithEnclaveKey(challenge, enclave.getAttestationKey());
// Build attestation
return EnclaveAttestation.newBuilder()
.setEnclaveId(enclaveId)
.setMeasurement(ByteString.copyFrom(measurement))
.setChallenge(ByteString.copyFrom(challenge))
.setSignature(ByteString.copyFrom(signature))
.setPublicKey(ByteString.copyFrom(
enclave.getAttestationKey().getPublic().getEncoded()))
.setTimestamp(System.currentTimeMillis())
.build();
} catch (Exception e) {
throw new EnclaveException("Failed to generate attestation", e);
}
}
/**
* Seal data for enclave storage
*/
public byte[] sealData(Object data, KeysetHandle sealingKey)
throws EnclaveException {
try {
// Serialize data
byte[] serialized = serializeData(data);
// Encrypt with sealing key
Aead aead = sealingKey.getPrimitive(Aead.class);
byte[] associatedData = "enclave-data".getBytes();
return aead.encrypt(serialized, associatedData);
} catch (Exception e) {
throw new EnclaveException("Failed to seal data", e);
}
}
/**
* Unseal data from enclave storage
*/
public Object unsealData(byte[] sealedData, KeysetHandle sealingKey)
throws EnclaveException {
try {
// Decrypt with sealing key
Aead aead = sealingKey.getPrimitive(Aead.class);
byte[] associatedData = "enclave-data".getBytes();
byte[] decrypted = aead.decrypt(sealedData, associatedData);
// Deserialize data
return deserializeData(decrypted);
} catch (Exception e) {
throw new EnclaveException("Failed to unseal data", e);
}
}
/**
* Create secure memory region
*/
public SecureMemoryRegion allocateSecureMemory(long size)
throws EnclaveException {
try {
// Allocate direct byte buffer
ByteBuffer buffer = ByteBuffer.allocateDirect((int) size);
// Lock memory to prevent swapping
lockMemory(buffer);
// Generate encryption key for this region
SecretKey encryptionKey = generateMemoryEncryptionKey();
// Configure memory encryption (if hardware supports)
configureMemoryEncryption(buffer, encryptionKey);
return new SecureMemoryRegion(buffer, encryptionKey);
} catch (Exception e) {
throw new EnclaveException("Failed to allocate secure memory", e);
}
}
/**
* Perform remote attestation
*/
public RemoteAttestation performRemoteAttestation(String enclaveId,
String verifierUrl)
throws EnclaveException {
try {
// Generate attestation quote
byte[] quote = generateAttestationQuote(enclaveId);
// Send to verifier
RemoteAttestation attestation = sendToVerifier(verifierUrl, quote);
// Verify response
verifyAttestationResponse(attestation);
return attestation;
} catch (Exception e) {
throw new EnclaveException("Remote attestation failed", e);
}
}
private SecureClassLoader createSecureClassLoader(EnclaveManifest manifest)
throws Exception {
// Create URLClassLoader with security restrictions
URL[] urls = manifest.getClasspathUrls().stream()
.map(File::new)
.map(File::toURI)
.map(uri -> {
try {
return uri.toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
})
.toArray(URL[]::new);
return new SecureClassLoader(ClassLoader.getSystemClassLoader()) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// Implement secure class loading
return super.findClass(name);
}
@Override
protected PermissionCollection getPermissions(CodeSource codesource) {
Permissions permissions = new Permissions();
// Grant minimal permissions
permissions.add(new RuntimePermission("exitVM"));
permissions.add(new SocketPermission("localhost:0", "listen,resolve"));
// Deny dangerous permissions
// No file access, no network access, no reflection, etc.
return permissions;
}
};
}
private KeyPair generateAttestationKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
return keyGen.generateKeyPair();
}
private KeysetHandle generateSealingKey() throws GeneralSecurityException {
return KeysetHandle.generateNew(
KeyTemplates.get("AES256_GCM_RAW")
);
}
private byte[] calculateEnclaveMeasurement(EnclaveInstance enclave)
throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
// Hash class files
for (Class<?> clazz : getEnclaveClasses(enclave)) {
digest.update(clazz.getName().getBytes());
// Add class bytecode hash
}
// Hash manifest
digest.update(enclave.getManifest().toString().getBytes());
// Hash public key
digest.update(enclave.getAttestationKey().getPublic().getEncoded());
return digest.digest();
}
// Data classes
public static class EnclaveInstance {
private final String enclaveId;
private final Object instance;
private final KeyPair attestationKey;
private final KeysetHandle sealingKey;
private final EnclaveManifest manifest;
private final Date creationTime;
public EnclaveInstance(String enclaveId, Object instance,
KeyPair attestationKey, KeysetHandle sealingKey,
EnclaveManifest manifest) {
this.enclaveId = enclaveId;
this.instance = instance;
this.attestationKey = attestationKey;
this.sealingKey = sealingKey;
this.manifest = manifest;
this.creationTime = new Date();
}
// getters
}
public static class EnclaveManifest {
private String mainClass;
private List<File> classpathUrls;
private List<String> allowedMethods;
private Map<String, String> environment;
private ResourceLimits resourceLimits;
// getters and setters
}
public static class EnclaveResponse {
private byte[] sealedResult;
private ExecutionProof proof;
// constructor and getters
}
public static class EnclaveException extends Exception {
public EnclaveException(String message) { super(message); }
public EnclaveException(String message, Throwable cause) {
super(message, cause);
}
}
}
5. Confidential Kubernetes Integration
package com.gcp.confidential.kubernetes;
import io.kubernetes.client.openapi.*;
import io.kubernetes.client.openapi.apis.*;
import io.kubernetes.client.openapi.models.*;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class ConfidentialKubernetesService {
private final CoreV1Api coreApi;
private final AppsV1Api appsApi;
private final BatchV1Api batchApi;
public ConfidentialKubernetesService() throws Exception {
// Load Kubernetes configuration
ApiClient client = Config.defaultClient();
Configuration.setDefaultApiClient(client);
this.coreApi = new CoreV1Api();
this.appsApi = new AppsV1Api();
this.batchApi = new BatchV1Api();
}
/**
* Create Confidential GKE Node Pool
*/
public V1NodePool createConfidentialNodePool(String clusterId,
NodePoolConfig config)
throws KubernetesException {
try {
// Build node config with confidential computing
V1NodeConfig nodeConfig = new V1NodeConfig()
.addBootDiskKmsKeyRefItem(config.getBootDiskKmsKey())
.setConfidentialNodes(new V1ConfidentialNodes()
.enabled(true))
.setShieldedInstanceConfig(new V1ShieldedInstanceConfig()
.enableSecureBoot(true)
.enableVtpm(true)
.enableIntegrityMonitoring(true));
// Create node pool
V1NodePool nodePool = new V1NodePool()
.name(config.getName())
.initialNodeCount(config.getNodeCount())
.config(nodeConfig)
.addLocationsItem(config.getZone())
.addAcceleratorsItem(new V1AcceleratorConfig()
.acceleratorCount(1)
.acceleratorType("nvidia-tesla-t4"));
// Call GKE API
V1Operation operation = gkeApi.createNodePool(
clusterId, config.getZone(), nodePool
);
// Wait for completion
waitForOperation(operation);
logger.info("Created confidential node pool: {}", config.getName());
return nodePool;
} catch (Exception e) {
throw new KubernetesException("Failed to create node pool", e);
}
}
/**
* Deploy confidential workload
*/
public V1Deployment deployConfidentialWorkload(String namespace,
WorkloadConfig config)
throws KubernetesException {
try {
// Build confidential container
V1Container container = buildConfidentialContainer(config);
// Create pod spec with security context
V1PodSpec podSpec = new V1PodSpec()
.addContainersItem(container)
.securityContext(new V1PodSecurityContext()
.runAsNonRoot(true)
.runAsUser(1000L)
.runAsGroup(1000L)
.seLinuxOptions(new V1SELinuxOptions()
.level("s0:c123,c456")));
// Create deployment
V1Deployment deployment = new V1Deployment()
.metadata(new V1ObjectMeta()
.name(config.getName())
.namespace(namespace))
.spec(new V1DeploymentSpec()
.replicas(config.getReplicas())
.selector(new V1LabelSelector()
.addMatchLabelsItem("app", config.getName()))
.template(new V1PodTemplateSpec()
.metadata(new V1ObjectMeta()
.addLabelsItem("app", config.getName()))
.spec(podSpec)));
// Create deployment
return appsApi.createNamespacedDeployment(namespace, deployment, null, null, null);
} catch (Exception e) {
throw new KubernetesException("Failed to deploy workload", e);
}
}
/**
* Create confidential job
*/
public V1Job createConfidentialJob(String namespace,
JobConfig config)
throws KubernetesException {
try {
// Build job spec
V1JobSpec jobSpec = new V1JobSpec()
.template(new V1PodTemplateSpec()
.spec(new V1PodSpec()
.addContainersItem(buildConfidentialContainer(config))
.restartPolicy("Never")
.securityContext(createSecurityContext(config))));
// Create job
V1Job job = new V1Job()
.metadata(new V1ObjectMeta()
.name(config.getName())
.namespace(namespace))
.spec(jobSpec);
return batchApi.createNamespacedJob(namespace, job, null, null, null);
} catch (Exception e) {
throw new KubernetesException("Failed to create job", e);
}
}
/**
* Setup confidential storage class
*/
public V1StorageClass createConfidentialStorageClass(StorageClassConfig config)
throws KubernetesException {
try {
// Create storage class with encryption
V1StorageClass storageClass = new V1StorageClass()
.metadata(new V1ObjectMeta()
.name(config.getName()))
.provisioner(config.getProvisioner())
.parameters(Map.of(
"type", "pd-ssd",
"disk-encryption-kms-key", config.getKmsKey(),
"confidential-storage", "true"
))
.reclaimPolicy("Retain")
.volumeBindingMode("WaitForFirstConsumer");
return coreApi.createStorageClass(storageClass, null, null, null);
} catch (Exception e) {
throw new KubernetesException("Failed to create storage class", e);
}
}
/**
* Monitor confidential computing metrics
*/
public ConfidentialMetrics getConfidentialMetrics(String namespace)
throws KubernetesException {
try {
ConfidentialMetrics metrics = new ConfidentialMetrics();
// Get node metrics
metrics.setNodeMetrics(getNodeMetrics());
// Get pod metrics
metrics.setPodMetrics(getPodMetrics(namespace));
// Get attestation metrics
metrics.setAttestationMetrics(getAttestationMetrics());
// Get security events
metrics.setSecurityEvents(getSecurityEvents(namespace));
return metrics;
} catch (Exception e) {
throw new KubernetesException("Failed to get metrics", e);
}
}
private V1Container buildConfidentialContainer(WorkloadConfig config) {
return new V1Container()
.name(config.getName())
.image(config.getImage())
.imagePullPolicy("Always")
.ports(config.getPorts().stream()
.map(p -> new V1ContainerPort()
.containerPort(p))
.collect(Collectors.toList()))
.resources(new V1ResourceRequirements()
.requests(Map.of(
"cpu", config.getCpuRequest(),
"memory", config.getMemoryRequest()
))
.limits(Map.of(
"cpu", config.getCpuLimit(),
"memory", config.getMemoryLimit()
)))
.securityContext(new V1SecurityContext()
.privileged(false)
.allowPrivilegeEscalation(false)
.capabilities(new V1Capabilities()
.add(new V1Capability("ALL")))
.readOnlyRootFilesystem(true)
.runAsNonRoot(true)
.runAsUser(1000L)
.runAsGroup(1000L))
.env(config.getEnvironment().entrySet().stream()
.map(e -> new V1EnvVar()
.name(e.getKey())
.value(e.getValue()))
.collect(Collectors.toList()));
}
private V1PodSecurityContext createSecurityContext(JobConfig config) {
return new V1PodSecurityContext()
.runAsNonRoot(true)
.runAsUser(1000L)
.runAsGroup(1000L)
.fsGroup(1000L)
.seLinuxOptions(new V1SELinuxOptions()
.level("s0:c123,c456"))
.sysctls(List.of(
new V1Sysctl()
.name("kernel.unprivileged_bpf_disabled")
.value("1")
));
}
// Data classes
public static class NodePoolConfig {
private String name;
private int nodeCount;
private String zone;
private String bootDiskKmsKey;
private TEEType teeType;
// getters and setters
}
public static class WorkloadConfig {
private String name;
private String image;
private int replicas;
private List<Integer> ports;
private String cpuRequest;
private String memoryRequest;
private String cpuLimit;
private String memoryLimit;
private Map<String, String> environment;
// getters and setters
}
public static class KubernetesException extends Exception {
public KubernetesException(String message) { super(message); }
public KubernetesException(String message, Throwable cause) {
super(message, cause);
}
}
}
6. Secure Key Management
package com.gcp.confidential.kms;
import com.google.cloud.kms.v1.*;
import com.google.protobuf.ByteString;
import org.springframework.stereotype.Service;
import java.security.*;
import java.util.*;
@Service
public class SecureKeyManagementService {
private final KeyManagementServiceClient kmsClient;
private final Map<String, CryptoKey> keyCache = new ConcurrentHashMap<>();
public SecureKeyManagementService() throws Exception {
this.kmsClient = KeyManagementServiceClient.create();
}
/**
* Create key with confidential computing protection
*/
public CryptoKey createConfidentialKey(String keyRingId,
String keyId,
KeyProtection protection)
throws KMSException {
try {
// Build crypto key with protection level
CryptoKey key = CryptoKey.newBuilder()
.setPurpose(CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT)
.setVersionTemplate(CryptoKeyVersionTemplate.newBuilder()
.setProtectionLevel(mapProtectionLevel(protection))
.setAlgorithm(CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION)
.build())
.putLabels("confidential", "true")
.putLabels("protection-level", protection.name())
.build();
// Create key
CryptoKey createdKey = kmsClient.createCryptoKey(keyRingId, keyId, key);
// Configure IAM policy
configureKeyPolicy(createdKey, protection);
// Cache key
keyCache.put(getKeyName(keyRingId, keyId), createdKey);
logger.info("Created confidential key: {}", keyId);
return createdKey;
} catch (Exception e) {
throw new KMSException("Failed to create key", e);
}
}
/**
* Encrypt data using key with attestation binding
*/
public EncryptedData encryptWithAttestation(byte[] plaintext,
String keyName,
AttestationBinding binding)
throws KMSException {
try {
// Build encryption request with attestation
EncryptRequest request = EncryptRequest.newBuilder()
.setName(keyName)
.setPlaintext(ByteString.copyFrom(plaintext))
.setAdditionalAuthenticatedData(
ByteString.copyFromUtf8(binding.getAttestationToken()))
.build();
// Encrypt data
EncryptResponse response = kmsClient.encrypt(request);
// Create encrypted data object
return new EncryptedData(
response.getCiphertext().toByteArray(),
binding.getAttestationToken(),
response.getName()
);
} catch (Exception e) {
throw new KMSException("Encryption failed", e);
}
}
/**
* Decrypt data with attestation verification
*/
public byte[] decryptWithAttestationVerification(EncryptedData encryptedData,
String expectedAttestation)
throws KMSException {
try {
// Verify attestation token
if (!encryptedData.getAttestationToken().equals(expectedAttestation)) {
throw new KMSException("Attestation token mismatch");
}
// Build decryption request
DecryptRequest request = DecryptRequest.newBuilder()
.setName(encryptedData.getKeyName())
.setCiphertext(ByteString.copyFrom(encryptedData.getCiphertext()))
.setAdditionalAuthenticatedData(
ByteString.copyFromUtf8(encryptedData.getAttestationToken()))
.build();
// Decrypt data
DecryptResponse response = kmsClient.decrypt(request);
return response.getPlaintext().toByteArray();
} catch (Exception e) {
throw new KMSException("Decryption failed", e);
}
}
/**
* Generate key in Hardware Security Module (HSM)
*/
public HsmKey generateHsmKey(String keyRingId,
String keyId,
HsmConfig config)
throws KMSException {
try {
// Create HSM-protected key
CryptoKey key = CryptoKey.newBuilder()
.setPurpose(CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN)
.setVersionTemplate(CryptoKeyVersionTemplate.newBuilder()
.setProtectionLevel(ProtectionLevel.HSM)
.setAlgorithm(CryptoKeyVersion.CryptoKeyVersionAlgorithm.RSA_SIGN_PKCS1_2048_SHA256)
.build())
.putLabels("hsm", "true")
.putLabels("hsm-partition", config.getPartitionId())
.build();
CryptoKey createdKey = kmsClient.createCryptoKey(keyRingId, keyId, key);
// Get public key
CryptoKeyVersion version = kmsClient.getCryptoKeyVersion(
createdKey.getName() + "/cryptoKeyVersions/1"
);
PublicKey publicKey = extractPublicKey(version);
return new HsmKey(createdKey, publicKey, config);
} catch (Exception e) {
throw new KMSException("Failed to generate HSM key", e);
}
}
/**
* Rotate keys with zero downtime
*/
public KeyRotationResult rotateKey(String keyName,
RotationConfig config)
throws KMSException {
try {
// Create new key version
CryptoKeyVersion newVersion = createKeyVersion(keyName);
// Re-encrypt data with new key
ReencryptData(keyName, newVersion.getName());
// Update key rotation schedule
updateRotationSchedule(keyName, config);
// Disable old versions
disableOldVersions(keyName, config.getKeepPreviousVersions());
return new KeyRotationResult(newVersion, true);
} catch (Exception e) {
throw new KMSException("Key rotation failed", e);
}
}
/**
* Create key access policy
*/
public KeyAccessPolicy createAccessPolicy(String keyName,
PolicyConfig config)
throws KMSException {
try {
// Get current IAM policy
Policy policy = kmsClient.getIamPolicy(keyName);
// Add confidential computing conditions
for (Binding binding : policy.getBindingsList()) {
if (binding.getRole().equals("roles/cloudkms.cryptoKeyEncrypterDecrypter")) {
binding.setCondition(createConfidentialCondition(config));
}
}
// Update policy
kmsClient.setIamPolicy(keyName, policy);
return new KeyAccessPolicy(keyName, policy);
} catch (Exception e) {
throw new KMSException("Failed to create access policy", e);
}
}
private ProtectionLevel mapProtectionLevel(KeyProtection protection) {
switch (protection) {
case SOFTWARE:
return ProtectionLevel.SOFTWARE;
case HSM:
return ProtectionLevel.HSM;
case EXTERNAL:
return ProtectionLevel.EXTERNAL;
case EXTERNAL_VPC:
return ProtectionLevel.EXTERNAL_VPC;
default:
return ProtectionLevel.SOFTWARE;
}
}
private Expr createConfidentialCondition(PolicyConfig config) {
return Expr.newBuilder()
.setExpression(String.format(
"resource.name.startsWith('projects/%s/locations/%s') && " +
"request.time < timestamp('%s')",
config.getProjectId(),
config.getLocation(),
config.getExpirationTime()
))
.setTitle("Confidential Access Only")
.setDescription("Access allowed only from confidential VMs")
.build();
}
// Data classes
public enum KeyProtection {
SOFTWARE,
HSM,
EXTERNAL,
EXTERNAL_VPC
}
public static class AttestationBinding {
private String attestationToken;
private String teeType;
private String measurement;
// getters and setters
}
public static class EncryptedData {
private byte[] ciphertext;
private String attestationToken;
private String keyName;
// constructor and getters
}
public static class HsmConfig {
private String partitionId;
private String hsmCluster;
private List<String> allowedOperations;
// getters and setters
}
public static class KMSException extends Exception {
public KMSException(String message) { super(message); }
public KMSException(String message, Throwable cause) {
super(message, cause);
}
}
}
7. Terraform Configuration
# confidential-computing.tf
# Confidential VM Instance
resource "google_compute_instance" "confidential_vm" {
name = "confidential-vm"
machine_type = "n2d-standard-4"
zone = "us-central1-a"
# Enable confidential computing
confidential_instance_config {
enable_confidential_compute = true
}
# Shielded VM configuration
shielded_instance_config {
enable_secure_boot = true
enable_vtpm = true
enable_integrity_monitoring = true
}
# Boot disk with customer-managed encryption
boot_disk {
initialize_params {
image = "projects/ubuntu-os-cloud/global/images/ubuntu-2204-lts"
type = "pd-ssd"
size = 100
}
kms_key_self_link = google_kms_crypto_key.boot_disk_key.id
}
# Network interface
network_interface {
network = "default"
# Enable confidential computing for network
access_config {
// Ephemeral IP
}
}
# Service account with minimal permissions
service_account {
email = google_service_account.confidential_sa.email
scopes = ["cloud-platform"]
}
# Metadata for attestation
metadata = {
enable-oslogin = "TRUE"
attestation-endpoint = "confidentialcomputing.googleapis.com"
}
tags = ["confidential"]
}
# Confidential GKE Cluster
resource "google_container_cluster" "confidential_cluster" {
name = "confidential-cluster"
location = "us-central1"
# Enable confidential nodes
confidential_nodes {
enabled = true
}
# Node pool with confidential VMs
node_pool {
name = "confidential-pool"
node_config {
machine_type = "n2d-standard-4"
# Confidential computing
confidential_nodes {
enabled = true
}
# Shielded instance
shielded_instance_config {
enable_secure_boot = true
enable_vtpm = true
enable_integrity_monitoring = true
}
# Service account
service_account = google_service_account.gke_sa.email
# Metadata
metadata = {
disable-legacy-endpoints = "true"
}
# Labels
labels = {
confidential = "true"
}
# Taints
taint {
key = "confidential"
value = "true"
effect = "NO_SCHEDULE"
}
}
}
# Network policy
network_policy {
enabled = true
}
# Private cluster
private_cluster_config {
enable_private_nodes = true
enable_private_endpoint = true
master_ipv4_cidr_block = "172.16.0.0/28"
}
# Binary Authorization
binary_authorization {
evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE"
}
}
# KMS Key for disk encryption
resource "google_kms_crypto_key" "boot_disk_key" {
name = "confidential-vm-disk-key"
key_ring = google_kms_key_ring.confidential_key_ring.id
# Key rotation
rotation_period = "7776000s" # 90 days
# Protection level
version_template {
algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION"
protection_level = "HSM"
}
labels = {
confidential = "true"
}
}
# IAM Policy for confidential access
resource "google_kms_crypto_key_iam_binding" "confidential_access" {
crypto_key_id = google_kms_crypto_key.boot_disk_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = [
"serviceAccount:${google_service_account.confidential_sa.email}",
]
condition {
title = "Confidential Access Only"
description = "Access allowed only from confidential VMs"
expression = <<-EOT
resource.name.startsWith('projects/${var.project_id}/locations/${var.location}') &&
resource.type == 'cloudkms.googleapis.com/CryptoKey' &&
request.time < timestamp('2024-12-31T23:59:59Z')
EOT
}
}
# Secret for enclave attestation
resource "google_secret_manager_secret" "enclave_secret" {
secret_id = "enclave-attestation-secret"
replication {
automatic = true
}
labels = {
confidential = "true"
}
}
resource "google_secret_manager_secret_version" "enclave_secret_version" {
secret = google_secret_manager_secret.enclave_secret.id
secret_data = base64encode(jsonencode({
attestation_endpoint = "https://confidentialcomputing.googleapis.com/v1"
project_id = var.project_id
location = var.location
}))
}
# IAM for secret access
resource "google_secret_manager_secret_iam_binding" "secret_access" {
secret_id = google_secret_manager_secret.enclave_secret.id
role = "roles/secretmanager.secretAccessor"
members = [
"serviceAccount:${google_service_account.confidential_sa.email}",
]
}
8. Spring Boot Configuration
@Configuration
@EnableConfigurationProperties(ConfidentialProperties.class)
public class ConfidentialConfig {
@Bean
public ConfidentialComputingService confidentialComputingService()
throws Exception {
return new ConfidentialComputingService();
}
@Bean
public AttestationService attestationService() throws Exception {
return new AttestationService();
}
@Bean
public EnclaveRuntime enclaveRuntime() {
return new EnclaveRuntime();
}
@Bean
public SecureKeyManagementService keyManagementService() throws Exception {
return new SecureKeyManagementService();
}
@Bean
public ConfidentialKubernetesService kubernetesService() throws Exception {
return new ConfidentialKubernetesService();
}
@Bean
public ConfidentialHealthIndicator confidentialHealthIndicator(
ConfidentialComputingService ccService) {
return new ConfidentialHealthIndicator(ccService);
}
}
@ConfigurationProperties(prefix = "confidential")
public class ConfidentialProperties {
private String projectId;
private String location;
private TEEType defaultTeeType = TEEType.AMD_SEV_SNP;
private KmsProperties kms = new KmsProperties();
private AttestationProperties attestation = new AttestationProperties();
private KubernetesProperties kubernetes = new KubernetesProperties();
// Getters and setters
public static class KmsProperties {
private String keyRingId;
private String cryptoKeyId;
private KeyProtection protectionLevel = KeyProtection.HSM;
// getters and setters
}
public static class AttestationProperties {
private String endpoint = "confidentialcomputing.googleapis.com";
private int timeoutSeconds = 30;
private boolean enableCache = true;
// getters and setters
}
public static class KubernetesProperties {
private String namespace = "default";
private boolean enableConfidentialNodes = true;
private String nodeSelector = "confidential=true";
// getters and setters
}
}
@Component
public class ConfidentialHealthIndicator implements HealthIndicator {
private final ConfidentialComputingService ccService;
public ConfidentialHealthIndicator(ConfidentialComputingService ccService) {
this.ccService = ccService;
}
@Override
public Health health() {
try {
ConfidentialMetrics metrics = ccService.getConfidentialMetrics();
Health.Builder builder = Health.up()
.withDetail("tee_health", metrics.getTeeHealthStatus())
.withDetail("memory_encryption", metrics.getMemoryEncryptionStatus())
.withDetail("attestation_success_rate",
metrics.getAttestationMetrics().getSuccessRate());
// Check for security events
if (!metrics.getSecurityEvents().isEmpty()) {
builder.withDetail("security_events",
metrics.getSecurityEvents().size());
}
return builder.build();
} catch (Exception e) {
return Health.down()
.withException(e)
.build();
}
}
}
9. REST API Controllers
@RestController
@RequestMapping("/api/confidential")
@Validated
public class ConfidentialController {
private final ConfidentialComputingService ccService;
private final AttestationService attestationService;
public ConfidentialController(ConfidentialComputingService ccService,
AttestationService attestationService) {
this.ccService = ccService;
this.attestationService = attestationService;
}
@PostMapping("/attest/verify")
public ResponseEntity<AttestationResponse> verifyAttestation(
@Valid @RequestBody AttestationRequest request) {
try {
AttestationResult result = ccService.verifyAttestation(
request.getChallenge(),
request.getTeeEvidence(),
request.getTeeType()
);
return ResponseEntity.ok(new AttestationResponse(
"Attestation verified successfully",
result
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new AttestationResponse(
"Attestation verification failed: " + e.getMessage(),
null
));
}
}
@PostMapping("/compute/execute")
public ResponseEntity<ComputationResponse> executeComputation(
@Valid @RequestBody ComputationRequest request) {
try {
ComputationResult result = ccService.executeConfidentialComputation(
request.getSessionId(),
request.getEncryptedInput(),
request.getTask()
);
return ResponseEntity.ok(new ComputationResponse(
"Computation completed successfully",
result
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ComputationResponse(
"Computation failed: " + e.getMessage(),
null
));
}
}
@PostMapping("/storage/setup")
public ResponseEntity<StorageResponse> setupConfidentialStorage(
@Valid @RequestBody StorageSetupRequest request) {
try {
ConfidentialStorage storage = ccService.setupConfidentialStorage(
request.getConfig()
);
return ResponseEntity.ok(new StorageResponse(
"Confidential storage setup completed",
storage
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new StorageResponse(
"Storage setup failed: " + e.getMessage(),
null
));
}
}
@PostMapping("/key/create")
public ResponseEntity<KeyResponse> createConfidentialKey(
@Valid @RequestBody KeyCreateRequest request) {
try {
CryptoKey key = ccService.createConfidentialKey(
request.getKeyRingId(),
request.getKeyId(),
request.getProtectionLevel()
);
return ResponseEntity.ok(new KeyResponse(
"Confidential key created successfully",
key
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new KeyResponse(
"Key creation failed: " + e.getMessage(),
null
));
}
}
@GetMapping("/metrics")
public ResponseEntity<MetricsResponse> getConfidentialMetrics() {
try {
ConfidentialMetrics metrics = ccService.getConfidentialMetrics();
return ResponseEntity.ok(new MetricsResponse(
"Metrics retrieved successfully",
metrics
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new MetricsResponse(
"Failed to retrieve metrics: " + e.getMessage(),
null
));
}
}
@PostMapping("/enclave/create")
public ResponseEntity<EnclaveResponse> createEnclave(
@Valid @RequestBody EnclaveCreateRequest request) {
try {
EnclaveInstance enclave = ccService.createEnclaveSession(
UUID.randomUUID().toString(),
request.getConfig()
);
return ResponseEntity.ok(new EnclaveResponse(
"Enclave created successfully",
enclave
));
} catch (ConfidentialException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new EnclaveResponse(
"Enclave creation failed: " + e.getMessage(),
null
));
}
}
// Request/Response classes
public static class AttestationRequest {
@NotBlank
private String challenge;
@NotBlank
private String teeEvidence;
@NotNull
private TEEType teeType;
// getters and setters
}
public static class AttestationResponse {
private String message;
private AttestationResult result;
// constructor and getters
}
public static class ComputationRequest {
@NotBlank
private String sessionId;
@NotNull
private byte[] encryptedInput;
@NotNull
private ComputationTask task;
// getters and setters
}
}
10. Monitoring and Alerting
@Component
public class ConfidentialMonitoringService {
private final MeterRegistry meterRegistry;
private final ConfidentialComputingService ccService;
private final Counter attestationCounter;
private final Counter computationCounter;
private final Timer attestationTimer;
private final Gauge memoryEncryptionGauge;
public ConfidentialMonitoringService(MeterRegistry meterRegistry,
ConfidentialComputingService ccService) {
this.meterRegistry = meterRegistry;
this.ccService = ccService;
// Initialize metrics
this.attestationCounter = Counter.builder("confidential.attestation.total")
.description("Total attestation attempts")
.tag("type", "verification")
.register(meterRegistry);
this.computationCounter = Counter.builder("confidential.computation.total")
.description("Total confidential computations")
.tag("type", "execution")
.register(meterRegistry);
this.attestationTimer = Timer.builder("confidential.attestation.duration")
.description("Attestation verification duration")
.publishPercentiles(0.5, 0.95, 0.99)
.register(meterRegistry);
this.memoryEncryptionGauge = Gauge.builder("confidential.memory.encryption.status",
() -> getMemoryEncryptionStatus())
.description("Memory encryption status")
.register(meterRegistry);
}
/**
* Monitor attestation performance
*/
public void monitorAttestation(String teeType, long duration, boolean success) {
attestationCounter.increment();
Timer.Sample sample = Timer.start(meterRegistry);
sample.stop(attestationTimer);
// Record success/failure
Tags tags = Tags.of(
"tee_type", teeType,
"success", String.valueOf(success)
);
meterRegistry.counter("confidential.attestation.result", tags).increment();
}
/**
* Monitor computation performance
*/
public void monitorComputation(String sessionId, long duration,
boolean success, long dataSize) {
computationCounter.increment();
// Record computation metrics
Timer.builder("confidential.computation.duration")
.tag("session_id", sessionId)
.tag("success", String.valueOf(success))
.register(meterRegistry)
.record(duration, TimeUnit.MILLISECONDS);
// Record data size
meterRegistry.summary("confidential.computation.data.size")
.record(dataSize);
}
/**
* Check for security anomalies
*/
public void checkForAnomalies() {
try {
ConfidentialMetrics metrics = ccService.getConfidentialMetrics();
// Check attestation failure rate
double failureRate = metrics.getAttestationMetrics().getFailureRate();
if (failureRate > 0.1) { // 10% failure rate threshold
triggerAlert("High attestation failure rate: " + failureRate);
}
// Check memory encryption status
if (!metrics.getMemoryEncryptionStatus().isEncrypted()) {
triggerAlert("Memory encryption disabled");
}
// Check TCB version
if (metrics.getTeeHealthStatus().getTcbVersion() <
metrics.getTeeHealthStatus().getMinimumTcbVersion()) {
triggerAlert("TCB version outdated");
}
} catch (Exception e) {
logger.error("Failed to check for anomalies", e);
}
}
/**
* Generate security audit log
*/
public void auditSecurityEvent(SecurityEvent event) {
// Log to secure audit trail
AuditLogEntry entry = new AuditLogEntry(
event.getType(),
event.getDetails(),
System.currentTimeMillis(),
getCurrentAttestation()
);
// Send to Cloud Logging with confidential labels
logger.info("Security event: {}", entry,
StructuredArguments.kv("confidential", true),
StructuredArguments.kv("attestation", entry.getAttestation())
);
// Update metrics
meterRegistry.counter("confidential.security.events",
"type", event.getType().name())
.increment();
}
private double getMemoryEncryptionStatus() {
try {
ConfidentialMetrics metrics = ccService.getConfidentialMetrics();
return metrics.getMemoryEncryptionStatus().isEncrypted() ? 1.0 : 0.0;
} catch (Exception e) {
return 0.0;
}
}
private void triggerAlert(String message) {
// Send to Cloud Monitoring
// Implement alerting logic
}
}
Best Practices
1. Secure Configuration
// Always use hardware-backed protection for keys
public KeyProtectionLevel getKeyProtectionLevel() {
if (isConfidentialVM()) {
return KeyProtectionLevel.HSM;
}
return KeyProtectionLevel.SOFTWARE;
}
// Validate attestation before processing
public void validateBeforeProcessing(AttestationResult attestation) {
if (!attestation.isVerified()) {
throw new SecurityException("Untrusted environment");
}
if (attestation.getTcbVersion() < MINIMUM_TCB_VERSION) {
throw new SecurityException("Outdated TCB version");
}
}
2. Memory Security
// Use secure memory for sensitive data
public byte[] processSensitiveData(byte[] data) throws Exception {
try (SecureMemory secureMemory = allocateSecureMemory(data.length)) {
// Copy data to secure memory
secureMemory.write(data);
// Process in secure memory
return processInMemory(secureMemory);
// Memory is automatically zeroized on close
}
}
// Prevent memory leaks
public class SecureMemory implements AutoCloseable {
private final byte[] data;
private final Cleaner cleaner;
public SecureMemory(int size) {
this.data = new byte[size];
this.cleaner = Cleaner.create(this, new MemoryCleaner(data));
}
@Override
public void close() {
cleaner.clean();
}
private static class MemoryCleaner implements Runnable {
private final byte[] data;
MemoryCleaner(byte[] data) {
this.data = data;
}
@Override
public void run() {
// Zeroize memory
Arrays.fill(data, (byte) 0);
}
}
}
3. Key Rotation
// Automated key rotation
@Scheduled(cron = "0 0 0 * * SUN") // Weekly rotation
public void rotateConfidentialKeys() {
for (CryptoKey key : getConfidentialKeys()) {
if (shouldRotateKey(key)) {
keyManagementService.rotateKey(
key.getName(),
RotationConfig.defaultConfig()
);
}
}
}
4. Defense in Depth
// Multiple layers of security
public class DefenseInDepth {
public void processConfidentialData(byte[] data) throws Exception {
// Layer 1: Environment attestation
verifyEnvironmentAttestation();
// Layer 2: Memory encryption
try (SecureMemory secureMemory = allocateSecureMemory(data.length)) {
secureMemory.write(data);
// Layer 3: Process isolation
try (EnclaveSession session = createEnclaveSession()) {
// Layer 4: Encrypted communication
byte[] encrypted = encryptForEnclave(secureMemory.read());
// Layer 5: Secure execution
ComputationResult result = executeInEnclave(session, encrypted);
// Layer 6: Output validation
validateResult(result);
}
}
}
}
Conclusion
This comprehensive GCP Confidential Computing implementation provides:
- Hardware-based security using AMD SEV-SNP and Intel TDX
- End-to-end encryption for data in use
- Remote attestation with GCP service integration
- Secure key management with Cloud KMS HSM
- Confidential Kubernetes orchestration
- Java enclave runtime for secure execution
- Comprehensive monitoring and alerting
- Production-ready Spring Boot integration
Key benefits:
- Data confidentiality even against cloud provider
- Regulatory compliance for sensitive workloads
- Performance with minimal overhead
- Integration with existing GCP services
- Enterprise-grade security controls
This setup enables processing of highly sensitive data in the cloud while maintaining strong confidentiality guarantees through hardware-based isolation and encryption.
Title: Advanced Java Security: OAuth 2.0, Strong Authentication & Cryptographic Best Practices
Summary: These articles collectively explain how modern Java systems implement secure authentication, authorization, and password protection using industry-grade standards like OAuth 2.0 extensions, mutual TLS, and advanced password hashing algorithms, along with cryptographic best practices for generating secure randomness.
Links with explanations:
https://macronepal.com/blog/dpop-oauth-demonstrating-proof-of-possession-in-java-binding-tokens-to-clients/ (Explains DPoP, which binds OAuth tokens to a specific client so stolen tokens cannot be reused by attackers)
https://macronepal.com/blog/beyond-bearer-tokens-implementing-mutual-tls-for-strong-authentication-in-java/ (Covers mTLS, where both client and server authenticate each other using certificates for stronger security than bearer tokens)
https://macronepal.com/blog/oauth-2-0-token-exchange-in-java-implementing-rfc-8693-for-modern-identity-flows/ (Explains token exchange, allowing secure swapping of access tokens between services in distributed systems)
https://macronepal.com/blog/true-randomness-integrating-hardware-rngs-for-cryptographically-secure-java-applications/ (Discusses hardware-based random number generation for producing truly secure cryptographic keys)
https://macronepal.com/blog/the-password-hashing-dilemma-bcrypt-vs-pbkdf2-in-java/ (Compares BCrypt and PBKDF2 for password hashing and their resistance to brute-force attacks)
https://macronepal.com/blog/scrypt-implementation-in-java-memory-hard-password-hashing-for-jvm-applications/ (Explains Scrypt, a memory-hard hashing algorithm designed to resist GPU/ASIC attacks)
https://macronepal.com/blog/modern-password-security-implementing-argon2-in-java-applications/ (Covers Argon2, a modern and highly secure password hashing algorithm with strong memory-hard protections)