Getting started with PodSecurityPolicy on EKS
As you might already know, security is not something that a specialized department should be responsible for. Instead, we all should bear in mind that security matters and build secure solutions from the very beginning. Today we're gonna talk about some practices in the world of containerized apps and Kubernetess. So let's say we have some best practices for the containerized workloads. But how to enforce that? We'll tell you right away.
And the answer is actually pretty straightforward. Do you want to enforce some security policies? Use Pod Security Policy resource. In reality, Pod Security Policy is just an admission controller which is able to check if pods comply to assigned set of rules.
For instance, we can check if pod is not running in privileged mode or we can also restrict the use of certain volumes types, this comes handy for example when you don't want to allow access to host filesystem.
So why do I even write this post? We have some specialized resource so we just create it and that's it, right? Well, it's not that easy. And that's why I wrote this article. Let's begin.
As already mentioned, Pod Security Policy is just another Kubernetes resource. The following document contains a really simple policy that prohibits the run of privileged containers.
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: example spec: privileged: false seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*'
But when you apply this document with
kubectl, it just does nothing.
That's because PSP mechanism is deeply integrated with RBAC system.
In order to use this policy, you need to authorize the respective accounts
to use it first.
So this is the basic ClusterRole which authorizes the use of verb
the PSP created before.
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: psp:example rules: - apiGroups: - policy resources: - podsecuritypolicies verbs: - use resourceNames: - example
Now we need to bind this
ClusterRole to the certain
Here I need to step in and add some context. Why are we talking about ServiceAccounts
when the workload is created by some users from flesh and bones?
The thing is that usually, we don't create pod resources by ourselves but
we're using some controllers instead. You can check more details in the
official documentation. So the whole job is done by someone else hence
we need to bind
ClusterRole accordingly. To show you the whole picture,
Deployment resources we want to use for our
apiVersion: v1 kind: ServiceAccount metadata: name: app namespace: app-test --- apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: app-test labels: app: app spec: replicas: 1 selector: matchLabels: app: app template: metadata: labels: app: app spec: serviceAccountName: app containers: - name: app image: mycustomnamespace/app:v1.0.0 ports: - containerPort: 80
Now we know that
app lives in the
we can create a suitable
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: psp:example:app:app-test roleRef: kind: ClusterRole name: psp:example apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: app namespace: app-test
From now, we should be able to run our workload as long as it does not run in privileged mode. Sweet.
But let's talk about EKS. This offering has enabled PSP out of the box. Do you have any experience with EKS? If yes, you know then that you are able to create any workload with no restrictions.
However, it does not mean that policy engine is not enabled. The reason is that PSP is a pretty comprehensive topic so EKS comes with preconfigured policy bound to all authenticated users.
The key elements are
What I'm saying here is that in order to apply your own rules you need to delete those resources and start on the green field.
kubectl delete podsecuritypolicy eks.privileged kubectl delete clusterrolebinding eks:podsecuritypolicy:authenticated
But when you do so, please be prepared for the following: no new pods can be created from now. You'll most likely get a similar error since we need at least one policy in order to start any pod with Pod Security Policy enabled.
unable to validate against any pod security policy: 
All mentioned is already documented by Amazon, personally I really like this blog post with a step-by-step guide.
When applying ultra restrictive policies, time to time you might encounter situations when the pod starts even when it does not comply with the PodSecurityPolicy. From my experience, it's always caused by incorrectly configured RBAC.
For instance, you've allowed all verbs to all resources in the
extensions API group
so now your
ServiceAccount is assigned to all
hence the restrictions don't work as intended.
Please also note that some resources are availabel in multiple api groups. For instance,
PodSecurityPolicycan be in
extensionsat the same time! Dangerous stuff 😀
But don't worry, you can address such issues with
auth can-i command!
kubectl auth can-i use podsecuritypolicy/example --namespace app-test --as app
Security really matters and you should not skip
just because it's not as straightforward as other Kubernetes resources.
Sure, this component can't save the whole world but it can help you with some
basics. Moreover, it's no so complex as you could see in this post. Give it a shot!
Do you have any specific questions regarding PSP? Do not hesitate to reach us, we're always happy to help.