Applying ServiceAccount specific OPA policies through Gatekeeper in kubernetes

715 views Asked by At

We are trying to replace our existing PSPs in kubernetes with OPA policies using Gatekeeper. I'm using the default templates provided by Gatekeeper https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy and defined corresponding constraints.

However, I can't figure out how I can apply a policy to a specific ServiceAccount. For eg. how to define allow-privilege-escalation policy only to a ServiceAccount named awsnode?

In PSPs I create a Role/ClusterRole for required podsecuritypolicies and create a RoleBinding to allow awsnode ServiceAccount to use required PSP. I'm struggling to understand how to achieve the same using Gatekeeper OPA policies?

Thank you.

2

There are 2 answers

0
autobot On BEST ANSWER

Apparently PSPs and Gatekeeper OPA policies are designed to achieve pod security at different levels. Here is the response from AWS support on the above question.

Gatekeeper constraint templates (and the corresponding constraint CRDs defined from the templates) apply to a larger scope of Kubernetes resources than just pods. Gatekeeper extends additional functionality that RBAC cannot provide at this stage. Gatekeeper itself cannot be managed by RBAC (by means of using verbs to restrict access to Gatekeeper constraints), because no RBAC resource keyword exists for Gatekeeper policy constraints (at least, at the time of writing this). PodSecurity Admission Controller might be an option for someone looking for a replacement for PSPs which needs to be controlled by RBAC if the cluster is on 1.22 version or above.

0
JKD On

I think a possible solution to applying an OPA Gatekeeper policy (a ConstraintTemplate) to a specific ServiceAccount, is to make the OPA/Rego policy code reflect that filter / selection logic. Since you said you're using pre-existing policies from the gatekeeper-library, maybe changing the policy code isn't an option for you. But if changing it is an option, I think your OPA/Rego policy can take into account the pod's serviceAccount field. Keep in mind with OPA Gatekeeper, the input to the Rego policy code is the entire admission request, including the spec of the pod (assuming it's pod creations that you're trying to check).

So part of the input to the Rego policy code might be like

      "spec": {
        "volumes": [...        ],
        "containers": [
          {
            "name": "apache",
            "image": "docker.io/apache:latest",
            "ports": [...            ],
            "env": [...            ],
            "resources": {},
            "volumeMounts": [...            ],
            "imagePullPolicy": "IfNotPresent",
            "securityContext": {...            }
          }
        ],
        "restartPolicy": "Always",
        "terminationGracePeriodSeconds": 30,
        "dnsPolicy": "ClusterFirst",
        "serviceAccountName": "apache-service-account",
        "serviceAccount": "apache-service-account",

So gatekeeper-library's allow-privilege-escalation references input.review.object.spec.containers and finds an array of containers like "apache". Similarly, you could modify the policy code to reference input.review.object.spec.serviceAccount and find "apache-service-account". From there, it's a matter of using that information to make sure the rule "violation" only matches if the service account is one you want to apply to.

Beyond that, it's possible to then take the expected service account name and make it a ConstraintTemplate parameter, to make your new policy more flexible/useable.

Hope this helps!