Enforcing Compliance of Container Environment Variables
We’re excited to present the new environment-variable-policy to Kubewarden users. With this policy, you will now be able to inspect init containers and ephemeral containers. You can also restrict their usage by reviewing the names and values defined under the containers’ env[*] field.
As always, the policy can be found in ArtifactHub and all the artifacts, including the BOM files, are signed with Sigstore.
What is useful about the new environment-variable policy?
This policy complements the recently released env-variable-secrets-scanner policy. Both policies focus on validating the environment values provided to Kubernetes Pod objects. In this new policy, users can validate which variable names and values their resources can have.
The policy controls the environment variable defined in the containers using the four operators described in the next sections.
anyIn
anyIn
works as a deny list of your usage of environment variables. It checks if any of the environmentVariables
are in the Pod/Workload resource:
For example, given the following configuration:
settings: rules: - reject: anyIn environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2"
The following Pod would be rejected:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar"
But the next one would be accepted:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo3" value: "bar3"
anyNotIn
anyNotIn
works as an allow list. Checks if any of the environmentVariables
are not in the Pod/Workload resource:
For example, given the following configuration:
settings: rules: - reject: anyNotIn environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2"
The following Pod would be rejected:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" - name: "foo3" value: "bar3"
But the next one would be accepted:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" - name: "foo2" value: "bar2"
allAreUsed
allAreUsed
the container cannot use all listed environment variables at once. Checks if all of the environmentVariables
are in the Pod/Workload resource:
For example, given the following configuration:
settings: rules: - reject: allAreUsed environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2" - name: "foo3" value: "bar3"
The following Pod would be rejected:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" - name: "foo2" value: "bar2" - name: "foo3" value: "bar3"
But the next one would be accepted:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" - name: "foo3" value: "bar3"
notAllAreUsed
notAllAreUsed
the container can use all listed environment variables at once. But it cannot has only a subset of them.
Checks if all of the environmentVariables
are not in the Pod/Workload resource
For example, given the following configuration:
settings: rules: - reject: notAllAreUsed environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2"
The following Pod would be rejected:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar"
But the next one would be accepted:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" - name: "foo2" value: "bar2"
Using multiple rules
The user is allowed to define multiple rules in the policy settings. The resource must be approved by all of them to be accepted into the cluster.
Let’s take a look at an example. Consider the following rules:
kubectl apply -f - <<EOF apiVersion: policies.kubewarden.io/v1 kind: ClusterAdmissionPolicy metadata: name: environment-variable-policy spec: module: ghcr.io/kubewarden/policies/environment-variable-policy:v0.1.1 mutating: false rules: - apiGroups: ["apps"] apiVersions: ["v1"] resources: ["deployments"] operations: - CREATE - UPDATE settings: rules: - reject: anyIn environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2" - reject: allAreUsed environmentVariables: - name: "foo3" value: "bar3" - name: "foo4" value: "bar4" EOF
The following two Deployments
will be rejected. The first rule will reject the first one:
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: template-nginx template: metadata: labels: app: template-nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" EOF Error from server: error when creating "STDIN": admission webhook "clusterwide-environment-variable-policy.kubewarden.admission" denied the request: Resource cannot define any of the environment variables from the rule.
The second Deployment
will be rejected by the second rule:
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: template-nginx template: metadata: labels: app: template-nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo3" value: "bar3" - name: "foo4" value: "bar4" EOF Error from server: error when creating "STDIN": admission webhook "clusterwide-environment-variable-policy.kubewarden.admission" denied the request: Resource cannot have all the environment variables from the rule defined.
But when we try to deploy a resource that respects both rules, it will be created with no issues:
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: template-nginx template: metadata: labels: app: template-nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo3" value: "bar3" EOF deployment.apps/nginx-deployment created
A use-case example
Let’s see how users can enforce that their resources have minimum required environment variables. For that, it possible to use the allAreUsed
operator:
kubectl apply -f - <<EOF apiVersion: policies.kubewarden.io/v1 kind: ClusterAdmissionPolicy metadata: name: environment-variable-policy spec: module: ghcr.io/kubewarden/policies/environment-variable-policy:v0.1.1 mutating: false rules: - apiGroups: ["apps"] apiVersions: ["v1"] resources: ["deployments"] operations: - CREATE - UPDATE settings: rules: - reject: anyIn environmentVariables: - name: "foo" value: "bar" - name: "foo2" value: "bar2" EOF
With the above policy only resources that have all the variables defined in the environmentVariables
field will be allowed.
Now try to deploy a resource that violates that rule:
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: template-nginx template: metadata: labels: app: template-nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 env: - name: "foo" value: "bar" EOF Error from server: error when creating "STDIN": admission webhook "clusterwide-environment-variable-policy.kubewarden.admission" denied the request: Resource cannot define any of the environment variables from the rule.
Summary
We hope this article provided you with a nice overview of the potential use cases of this policy and how to use it. Give it a try and, as usual, we look forward to your feedback 🙂
Have ideas for new policies? Would you like more features on existing ones? Drop us a line at #kubewarden on Slack!
Related Articles
May 03rd, 2023
Hybrid Boot and SEV-SNP support in AWS EC2
Oct 15th, 2024
Ensuring High Availability with Cloud-Managed Kubernetes
Nov 17th, 2024