Use admission controllers to enforce security policies
Admission controllers are a powerful feature in Kubernetes. These controllers intercept
requests to create new objects or mutate existing objects in a cluster, and take one or more
actions. Admission controllers can modify a request to conform to a designated policy (a
“mutating webhook”
AWS recommends that customers running multi-tenant clusters implement one or both of the following security policy enforcement mechanisms.
Pod Security Policies (PSPs)
Every EKS cluster comes with a built-in admission controller capable of enforcing Pod
Security Policies (PSPs). These policies are ordinary Kubernetes objects that a cluster
administrator can create. For details, see Pod Security
Policies
Here is an example of a policy that forbids running privileged Pods:
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: DisallowPrivilegedPods spec: privileged: false # The rest fills in some required fields. seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*'
A more complex policy can be found in Appendix: Strict pod security policy for an untrusted tenant. This policy does the following:
-
Disallows privileged pods
-
Disallows privilege escalation
-
Requires all capabilities be dropped
-
Forbids host volumes from being mounted
-
Forbids using host networking, Inter-Process Communication (IPC) with the host, and using host process IDs (PIDs)
-
Forbids running as root
-
Requires a default Seccomp profile
By default, EKS provides an unrestricted Pod Security Policy. AWS recommends removing
the default cluster role binding of the eks.privileged
policy to all
authenticated users. You can do this by editing the
eks:podsecuritypolicy:authenticated
cluster role binding to remove the
system:authenticated
group from the subject list. If you have created an
alternative administrator group for your cluster, you can replace the system:authenticated
group with your administrator group instead:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: eks:podsecuritypolicy:authenticated annotations: kubernetes.io/description: 'Allow all authenticated users to create privileged pods.' labels: kubernetes.io/cluster-service: "true" eks.amazonaws.com/component: pod-security-policy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: eks:podsecuritypolicy:privileged subjects: - kind: Group apiGroup: rbac.authorization.k8s.io # Replace this with your administrator group name name: system:authenticated
Warning
Be careful when making these or other changes to your cluster. They may prevent you from creating new pods until replacement policies, appropriate roles, and role bindings are created.
Open Policy Agent (OPA)
Open Policy Agent (OPA) is a powerful, open-source general-purpose policy agent. At its
core, OPA evaluates configurations against a set of rules you define, using a
domain-specific language called Rego.
OPA is capable of providing much more extensive policy management than a Pod Security Policy. PSPs are limited to Pods, while OPA can manage nearly any kind of Kubernetes object. And while PSPs are only able to apply a limited set of policies to a pod, OPA can apply powerful validators such as pattern matchers to any field in an object. For example, with OPA, you can also require that all container images be pulled from a trusted image repository.
The following is an example of a Rego policy that prohibits the creation of privileged containers:
package kubernetes.admission deny[message] { # match only if a Pod is being created input.request.kind.kind == "Pod" # examine each container container := input.request.object.spec.containers[_] # match if privileged is set container.securityContext.privileged message := sprintf("Container %v runs in privileged mode.", [container.name]) }
OPA is rapidly evolving. Customers can choose from several different implementations to
run in their EKS clusters. Kube-mgmt