Known limitations

This document tracks the current, known limitations of runtime-enforcer. Some are explicit design decisions, and some are constraints inherited from upstream components (kernel/eBPF, Kubernetes, container runtimes). The goal is to help you understand the limitations and make informed decisions about your runtime-enforcer deployment.

Learning cap: 100 allowed executables per proposal

During learning, runtime-enforcer writes observed executable paths into a WorkloadPolicyProposal under spec.rulesByContainer[*].executables.allowed.

To bound proposal growth, the learning controller stops adding new entries once the proposal contains 100 distinct allowed executables in total (summed across all containers in rulesByContainer). This is a design decision.

  • Impact: if a workload executes more than 100 distinct executables, the proposal becomes “full” and additional executables won’t be learned automatically. In that case you may need to curate and trim the list or manage policy contents manually.

In some scenarios the full workload name is not extracted

With NRI, runtime-enforcer derives the workload name from the pod name format and a small set of well-known labels. In some scenarios this information isn’t sufficient to reconstruct the original controller name.

This happens when Kubernetes truncates pod names due to the 63-character limit (common with long Deployment/DaemonSet names), which can remove parts of the name and/or separators that would otherwise allow reliable parsing.

In these cases, runtime-enforcer may only be able to report a shortened, best-effort workload name and won’t be able to extract the full workload name.

  • Impact: workload names shown in policy proposals and violation reporting can be incomplete and may not exactly match the original Kubernetes resource name. Since workload type and name name is also used to derive the WorkloadPolicyProposal resource name, the proposal may be created under an unexpected name, which can make it look like learning didn’t happen.

Static pods: API-server Pod UID can’t be resolved via NRI

For Kubernetes static pods, the Pod UID used by the kubelet and the Pod UID assigned by the Kubernetes API server can differ.

In the NRI context, runtime-enforcer can’t reliably retrieve the API-server Pod UID for static pods, and instead relies on the UID available via NRI.

  • Impact: when correlating runtime-enforcer events/policies with Kubernetes objects, the Pod UID may not match what you see on the Pod object returned by the Kubernetes API for static pods.

VAP-based protections aren’t applied prior to Kubernetes 1.30

runtime-enforcer uses Kubernetes Validating Admission Policy (VAP) to enforce admission-time protections (for example, preventing changes that would add/remove/update the security.rancher.io/policy label on Pods).

VAP is only available as admissionregistration.k8s.io/v1 starting in Kubernetes 1.30. On Kubernetes versions before v1.30, runtime-enforcer doesn’t apply any VAP-based protections.

Earlier Kubernetes versions exposed Validating Admission Policy as admissionregistration.k8s.io/v1beta1, but runtime-enforcer won’t support it. This is a design decision.

  • Impact: on Kubernetes 1.29 and earlier, changes that should be blocked by VAP (such as mutating security.rancher.io/policy on existing Pods) may be allowed.

NRI may not be enabled by default for containerd prior to v2.0

runtime-enforcer requires NRI to be enabled in the container runtime. On containerd versions prior to v2.0, NRI may be available but not enabled by default, depending on how containerd is packaged/configured in your distribution.

  • Impact: if NRI isn’t enabled, runtime-enforcer won’t be able to learn and resolve container identity correctly and may fail to operate as expected. You have to enable NRI manually.

ReplicaSet isn’t supported as a workload for learning

runtime-enforcer doesn’t currently learn policies with ReplicaSet as the workload identity.

In the NRI context, runtime-enforcer derives the “workload kind/name” primarily from the pod name and a small set of well-known labels. This works for common workload types (for example, Deployment, DaemonSet), but it isn’t sufficient to reliably identify a pod as belonging to a ReplicaSet in the general case.

As a result, pods created by standalone ReplicaSet may be treated as plain Pod workloads for learning and reporting purposes.

  • Impact: policy proposals and violation reporting may not group/label these pods under a ReplicaSet workload, and may not match the workload identity you expect. Please use other workload types (for example, Deployment, DaemonSet) when you want reliable workload attribution and policy learning.

arm64: kernels prior to 6.4 are not supported

On arm64/aarch64, runtime-enforcer requires a Linux kernel version >= 6.4.

  • Impact: on older arm64 kernels, runtime-enforcer may fail to load eBPF programs or may not function correctly.

cri-dockerd is not supported

runtime-enforcer doesn’t support running Kubernetes with Docker via cri-dockerd, and there are no plans to add support.

runtime-enforcer relies on container-runtime integration that provides consistent container/pod identity information (NRI). cri-dockerd doesn’t meet this requirement, so container attribution and policy enforcement behavior isn’t reliable in that environment.

  • Impact: runtime-enforcer may fail to start correctly, or may be unable to reliably attribute processes to containers/workloads. Please use a supported container runtime (containerd or CRI-O) instead.