Introduction
So far, we have seen about two OPA use cases and their importance. Today, we’re going to look at a policy used to deny unauthorized configmap volumes from being mounted.
What is a ConfigMap?
Configmaps are similar to Kubernetes Secrets but are used to store non confidential configurations that an application requires like environmental variables that need to be set or command line arguments that have to be run. An application often requires multiple configmaps. So the common practice is to have a separate volume to store all the configmaps and then access them by mounting them.
Why do we need this policy?
As configmaps contain configurations needed for a particular service, we always want the correct configurations to be used. Not restricting the configmaps that can be used by a pod, an attacker, after compromising a pod, might use his own configmap with some malicious configurations rather than using the intended configmap.
Deny Unauthorized ConfigMap Volumes
template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sdenyconfigmap annotations: description: Blocks unauthorized configmaps. spec: crd: spec: names: kind: K8sDenyConfigMap validation: # Schema for the `parameters` field openAPIV3Schema: properties: paths: type: array items: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sdenyconfigmap violation[{"msg": msg, "details": {}}] { input.review.object.kind == "Pod" allowedconfigmaps := input.parameters.configmaps configmap := input.review.object.spec.volumes[_].configMap.name not contains(allowedconfigmaps,configmap) msg := sprintf("%v - configmap not allowed",[configmap]) } contains(allowedconfigmaps,configmap) { configmap == allowedconfigmaps[_] }
Rego Policy explained:
- Check if the kind is “Pod”
- Store the allowed configmap names from parameter in the “allowedconfigmaps” variable.
- Store the name of the configmap used in the deployment file in the “configmap” variable.
- Since we need to deny if the “configmap” is not in “allowedconfigmaps”, we check if it’s in “allowedconfigmaps” by calling the “contains” and then use “not”. So it will return true only if the path in “configmap” is not in “allowedconfigmaps”.
- The message gets printed if all the above returns true.
constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sDenyConfigMap metadata: name: deny-config-map spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] parameters: allowed: ["mysql", "es"]
We have allowed the configmaps with the names “mysql” and “es”.
deployment-non-violation.yaml
apiVersion: v1 kind: Pod metadata: name: configmap-demo-pod spec: containers: - name: demo image: alpine volumeMounts: - name: config mountPath: "/config" readOnly: true volumes: - name: mysql configMap: name: demo
This file will get created without any issues as the configmap “mysql” is allowed and can be used by a pod.
deployment-violation.yaml
apiVersion: v1 kind: Pod metadata: name: configmap-demo-pod spec: containers: - name: demo image: alpine volumeMounts: - name: config mountPath: "/root" readOnly: true volumes: - name: configdata configMap: name: demo
This will not get created as the configmap named “configdata” is not allowed.
Conclusion
This use case is very important as every application needs configmaps and we might end up not restricting the paths that can be mounted. The takeaways are:
- We should always remember to prohibit unauthorized configmap volumes that can be used.
- Another important thing to keep in mind though it’s not related to OPA policy is that we should never store confidential information in configmaps as it’s not meant for that purpose.
Other related articles:
- OPA Gatekeeper Audit and Logging using EFK
- A Series of Blog Posts on using OPA Policies & Gatekeeper for Kubernetes Security
Practice here:
https://www.katacoda.com/cloudsecops/courses/opagatekeeper-policy/configmap
References:
- https://github.com/open-policy-agent/gatekeeper
- https://github.com/open-policy-agent/gatekeeper-library
Thank you for reading! – Vishal Pranav and Setu Parimi
Sign up for the blog directly here.
Check out our professional services here.
Feedback is welcome! For professional services, fan mail, hate mail, or whatever else, contact [email protected]
0 Comments