Skip to main content

Removing gitRepo Volumes in Kubernetes

The in-tree gitRepo volume driver has been a recurring vector for remote code execution in Kubernetes clusters. According to the official Kubernetes volumes documentation, "Kubernetes 1.36 does not include the gitRepo volume driver. The last version that provided a way to use this driver was Kubernetes v1.35, and it has been deprecated since the v1.11 minor release." This article explains the security motivation for the removal, the exact version timeline, and how to migrate existing workloads.


1. Why gitRepo Was Removed

Issue: The gitRepo volume driver clones a Git repository into an emptyDir-style volume as part of pod startup. The clone is executed by the kubelet on the node, and the repository's own Git hooks can be invoked during the operation — giving any user with pod-creation rights a path to remote code execution on the underlying node.
Fix: Migrate workloads to an init container that performs the clone inside the pod, and upgrade to Kubernetes v1.36, which removes the driver entirely.

CVE-2024-10220 — Arbitrary Command Execution via gitRepo

  • CVSS: 8.1 (High) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
  • Impact: A user with the ability to create a pod and associate a gitRepo volume can execute arbitrary commands beyond the container boundary. The vulnerability leverages the hooks folder in the target repository to run arbitrary commands outside of the container's boundary.
  • Affected kubelet versions: v1.30.0 to v1.30.2, v1.29.0 to v1.29.6, and all versions up to and including v1.28.11.
  • Fixed in: kubelet v1.31.0, v1.30.3, v1.29.7, and v1.28.12.

KEP-5040 summarises the broader motivation as: "Remove a vector for remote code execution through an ancient and unmaintained volume plugin."


2. Removal Timeline

VersionBehavior
v1.11gitRepo volume is marked deprecated.
v1.31 / v1.30.3 / v1.29.7 / v1.28.12Kubelet patches released for CVE-2024-10220.
v1.33Feature gate GitRepoVolumeDriver is introduced and defaults to false. Cluster administrators can still opt in by setting the gate to true.
v1.35Last Kubernetes version that ships the gitRepo volume driver.
v1.36Kubernetes v1.36 does not include the gitRepo volume driver.

The GitRepoVolumeDriver feature gate is listed as Deprecated in the official feature gates reference, introduced at v1.33 with a default value of false.


3. Migration: Use an Init Container

Issue: Workloads that depend on a gitRepo volume do not start on clusters running Kubernetes v1.36 or later.
Fix: Replace the gitRepo volume with an emptyDir volume populated by a dedicated init container that performs the clone. This is the pattern recommended by the official Kubernetes volumes documentation: "you can mount an emptyDir volume into an init container that clones the repo using Git, then mount the EmptyDir into the Pod's container."

Example Manifest

apiVersion: v1
kind: Pod
metadata:
name: git-cloned-workload
spec:
initContainers:
- name: git-clone
image: alpine/git:latest
args:
- clone
- https://github.com/example/repo.git
- /repo
volumeMounts:
- name: source
mountPath: /repo
containers:
- name: app
image: app-image:1.0
volumeMounts:
- name: source
mountPath: /repo
readOnly: true
volumes:
- name: source
emptyDir: {}

Why This Is Safer

  • The clone runs inside a dedicated container image with its own filesystem and user context, not directly on the node.
  • The application container can mount the cloned repository as read-only, preventing tampering at runtime.
  • Git hook execution is confined to the init container, not the node's kubelet process.

4. Detect and Block gitRepo Usage

Audit existing workloads

Before upgrading a cluster to v1.36, audit all workloads for existing gitRepo references:

kubectl get pods --all-namespaces -o json \
| jq -r '.items[]
| select([.spec.volumes[]?.gitRepo] | any)
| "\(.metadata.namespace)/\(.metadata.name)"'

Extend the same check to the pod templates of other workload resources (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs) by scanning .spec.template.spec.volumes[].

Block new workloads with ValidatingAdmissionPolicy

Kubernetes documentation provides an official CEL expression that rejects pods using gitRepo volumes, deployable via a built-in ValidatingAdmissionPolicy:

!has(object.spec.volumes) || !object.spec.volumes.exists(v, has(v.gitRepo))

This expression passes when the pod has no volumes at all, or when none of the volumes define a gitRepo field. External admission controllers such as Kyverno and OPA Gatekeeper can enforce the equivalent rule where ValidatingAdmissionPolicy is not available.


References

This article is based on information from the following official sources:

  1. Volumes — gitRepo (disabled) - Kubernetes Documentation
  2. Feature Gates — GitRepoVolumeDriver - Kubernetes Documentation
  3. Kubernetes v1.36 Sneak Peek - Kubernetes Blog
  4. CVE-2024-10220: Arbitrary command execution through gitRepo volume - Kubernetes Security Response Committee
  5. KEP-5040: Remove gitRepo volume driver - Kubernetes Enhancement Proposals