Implementing Pod Security Standards in Java

Overview

Pod Security Standards (PSS) define different isolation levels for Kubernetes pods. This Java implementation provides validation, admission control, and security context management for Kubernetes workloads.

1. Dependencies

<dependencies>
<!-- Kubernetes Client -->
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>18.0.0</version>
</dependency>
<!-- Jakarta Validation -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>
<!-- JSON Processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- YAML Processing -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.15.2</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>

2. Core Domain Models

Pod Security Standards Levels

package com.example.pss;
public enum PodSecurityLevel {
PRIVILEGED("privileged"),
BASELINE("baseline"), 
RESTRICTED("restricted");
private final String value;
PodSecurityLevel(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static PodSecurityLevel fromString(String value) {
for (PodSecurityLevel level : values()) {
if (level.value.equalsIgnoreCase(value)) {
return level;
}
}
throw new IllegalArgumentException("Unknown Pod Security Level: " + value);
}
}

Security Context Models

package com.example.pss.model;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PodSecurityContext {
private Boolean runAsNonRoot;
private Long runAsUser;
private Long runAsGroup;
private Long fsGroup;
private String fsGroupChangePolicy;
private SeLinuxOptions seLinuxOptions;
private SeccompProfile seccompProfile;
private WindowsSecurityContextOptions windowsOptions;
// Getters and Setters
public Boolean getRunAsNonRoot() { return runAsNonRoot; }
public void setRunAsNonRoot(Boolean runAsNonRoot) { this.runAsNonRoot = runAsNonRoot; }
public Long getRunAsUser() { return runAsUser; }
public void setRunAsUser(Long runAsUser) { this.runAsUser = runAsUser; }
public Long getRunAsGroup() { return runAsGroup; }
public void setRunAsGroup(Long runAsGroup) { this.runAsGroup = runAsGroup; }
public Long getFsGroup() { return fsGroup; }
public void setFsGroup(Long fsGroup) { this.fsGroup = fsGroup; }
public String getFsGroupChangePolicy() { return fsGroupChangePolicy; }
public void setFsGroupChangePolicy(String fsGroupChangePolicy) { this.fsGroupChangePolicy = fsGroupChangePolicy; }
public SeLinuxOptions getSeLinuxOptions() { return seLinuxOptions; }
public void setSeLinuxOptions(SeLinuxOptions seLinuxOptions) { this.seLinuxOptions = seLinuxOptions; }
public SeccompProfile getSeccompProfile() { return seccompProfile; }
public void setSeccompProfile(SeccompProfile seccompProfile) { this.seccompProfile = seccompProfile; }
public WindowsSecurityContextOptions getWindowsOptions() { return windowsOptions; }
public void setWindowsOptions(WindowsSecurityContextOptions windowsOptions) { this.windowsOptions = windowsOptions; }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ContainerSecurityContext {
private Boolean allowPrivilegeEscalation;
private Boolean privileged;
private Boolean readOnlyRootFilesystem;
private Long runAsUser;
private Long runAsGroup;
private Boolean runAsNonRoot;
private SeLinuxOptions seLinuxOptions;
private SeccompProfile seccompProfile;
private WindowsSecurityContextOptions windowsOptions;
private Capabilities capabilities;
// Getters and Setters
public Boolean getAllowPrivilegeEscalation() { return allowPrivilegeEscalation; }
public void setAllowPrivilegeEscalation(Boolean allowPrivilegeEscalation) { this.allowPrivilegeEscalation = allowPrivilegeEscalation; }
public Boolean getPrivileged() { return privileged; }
public void setPrivileged(Boolean privileged) { this.privileged = privileged; }
public Boolean getReadOnlyRootFilesystem() { return readOnlyRootFilesystem; }
public void setReadOnlyRootFilesystem(Boolean readOnlyRootFilesystem) { this.readOnlyRootFilesystem = readOnlyRootFilesystem; }
public Long getRunAsUser() { return runAsUser; }
public void setRunAsUser(Long runAsUser) { this.runAsUser = runAsUser; }
public Long getRunAsGroup() { return runAsGroup; }
public void setRunAsGroup(Long runAsGroup) { this.runAsGroup = runAsGroup; }
public Boolean getRunAsNonRoot() { return runAsNonRoot; }
public void setRunAsNonRoot(Boolean runAsNonRoot) { this.runAsNonRoot = runAsNonRoot; }
public SeLinuxOptions getSeLinuxOptions() { return seLinuxOptions; }
public void setSeLinuxOptions(SeLinuxOptions seLinuxOptions) { this.seLinuxOptions = seLinuxOptions; }
public SeccompProfile getSeccompProfile() { return seccompProfile; }
public void setSeccompProfile(SeccompProfile seccompProfile) { this.seccompProfile = seccompProfile; }
public WindowsSecurityContextOptions getWindowsOptions() { return windowsOptions; }
public void setWindowsOptions(WindowsSecurityContextOptions windowsOptions) { this.windowsOptions = windowsOptions; }
public Capabilities getCapabilities() { return capabilities; }
public void setCapabilities(Capabilities capabilities) { this.capabilities = capabilities; }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Capabilities {
private java.util.List<String> add;
private java.util.List<String> drop;
// Getters and Setters
public java.util.List<String> getAdd() { return add; }
public void setAdd(java.util.List<String> add) { this.add = add; }
public java.util.List<String> getDrop() { return drop; }
public void setDrop(java.util.List<String> drop) { this.drop = drop; }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SeLinuxOptions {
private String level;
private String role;
private String type;
private String user;
// Getters and Setters
public String getLevel() { return level; }
public void setLevel(String level) { this.level = level; }
public String getRole() { return role; }
public void setRole(String role) { this.role = role; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getUser() { return user; }
public void setUser(String user) { this.user = user; }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SeccompProfile {
private String type;
private String localhostProfile;
// Getters and Setters
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getLocalhostProfile() { return localhostProfile; }
public void setLocalhostProfile(String localhostProfile) { this.localhostProfile = localhostProfile; }
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class WindowsSecurityContextOptions {
private String gmsaCredentialSpec;
private String gmsaCredentialSpecName;
private String hostProcess;
private String runAsUserName;
// Getters and Setters
public String getGmsaCredentialSpec() { return gmsaCredentialSpec; }
public void setGmsaCredentialSpec(String gmsaCredentialSpec) { this.gmsaCredentialSpec = gmsaCredentialSpec; }
public String getGmsaCredentialSpecName() { return gmsaCredentialSpecName; }
public void setGmsaCredentialSpecName(String gmsaCredentialSpecName) { this.gmsaCredentialSpecName = gmsaCredentialSpecName; }
public String getHostProcess() { return hostProcess; }
public void setHostProcess(String hostProcess) { this.hostProcess = hostProcess; }
public String getRunAsUserName() { return runAsUserName; }
public void setRunAsUserName(String runAsUserName) { this.runAsUserName = runAsUserName; }
}

3. Pod Security Standards Validator

package com.example.pss.validator;
import com.example.pss.PodSecurityLevel;
import com.example.pss.model.*;
import com.example.pss.result.ValidationResult;
import com.example.pss.result.Violation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class PodSecurityValidator {
private static final Logger log = LoggerFactory.getLogger(PodSecurityValidator.class);
public ValidationResult validatePod(PodSpec podSpec, PodSecurityLevel level) {
List<Violation> violations = new ArrayList<>();
switch (level) {
case PRIVILEGED:
// No restrictions for privileged
break;
case BASELINE:
violations.addAll(validateBaseline(podSpec));
break;
case RESTRICTED:
violations.addAll(validateBaseline(podSpec));
violations.addAll(validateRestricted(podSpec));
break;
}
return new ValidationResult(violations.isEmpty(), violations);
}
private List<Violation> validateBaseline(PodSpec podSpec) {
List<Violation> violations = new ArrayList<>();
// Validate pod-level security context
validatePodSecurityContext(podSpec.getSecurityContext(), violations);
// Validate container security contexts
for (ContainerSpec container : podSpec.getContainers()) {
validateContainerBaseline(container, violations);
}
// Validate host namespace sharing
if (Boolean.TRUE.equals(podSpec.getHostNetwork())) {
violations.add(new Violation("hostNetwork", 
"Sharing the host network namespace is not allowed", "baseline"));
}
if (Boolean.TRUE.equals(podSpec.getHostPID())) {
violations.add(new Violation("hostPID", 
"Sharing the host PID namespace is not allowed", "baseline"));
}
if (Boolean.TRUE.equals(podSpec.getHostIPC())) {
violations.add(new Violation("hostIPC", 
"Sharing the host IPC namespace is not allowed", "baseline"));
}
return violations;
}
private List<Violation> validateRestricted(PodSpec podSpec) {
List<Violation> violations = new ArrayList<>();
// Validate pod security context for restricted requirements
PodSecurityContext podSecurityContext = podSpec.getSecurityContext();
if (podSecurityContext == null) {
violations.add(new Violation("securityContext", 
"Pod-level security context is required", "restricted"));
} else {
if (podSecurityContext.getRunAsNonRoot() == null || !podSecurityContext.getRunAsNonRoot()) {
violations.add(new Violation("securityContext.runAsNonRoot", 
"Must run as non-root user", "restricted"));
}
if (podSecurityContext.getSeccompProfile() == null || 
!"RuntimeDefault".equals(podSecurityContext.getSeccompProfile().getType())) {
violations.add(new Violation("securityContext.seccompProfile", 
"Seccomp profile must be set to RuntimeDefault", "restricted"));
}
}
// Validate container security contexts for restricted requirements
for (ContainerSpec container : podSpec.getContainers()) {
validateContainerRestricted(container, violations);
}
return violations;
}
private void validatePodSecurityContext(PodSecurityContext context, List<Violation> violations) {
if (context == null) {
return;
}
// Validate SELinux options
if (context.getSeLinuxOptions() != null) {
violations.add(new Violation("securityContext.seLinuxOptions", 
"SELinux options are not allowed", "baseline"));
}
// Validate Windows options
if (context.getWindowsOptions() != null) {
violations.add(new Violation("securityContext.windowsOptions", 
"Windows security options are not allowed", "baseline"));
}
}
private void validateContainerBaseline(ContainerSpec container, List<Violation> violations) {
ContainerSecurityContext context = container.getSecurityContext();
if (context == null) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext", 
"Container security context is required", "baseline"));
return;
}
// Privileged containers are not allowed
if (Boolean.TRUE.equals(context.getPrivileged())) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.privileged", 
"Privileged containers are not allowed", "baseline"));
}
// Host path volumes are restricted
if (container.getVolumeMounts() != null) {
for (VolumeMount mount : container.getVolumeMounts()) {
if ("hostPath".equals(mount.getType())) {
violations.add(new Violation("volumes[" + mount.getName() + "].hostPath", 
"HostPath volumes are restricted", "baseline"));
}
}
}
// Validate capabilities
validateCapabilities(container.getName(), context.getCapabilities(), violations);
}
private void validateContainerRestricted(ContainerSpec container, List<Violation> violations) {
ContainerSecurityContext context = container.getSecurityContext();
if (context == null) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext", 
"Container security context is required for restricted level", "restricted"));
return;
}
// Must run as non-root
if (context.getRunAsNonRoot() == null || !context.getRunAsNonRoot()) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.runAsNonRoot", 
"Must run as non-root user", "restricted"));
}
// Allow privilege escalation must be false
if (context.getAllowPrivilegeEscalation() == null || context.getAllowPrivilegeEscalation()) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.allowPrivilegeEscalation", 
"Privilege escalation must be disabled", "restricted"));
}
// Read-only root filesystem is required
if (context.getReadOnlyRootFilesystem() == null || !context.getReadOnlyRootFilesystem()) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.readOnlyRootFilesystem", 
"Read-only root filesystem is required", "restricted"));
}
// Must drop ALL capabilities
if (context.getCapabilities() != null) {
List<String> drop = context.getCapabilities().getDrop();
if (drop == null || !drop.contains("ALL")) {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.capabilities.drop", 
"Must drop ALL capabilities", "restricted"));
}
} else {
violations.add(new Violation("containers[" + container.getName() + "].securityContext.capabilities", 
"Capabilities must be configured to drop ALL", "restricted"));
}
}
private void validateCapabilities(String containerName, Capabilities capabilities, List<Violation> violations) {
if (capabilities == null) {
return;
}
// Check for dangerous capabilities in add list
List<String> dangerousCaps = Arrays.asList(
"NET_RAW", "SYS_ADMIN", "SYS_PTRACE", "SYS_MODULE", "SYS_RAWIO"
);
if (capabilities.getAdd() != null) {
for (String cap : capabilities.getAdd()) {
if (dangerousCaps.contains(cap)) {
violations.add(new Violation("containers[" + containerName + "].securityContext.capabilities.add." + cap, 
"Dangerous capability " + cap + " is not allowed", "baseline"));
}
}
}
}
}

