Runtime Enforcer phases: learn, monitor, protect
This document explains the three phases of runtime-enforcer and how to move between them.
Learn phase
What happens during this phase
-
Processes aren’t blocked.
-
Runtime-enforcer observes process executions in your workloads and learns the executable paths that run.
-
For each learned executable, runtime-enforcer creates or updates a
WorkloadPolicyProposalin the workload namespace and adds the executable path under.spec.rulesByContainer[CONTAINER_NAME].executables.allowed.
|
Learn is based on exec events observed after the agent is running. The agent does not reconstruct what happened before it started. |
This means:
-
If a workload was already running before runtime-enforcer started, we can’t propose the full set of processes it already executed in the past.
-
You only learn processes that exec after runtime-enforcer is running (for long-lived pods that rarely execute, you may learn little or nothing until a restart or other activity happens).
Operationally, if you want complete proposals, enable learning first and then (re)start the workloads you want to learn.
How to enter and leave the Learn phase
-
Enter
-
Check learning is enabled on some namespaces:
values.learning.namespaceSelector -
No per-workload configuration is required to start generating proposals (proposals are created as exec events are observed).
-
-
Leave
-
Promote the corresponding proposal by setting the label:
security.rancher.io/promote=<monitor|protect> -
Alternatively, use the kubectl plugin:
kubectl runtime-enforcer proposal promote <PROPOSAL_NAME>. -
This triggers creation of a
WorkloadPolicy(defaulting tomode: monitor), with theworkloadpolicy.security.rancher.io/promoted-fromlabel set so the promotion relationship is explicit. -
The
WorkloadPolicyProposalobject is deleted after the promotion. Under rare conditions, caches might not be immediately updated, causing theWorkloadPolicyProposalto be created again. In those cases, a periodic cleanup removes the leftover proposals.
-
|
If you create a |
CRDs created/updated during this phase
-
Created/updated:
WorkloadPolicyProposal(security.rancher.io/v1alpha1)-
Name format is derived from workload kind/name (for example,
deploy-NAME,ds-NAME, and so on). -
The proposal is linked back to the owning workload via
ownerReferences. If the owning workload is deleted, so is the proposal.
-
Monitor phase
What happens during this phase
-
Processes aren’t blocked.
-
When a process exec isn’t on the allow-list for the container:
-
the exec is allowed
-
a violation event is emitted and exported via OpenTelemetry with
action=monitor.
-
|
|
How to enter and leave the phase
-
Enter
-
A
WorkloadPolicyis created (usually by approving a proposal), and ensure it has:-
.spec.mode: monitor -
.spec.rulesByContainerpopulated with allowed executables per container name
-
-
Bind workloads/pods to the policy by applying the label:
security.rancher.io/policy: WORKLOAD_POLICY_NAME. The label must be applied to the Pod. When dealing with workload types (such as Deployment), make sure the label is specified inside of thePodTemplateSpec.Runtime-enforcer uses this label to decide which pods the policy applies to.
The
security.rancher.io/policylabel must be set at Pod creation time only. Changing this label on a running Pod (adding, removing, or modifying its value) is prohibited.
-
|
By default in the runtime-enforcer Helm chart, pods with a non-existing policy
are prevented from running. This ensures that when a pod starts, it has all
protections ready. To enable fail-open behavior, set |
-
Leave
-
Monitor → Protect: update the
WorkloadPolicyand set.spec.mode: protect(orkubectl runtime-enforcer policy protect <POLICY_NAME>). -
Monitor → Learn: remove the binding label from workloads/pods, delete the
WorkloadPolicy, then delete the existingWorkloadPolicyProposal, or set remove thesecurity.rancher.io/promotelabel from the proposal to resume learning.
-
Protect phase
What happens during this phase
-
Processes are blocked when they violate the allow-list.
-
On an attempted exec that is not allowed:
-
a violation event is emitted (same as monitor, but with
action=protect) -
the exec fails, which typically appears as “Permission denied” in the container/process
-
the process does not start; depending on what was blocked this can cause application errors, crash loops, or failed jobs.
-
|
The same container scoping rule applies in protect mode: only containers present
in |
How to enter and leave the phase
-
Enter
-
Ensure the workload is bound via
security.rancher.io/policy: WORKLOAD_POLICY_NAME. The label must be applied to the Pod. When dealing with workload types (such as Deployment), make sure the label is specified inside of thePodTemplateSpec. + WARNING: Thesecurity.rancher.io/policylabel must be set at Pod creation time only. Changing this label on a running Pod (adding, removing, or modifying its value) is prohibited. -
Update the
WorkloadPolicyto set.spec.mode: protect.
-
-
Leave
-
Protect → Monitor: update the
WorkloadPolicyand set.spec.mode: monitor(orkubectl runtime-enforcer policy monitor <POLICY_NAME>). -
Protect → Learn: remove the binding label from workloads/pods, delete the
WorkloadPolicy, then delete the existingWorkloadPolicyProposal, or set remove thesecurity.rancher.io/promotelabel from the proposal to resume learning.
-
Quick mapping to CRDs
-
Learn phase: the system observes process executions and creates/updates
WorkloadPolicyProposalobjects. -
Monitor phase: a
WorkloadPolicyexists with.spec.mode: monitor(violations are reported, not blocked). -
Protect phase: a
WorkloadPolicyexists with.spec.mode: protect(violations are reported and blocked).
|
The |