Add validating admission policy to restrict upstream driver access (#482)

* Add validating admission policy to restrict upstream driver access

Signed-off-by: Kevin Fox <[email protected]>

* Update charts/spire/charts/spiffe-csi-driver/templates/policy.yaml

Signed-off-by: kfox1111 <[email protected]>

* Fix logic

Signed-off-by: Kevin Fox <[email protected]>

* Upgrade helm

Signed-off-by: Kevin Fox <[email protected]>

* Upgrade kind and fix node version

Signed-off-by: Kevin Fox <[email protected]>

* Upgrade kind and fix node version

Signed-off-by: Kevin Fox <[email protected]>

* Upgrade kind and fix node version

Signed-off-by: Kevin Fox <[email protected]>

* Upgrade kind and fix node version

Signed-off-by: Kevin Fox <[email protected]>

* Add version info

Signed-off-by: Kevin Fox <[email protected]>

* Add version info

Signed-off-by: Kevin Fox <[email protected]>

* Fix kind version

Signed-off-by: Kevin Fox <[email protected]>

* Fix kind version

Signed-off-by: Kevin Fox <[email protected]>

* Fix kind version

Signed-off-by: Kevin Fox <[email protected]>

* Fix detection

Signed-off-by: Kevin Fox <[email protected]>

* Just for testing...

Signed-off-by: Kevin Fox <[email protected]>

* Just for testing...

Signed-off-by: Kevin Fox <[email protected]>

* Just for testing

Signed-off-by: Kevin Fox <[email protected]>

* Fix policy

Signed-off-by: Kevin Fox <[email protected]>

* Fix policy

Signed-off-by: Kevin Fox <[email protected]>

* Fix policy

Signed-off-by: Kevin Fox <[email protected]>

* Incorperate feedback

Signed-off-by: Kevin Fox <[email protected]>

* Update charts/spire/charts/spiffe-csi-driver/values.yaml

Co-authored-by: Faisal Memon <[email protected]>
Signed-off-by: kfox1111 <[email protected]>

* Update docs

Signed-off-by: Kevin Fox <[email protected]>

---------

Signed-off-by: Kevin Fox <[email protected]>
Signed-off-by: kfox1111 <[email protected]>
Co-authored-by: Faisal Memon <[email protected]>
This commit is contained in:
kfox1111
2024-10-26 07:40:29 -07:00
committed by GitHub
co-authored by Faisal Memon
parent a7368eee1f
commit a360646842
9 changed files with 144 additions and 78 deletions
+12 -12
View File
@@ -30,9 +30,9 @@ jobs:
strategy:
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
steps:
- run: 'echo "Skipping tests"'
@@ -74,9 +74,9 @@ jobs:
strategy:
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
example:
- ${{ fromJson(needs.build-matrix.outputs.examples) }}
@@ -92,9 +92,9 @@ jobs:
strategy:
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
example:
- ${{ fromJson(needs.build-matrix.outputs.integrationtests) }}
@@ -110,9 +110,9 @@ jobs:
strategy:
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
steps:
- run: 'echo "Skipping upgrade-test"'
+18 -17
View File
@@ -21,9 +21,9 @@ concurrency:
cancel-in-progress: true
env:
HELM_VERSION: v3.12.0
HELM_VERSION: v3.16.2
PYTHON_VERSION: 3.11.3
KIND_VERSION: v0.19.0
KIND_VERSION: v0.24.0
CHART_TESTING_VERSION: v3.8.0
jobs:
@@ -130,9 +130,9 @@ jobs:
# Kubernetes, but can go back farther as long as we don't need heroics
# to pull it off (i.e. kubectl version juggling).
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
steps:
- name: Checkout
@@ -218,9 +218,9 @@ jobs:
fail-fast: false
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
example:
- ${{ fromJson(needs.build-matrix.outputs.examples) }}
@@ -243,7 +243,7 @@ jobs:
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
node_image: kindest/node:v1.26.4
node_image: kindest/node:${{ matrix.k8s }}
config: .github/kind/conf/kind-config.yaml
verbosity: 1
@@ -256,6 +256,7 @@ jobs:
kubectl create namespace spire-server
helm install -n spire-server spire-crds charts/spire-crds
fi
export K8S="${{ matrix.k8s }}"
${{ matrix.example }}/run-tests.sh
integration-test:
@@ -269,9 +270,9 @@ jobs:
fail-fast: false
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
integrationtest:
- ${{ fromJson(needs.build-matrix.outputs.integrationtests) }}
@@ -294,7 +295,7 @@ jobs:
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
node_image: kindest/node:v1.26.4
node_image: kindest/node:${{ matrix.k8s }}
config: .github/kind/conf/kind-config.yaml
verbosity: 1
@@ -314,9 +315,9 @@ jobs:
fail-fast: false
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
- v1.31.1
- v1.30.4
- v1.29.8
steps:
- name: Checkout
@@ -337,7 +338,7 @@ jobs:
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
node_image: kindest/node:v1.26.4
node_image: kindest/node:${{ matrix.k8s }}
config: .github/kind/conf/kind-config.yaml
verbosity: 1
+48 -46
View File
@@ -25,50 +25,52 @@ A Helm chart to install the SPIFFE CSI driver.
### SPIFFE CSI Driver Chart parameters
| Name | Description | Value |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `pluginName` | Set the csi driver name deployed to Kubernetes. | `csi.spiffe.io` |
| `image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `image.repository` | The repository within the registry | `spiffe/spiffe-csi-driver` |
| `image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
| `resources` | Resource requests and limits for spiffe-csi-driver | `{}` |
| `healthChecks.port` | The healthcheck port for spiffe-csi-driver | `9809` |
| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` |
| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` |
| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` |
| `livenessProbe.timeoutSeconds` | Timeout value in seconds for livenessProbe | `5` |
| `imagePullSecrets` | Image pull secret details for spiffe-csi-driver | `[]` |
| `nameOverride` | Name override for spiffe-csi-driver | `""` |
| `namespaceOverride` | Namespace to install spiffe-csi-driver | `""` |
| `fullnameOverride` | Full name override for spiffe-csi-driver | `""` |
| `csiDriverLabels` | Labels to apply to the CSIDriver | `{}` |
| `initContainers` | Init Containers to apply to the CSI Driver DaemonSet | `[]` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated. | `""` |
| `podAnnotations` | Pod annotations for spiffe-csi-driver | `{}` |
| `podSecurityContext` | Security context for CSI driver pods | `{}` |
| `securityContext.readOnlyRootFilesystem` | Flag for read only root filesystem | `true` |
| `securityContext.privileged` | Flag for specifying privileged mode | `true` |
| `nodeSelector` | Node selector for CSI driver pods | `{}` |
| `tolerations` | Tolerations for CSI driver pods | `[]` |
| `affinity` | Node affinity | `{}` |
| `nodeDriverRegistrar.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` |
| `nodeDriverRegistrar.image.repository` | The repository within the registry | `sig-storage/csi-node-driver-registrar` |
| `nodeDriverRegistrar.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.4` |
| `nodeDriverRegistrar.resources` | Resource requests and limits for CSI driver pods | `{}` |
| `agentSocketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` |
| `kubeletPath` | Path to kubelet file | `/var/lib/kubelet` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `restrictedScc.enabled` | Enables the creation of a SecurityContextConstraint based on the restricted SCC with CSI volume support | `false` |
| `restrictedScc.name` | Set the name of the restricted SCC with CSI support | `""` |
| `restrictedScc.version` | Version of the restricted SCC | `2` |
| `selinux.enabled` | Enable selinux support | `false` |
| `selinux.context` | Which selinux context to use | `container_file_t` |
| `selinux.image.registry` | The OCI registry to pull the image from | `registry.access.redhat.com` |
| `selinux.image.repository` | The repository within the registry | `ubi9` |
| `selinux.image.pullPolicy` | The image pull policy | `Always` |
| `selinux.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest` |
| Name | Description | Value |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------- |
| `pluginName` | Set the csi driver name deployed to Kubernetes. | `csi.spiffe.io` |
| `image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `image.repository` | The repository within the registry | `spiffe/spiffe-csi-driver` |
| `image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
| `resources` | Resource requests and limits for spiffe-csi-driver | `{}` |
| `healthChecks.port` | The healthcheck port for spiffe-csi-driver | `9809` |
| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` |
| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` |
| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` |
| `livenessProbe.timeoutSeconds` | Timeout value in seconds for livenessProbe | `5` |
| `imagePullSecrets` | Image pull secret details for spiffe-csi-driver | `[]` |
| `nameOverride` | Name override for spiffe-csi-driver | `""` |
| `namespaceOverride` | Namespace to install spiffe-csi-driver | `""` |
| `serverNamespaceOverride` | Override the namespace that the spire-server is installed into | `""` |
| `validatingAdmissionPolicy.enabled` | When set to auto, the validatingAdmissionPolicy will be enabled when the pluginName == "upstream.csi.spiffe.io" and k8s >= 1.30.0. Valid options are [auto, true, false] | `auto` |
| `fullnameOverride` | Full name override for spiffe-csi-driver | `""` |
| `csiDriverLabels` | Labels to apply to the CSIDriver | `{}` |
| `initContainers` | Init Containers to apply to the CSI Driver DaemonSet | `[]` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated. | `""` |
| `podAnnotations` | Pod annotations for spiffe-csi-driver | `{}` |
| `podSecurityContext` | Security context for CSI driver pods | `{}` |
| `securityContext.readOnlyRootFilesystem` | Flag for read only root filesystem | `true` |
| `securityContext.privileged` | Flag for specifying privileged mode | `true` |
| `nodeSelector` | Node selector for CSI driver pods | `{}` |
| `tolerations` | Tolerations for CSI driver pods | `[]` |
| `affinity` | Node affinity | `{}` |
| `nodeDriverRegistrar.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` |
| `nodeDriverRegistrar.image.repository` | The repository within the registry | `sig-storage/csi-node-driver-registrar` |
| `nodeDriverRegistrar.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.4` |
| `nodeDriverRegistrar.resources` | Resource requests and limits for CSI driver pods | `{}` |
| `agentSocketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` |
| `kubeletPath` | Path to kubelet file | `/var/lib/kubelet` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `restrictedScc.enabled` | Enables the creation of a SecurityContextConstraint based on the restricted SCC with CSI volume support | `false` |
| `restrictedScc.name` | Set the name of the restricted SCC with CSI support | `""` |
| `restrictedScc.version` | Version of the restricted SCC | `2` |
| `selinux.enabled` | Enable selinux support | `false` |
| `selinux.context` | Which selinux context to use | `container_file_t` |
| `selinux.image.registry` | The OCI registry to pull the image from | `registry.access.redhat.com` |
| `selinux.image.repository` | The repository within the registry | `ubi9` |
| `selinux.image.pullPolicy` | The image pull policy | `Always` |
| `selinux.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest` |
@@ -40,6 +40,23 @@ Allow the release namespace to be overridden for multi-namespace deployments in
{{- end -}}
{{- end -}}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts
*/}}
{{- define "spiffe-csi-driver.server-namespace" -}}
{{- if .Values.serverNamespaceOverride -}}
{{- .Values.serverNamespaceOverride -}}
{{- else if and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "namespaceLayout" true .Values.global) }}
{{- if ne (len (dig "spire" "namespaces" "server" "name" "" .Values.global)) 0 }}
{{- .Values.global.spire.namespaces.server.name }}
{{- else }}
{{- printf "spire-server" }}
{{- end }}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
@@ -0,0 +1,37 @@
{{- $upstream := eq .Values.pluginName "upstream.csi.spiffe.io" }}
{{- $detectedValidation := semverCompare ">=1.30-0" .Capabilities.KubeVersion.GitVersion -}}
{{- $policyEnabled := .Values.validatingAdmissionPolicy.enabled | toString }}
{{- $auto := eq $policyEnabled "auto" }}
{{- if or (eq $policyEnabled "true") (and $auto $upstream $detectedValidation) }}
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: {{ .Values.pluginName | quote }}
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: |
!object.spec.volumes.exists(c, has(c.csi) && has(c.csi.driver) && c.csi.driver == {{ .Values.pluginName | quote }})
message: 'you may not use the upstream.csi.spiffe.io csi driver'
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: {{ .Values.pluginName | quote }}
spec:
policyName: {{ .Values.pluginName | quote }}
validationActions: ["Deny"]
matchResources:
namespaceSelector:
matchExpressions:
- key: "kubernetes.io/metadata.name"
operator: NotIn
values:
- {{ include "spiffe-csi-driver.server-namespace" . | quote }}
{{- end }}
@@ -60,6 +60,13 @@ nameOverride: ""
## @param namespaceOverride Namespace to install spiffe-csi-driver
namespaceOverride: ""
## @param serverNamespaceOverride Override the namespace that the spire-server is installed into
serverNamespaceOverride: ""
validatingAdmissionPolicy:
## @param validatingAdmissionPolicy.enabled When set to auto, the validatingAdmissionPolicy will be enabled when the pluginName == "upstream.csi.spiffe.io" and k8s >= 1.30.0. Valid options are [auto, true, false]
enabled: auto
## @param fullnameOverride Full name override for spiffe-csi-driver
fullnameOverride: ""
-1
View File
@@ -5,4 +5,3 @@
tags:
nestedChildFull: true
+3 -1
View File
@@ -71,7 +71,9 @@ kubectl rollout status -n kube-system -w --timeout=1m deploy/coredns
for cluster in child other; do
KC="${SCRIPTPATH}/kubeconfig-${cluster}"
kind create cluster --name "${cluster}" --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}" --config "${SCRIPTPATH}/.test-files/${cluster}-kind-config.yaml"
kind create cluster --name "${cluster}" --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}" --config "${SCRIPTPATH}/.test-files/${cluster}-kind-config.yaml" --image "kindest/node:${K8S}"
kubectl version --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}"
md5sum "${KC}"
wc -l "${KC}"
+2 -1
View File
@@ -73,7 +73,7 @@ kubectl rollout status -n kube-system -w --timeout=1m deploy/coredns
for cluster in child; do
KC="${SCRIPTPATH}/kubeconfig-${cluster}"
kind create cluster --name "${cluster}" --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}" --config "${SCRIPTPATH}/.test-files/${cluster}-kind-config.yaml"
kind create cluster --name "${cluster}" --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}" --config "${SCRIPTPATH}/.test-files/${cluster}-kind-config.yaml" --image "kindest/node:${K8S}"
md5sum "${KC}"
wc -l "${KC}"
@@ -102,6 +102,7 @@ helm upgrade --install --create-namespace --namespace spire-mgmt --values "${COM
# The check is being too pedantic.
# shellcheck shell=bash disable=SC2043
for cluster in child; do
kubectl version --kubeconfig "${SCRIPTPATH}/kubeconfig-${cluster}"
KC="${SCRIPTPATH}/kubeconfig-${cluster}"
kubectl --kubeconfig "${KC}" get configmap -n spire-system spire-bundle-upstream -o yaml
kubectl --kubeconfig "${KC}" rollout restart daemonset spire-agent-downstream -n spire-system