4. Pod Specification Models

package com.example.pss.model;
import java.util.List;
import java.util.Map;
public class PodSpec {
private PodSecurityContext securityContext;
private Boolean hostNetwork;
private Boolean hostPID;
private Boolean hostIPC;
private List<ContainerSpec> containers;
private List<Volume> volumes;
private List<ContainerSpec> initContainers;
// Getters and Setters
public PodSecurityContext getSecurityContext() { return securityContext; }
public void setSecurityContext(PodSecurityContext securityContext) { this.securityContext = securityContext; }
public Boolean getHostNetwork() { return hostNetwork; }
public void setHostNetwork(Boolean hostNetwork) { this.hostNetwork = hostNetwork; }
public Boolean getHostPID() { return hostPID; }
public void setHostPID(Boolean hostPID) { this.hostPID = hostPID; }
public Boolean getHostIPC() { return hostIPC; }
public void setHostIPC(Boolean hostIPC) { this.hostIPC = hostIPC; }
public List<ContainerSpec> getContainers() { return containers; }
public void setContainers(List<ContainerSpec> containers) { this.containers = containers; }
public List<Volume> getVolumes() { return volumes; }
public void setVolumes(List<Volume> volumes) { this.volumes = volumes; }
public List<ContainerSpec> getInitContainers() { return initContainers; }
public void setInitContainers(List<ContainerSpec> initContainers) { this.initContainers = initContainers; }
}
public class ContainerSpec {
private String name;
private String image;
private ContainerSecurityContext securityContext;
private List<VolumeMount> volumeMounts;
private List<EnvVar> env;
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getImage() { return image; }
public void setImage(String image) { this.image = image; }
public ContainerSecurityContext getSecurityContext() { return securityContext; }
public void setSecurityContext(ContainerSecurityContext securityContext) { this.securityContext = securityContext; }
public List<VolumeMount> getVolumeMounts() { return volumeMounts; }
public void setVolumeMounts(List<VolumeMount> volumeMounts) { this.volumeMounts = volumeMounts; }
public List<EnvVar> getEnv() { return env; }
public void setEnv(List<EnvVar> env) { this.env = env; }
}
public class VolumeMount {
private String name;
private String mountPath;
private String type;
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getMountPath() { return mountPath; }
public void setMountPath(String mountPath) { this.mountPath = mountPath; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
}
public class Volume {
private String name;
private String type;
private Map<String, Object> config;
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public Map<String, Object> getConfig() { return config; }
public void setConfig(Map<String, Object> config) { this.config = config; }
}
public class EnvVar {
private String name;
private String value;
private EnvVarSource valueFrom;
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
public EnvVarSource getValueFrom() { return valueFrom; }
public void setValueFrom(EnvVarSource valueFrom) { this.valueFrom = valueFrom; }
}
public class EnvVarSource {
private Object fieldRef;
private Object secretKeyRef;
private Object configMapKeyRef;
// Getters and Setters
public Object getFieldRef() { return fieldRef; }
public void setFieldRef(Object fieldRef) { this.fieldRef = fieldRef; }
public Object getSecretKeyRef() { return secretKeyRef; }
public void setSecretKeyRef(Object secretKeyRef) { this.secretKeyRef = secretKeyRef; }
public Object getConfigMapKeyRef() { return configMapKeyRef; }
public void setConfigMapKeyRef(Object configMapKeyRef) { this.configMapKeyRef = configMapKeyRef; }
}

5. Validation Results

package com.example.pss.result;
import java.util.List;
public class ValidationResult {
private final boolean valid;
private final List<Violation> violations;
private final String message;
public ValidationResult(boolean valid, List<Violation> violations) {
this.valid = valid;
this.violations = violations;
this.message = valid ? "Validation passed" : "Validation failed with " + violations.size() + " violations";
}
// Getters
public boolean isValid() { return valid; }
public List<Violation> getViolations() { return violations; }
public String getMessage() { return message; }
}
package com.example.pss.result;
public class Violation {
private final String field;
private final String message;
private final String level;
private final Severity severity;
public enum Severity {
LOW, MEDIUM, HIGH, CRITICAL
}
public Violation(String field, String message, String level) {
this.field = field;
this.message = message;
this.level = level;
this.severity = determineSeverity(field, message);
}
// Getters
public String getField() { return field; }
public String getMessage() { return message; }
public String getLevel() { return level; }
public Severity getSeverity() { return severity; }
private Severity determineSeverity(String field, String message) {
if (field.contains("privileged") || field.contains("hostNetwork")) {
return Severity.CRITICAL;
} else if (field.contains("capabilities") || field.contains("runAsNonRoot")) {
return Severity.HIGH;
} else if (field.contains("seLinuxOptions") || field.contains("seccompProfile")) {
return Severity.MEDIUM;
} else {
return Severity.LOW;
}
}
@Override
public String toString() {
return String.format("Violation{field='%s', message='%s', level='%s', severity=%s}",
field, message, level, severity);
}
}

6. Security Context Generator

package com.example.pss.generator;
import com.example.pss.PodSecurityLevel;
import com.example.pss.model.*;
public class SecurityContextGenerator {
public static PodSecurityContext generatePodSecurityContext(PodSecurityLevel level) {
PodSecurityContext context = new PodSecurityContext();
switch (level) {
case RESTRICTED:
context.setRunAsNonRoot(true);
context.setRunAsUser(1000L);
context.setRunAsGroup(1000L);
context.setFsGroup(1000L);
SeccompProfile seccomp = new SeccompProfile();
seccomp.setType("RuntimeDefault");
context.setSeccompProfile(seccomp);
break;
case BASELINE:
context.setRunAsNonRoot(true);
context.setRunAsUser(1000L);
break;
case PRIVILEGED:
// Minimal restrictions for privileged
break;
}
return context;
}
public static ContainerSecurityContext generateContainerSecurityContext(PodSecurityLevel level) {
ContainerSecurityContext context = new ContainerSecurityContext();
switch (level) {
case RESTRICTED:
context.setRunAsNonRoot(true);
context.setRunAsUser(1000L);
context.setAllowPrivilegeEscalation(false);
context.setReadOnlyRootFilesystem(true);
context.setPrivileged(false);
// Drop ALL capabilities
Capabilities caps = new Capabilities();
caps.setDrop(java.util.Arrays.asList("ALL"));
context.setCapabilities(caps);
// Set seccomp profile
SeccompProfile seccomp = new SeccompProfile();
seccomp.setType("RuntimeDefault");
context.setSeccompProfile(seccomp);
break;
case BASELINE:
context.setRunAsNonRoot(true);
context.setAllowPrivilegeEscalation(false);
context.setPrivileged(false);
// Drop some dangerous capabilities
Capabilities baselineCaps = new Capabilities();
baselineCaps.setDrop(java.util.Arrays.asList("NET_RAW", "SYS_ADMIN"));
context.setCapabilities(baselineCaps);
break;
case PRIVILEGED:
// Minimal restrictions
break;
}
return context;
}
public static PodSpec enforceSecurityStandards(PodSpec originalPod, PodSecurityLevel level) {
PodSpec securedPod = deepCopy(originalPod);
// Set pod-level security context
if (securedPod.getSecurityContext() == null) {
securedPod.setSecurityContext(generatePodSecurityContext(level));
}
// Set container security contexts
if (securedPod.getContainers() != null) {
for (ContainerSpec container : securedPod.getContainers()) {
if (container.getSecurityContext() == null) {
container.setSecurityContext(generateContainerSecurityContext(level));
}
}
}
// Set init container security contexts
if (securedPod.getInitContainers() != null) {
for (ContainerSpec initContainer : securedPod.getInitContainers()) {
if (initContainer.getSecurityContext() == null) {
initContainer.setSecurityContext(generateContainerSecurityContext(level));
}
}
}
// Enforce namespace restrictions based on level
if (level != PodSecurityLevel.PRIVILEGED) {
securedPod.setHostNetwork(false);
securedPod.setHostPID(false);
securedPod.setHostIPC(false);
}
return securedPod;
}
private static PodSpec deepCopy(PodSpec original) {
// In a real implementation, use a proper deep copy mechanism
// This is a simplified version
PodSpec copy = new PodSpec();
copy.setSecurityContext(original.getSecurityContext());
copy.setHostNetwork(original.getHostNetwork());
copy.setHostPID(original.getHostPID());
copy.setHostIPC(original.getHostIPC());
copy.setContainers(original.getContainers());
copy.setInitContainers(original.getInitContainers());
copy.setVolumes(original.getVolumes());
return copy;
}
}

7. Kubernetes Admission Webhook

package com.example.pss.webhook;
import com.example.pss.PodSecurityLevel;
import com.example.pss.validator.PodSecurityValidator;
import com.example.pss.model.PodSpec;
import com.example.pss.result.ValidationResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
public class AdmissionWebhook {
private static final Logger log = LoggerFactory.getLogger(AdmissionWebhook.class);
private static final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
private final PodSecurityValidator validator;
private final PodSecurityLevel enforcedLevel;
public AdmissionWebhook(PodSecurityLevel enforcedLevel) {
this.validator = new PodSecurityValidator();
this.enforcedLevel = enforcedLevel;
}
public AdmissionResponse validateAdmission(AdmissionRequest request) {
try {
log.info("Processing admission request for {}", request.getUid());
// Extract pod spec from request
PodSpec podSpec = extractPodSpec(request.getObject());
// Validate against enforced level
ValidationResult result = validator.validatePod(podSpec, enforcedLevel);
return buildAdmissionResponse(request.getUid(), result);
} catch (Exception e) {
log.error("Error processing admission request", e);
return buildErrorResponse(request.getUid(), e.getMessage());
}
}
private PodSpec extractPodSpec(Map<String, Object> requestObject) {
// Extract pod spec from Kubernetes admission request
// This is a simplified extraction - real implementation would be more robust
Map<String, Object> spec = (Map<String, Object>) requestObject.get("spec");
return mapper.convertValue(spec, PodSpec.class);
}
private AdmissionResponse buildAdmissionResponse(String uid, ValidationResult result) {
AdmissionResponse response = new AdmissionResponse();
response.setUid(uid);
response.setAllowed(result.isValid());
if (!result.isValid()) {
AdmissionResponse.Status status = new AdmissionResponse.Status();
status.setMessage(result.getMessage());
status.setCode(403);
response.setStatus(status);
// Add detailed violations to response
response.setViolations(result.getViolations());
}
return response;
}
private AdmissionResponse buildErrorResponse(String uid, String error) {
AdmissionResponse response = new AdmissionResponse();
response.setUid(uid);
response.setAllowed(false);
AdmissionResponse.Status status = new AdmissionResponse.Status();
status.setMessage("Error validating pod: " + error);
status.setCode(500);
response.setStatus(status);
return response;
}
}
// Admission request/response models
class AdmissionRequest {
private String uid;
private Map<String, Object> object;
private Map<String, Object> oldObject;
private String operation;
// Getters and Setters
public String getUid() { return uid; }
public void setUid(String uid) { this.uid = uid; }
public Map<String, Object> getObject() { return object; }
public void setObject(Map<String, Object> object) { this.object = object; }
public Map<String, Object> getOldObject() { return oldObject; }
public void setOldObject(Map<String, Object> oldObject) { this.oldObject = oldObject; }
public String getOperation() { return operation; }
public void setOperation(String operation) { this.operation = operation; }
}
class AdmissionResponse {
private String uid;
private boolean allowed;
private Status status;
private Object patch;
private String patchType;
private Object violations;
// Getters and Setters
public String getUid() { return uid; }
public void setUid(String uid) { this.uid = uid; }
public boolean isAllowed() { return allowed; }
public void setAllowed(boolean allowed) { this.allowed = allowed; }
public Status getStatus() { return status; }
public void setStatus(Status status) { this.status = status; }
public Object getPatch() { return patch; }
public void setPatch(Object patch) { this.patch = patch; }
public String getPatchType() { return patchType; }
public void setPatchType(String patchType) { this.patchType = patchType; }
public Object getViolations() { return violations; }
public void setViolations(Object violations) { this.violations = violations; }
public static class Status {
private String message;
private int code;
// Getters and Setters
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
}
}

8. Example Usage

package com.example.pss.demo;
import com.example.pss.PodSecurityLevel;
import com.example.pss.generator.SecurityContextGenerator;
import com.example.pss.model.*;
import com.example.pss.validator.PodSecurityValidator;
import com.example.pss.result.ValidationResult;
import java.util.Arrays;
public class PodSecurityDemo {
public static void main(String[] args) {
// Create a sample pod specification
PodSpec podSpec = createSamplePod();
// Initialize validator
PodSecurityValidator validator = new PodSecurityValidator();
// Test different security levels
testSecurityLevel(podSpec, validator, PodSecurityLevel.BASELINE);
testSecurityLevel(podSpec, validator, PodSecurityLevel.RESTRICTED);
// Generate secured pod spec
PodSpec securedPod = SecurityContextGenerator.enforceSecurityStandards(
podSpec, PodSecurityLevel.RESTRICTED);
System.out.println("\n=== Secured Pod Specification ===");
System.out.println("RunAsNonRoot: " + 
securedPod.getSecurityContext().getRunAsNonRoot());
System.out.println("Seccomp Profile: " + 
securedPod.getSecurityContext().getSeccompProfile().getType());
}
private static void testSecurityLevel(PodSpec podSpec, PodSecurityValidator validator, 
PodSecurityLevel level) {
System.out.println("\n=== Testing " + level + " Level ===");
ValidationResult result = validator.validatePod(podSpec, level);
System.out.println("Valid: " + result.isValid());
System.out.println("Message: " + result.getMessage());
if (!result.isValid()) {
System.out.println("Violations:");
result.getViolations().forEach(v -> 
System.out.println("  - " + v.getField() + ": " + v.getMessage() + 
" (Severity: " + v.getSeverity() + ")"));
}
}
private static PodSpec createSamplePod() {
PodSpec pod = new PodSpec();
// Create a container with minimal security context
ContainerSpec container = new ContainerSpec();
container.setName("test-container");
container.setImage("nginx:latest");
// Intentionally insecure configuration for demonstration
ContainerSecurityContext containerContext = new ContainerSecurityContext();
containerContext.setPrivileged(false); // This would fail baseline
container.setSecurityContext(containerContext);
pod.setContainers(Arrays.asList(container));
// Set some insecure pod-level settings
pod.setHostNetwork(true); // This would fail baseline
pod.setHostPID(false);
return pod;
}
}

Key Features

  1. Pod Security Standards Validation: Implements baseline and restricted levels
  2. Security Context Generation: Automatically generates compliant security contexts
  3. Admission Control: Kubernetes webhook for real-time validation
  4. Comprehensive Violation Reporting: Detailed security violation information
  5. Security Context Management: Tools for managing pod and container security contexts

This implementation provides a complete framework for enforcing Pod Security Standards in Java applications, suitable for integration with Kubernetes operators, CI/CD pipelines, or security scanning tools.

Leave a Reply

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


Macro Nepal Helper