Enforce Runtime Policies that Block Violating Actions (RHACS)

Duration: ~25 minutes

Overview

201-11 Elevation of privilege / Tampering at runtime: a pod that was admitted can still run dnf, a shell gadget, or a packager. acs-06 already killed Alpine apk on the patient-portal frontend. This lab does the same job for a Red Hat UBI workload: clone Red Hat Package Manager Execution, set Inform and enforce at Runtime, and prove RHACS kills the pod when dnf/yum/microdnf runs.

The sensor is the ACS Collector. The response is OpenShift killing the pod so cluster state stays consistent.

Why it matters

Admission cannot see a process that did not exist at create. Runtime enforce is the control that turns “we alerted” into “the violating action did not finish.” Package managers in running containers are how attackers install a tool after they get exec.

What does it solve

  • Inform-only policies that page the SOC while the process keeps running

  • Alpine-only runtime demos on a fleet that actually runs UBI

  • Confusion between “scale to zero” (not what ACS runtime does) and kill this pod

Your Mission

Deploy a UBI probe (and reuse 301-02 Python if it is still up), clone the Red Hat package-manager policy with runtime enforce, exec dnf or microdnf, and watch the pod get killed.

Prerequisites

  • RHACS Central reachable (acs-00)

  • Cluster-admin or permission to exec in the lab namespace

  • Collector running on worker nodes

Click each step only if you need a hint.

Part A: Workload

Deploy the UBI package-manager probe

ubi9/ubi includes dnf. Restricted PSA + runAsNonRoot. Leave 301-02-python running if you still have it—ACS will show both namespaces.

oc apply -f ~/openshift-security-roadshow/setup/acs-runtime-lab/pkgmgr-probe.yaml
oc rollout status deploy/pkgmgr-probe -n 301-04-runtime --timeout=120s
oc get route central -n stackrox -o jsonpath='https://{.spec.host}{"\n"}'
Probe Running. Open the Central URL for Policy Management.

Part B: Clone and enforce

Find Red Hat Package Manager Execution

In RHACS: Platform Configuration → Policy Management. Search Red Hat Package Manager Execution (criteria include yum / dnf / rpm / microdnf).

If you already cloned the Alpine policy in acs-06, leave it. This clone is the UBI equivalent.

Open the policy and confirm it is Runtime capable and currently Inform (or disabled). You will clone, not edit the default.
Clone with Inform and enforce at Runtime

Actions → Clone policy. Name:

Red Hat Package Manager Execution - Runtime

Then Policy Behavior → Actions:

  • Lifecycle: Runtime

  • Enable Inform and enforce

  • Enforcement: Enforce at Runtime (kills the pod; it does not scale the Deployment to zero)

Save the policy.

Same click path as acs-06 runtime enforce, different policy name.

Part C: Trigger the kill

Watch events, then exec the package manager
oc get events -n 301-04-runtime -w

In a second terminal:

POD=$(oc get pod -l app=pkgmgr-probe -n 301-04-runtime -o jsonpath='{.items[0].metadata.name}')
oc exec "$POD" -n 301-04-runtime -- /bin/bash -c 'dnf --version || microdnf --version || yum --version'
The exec session ends (often exit 137). Events show RHACS Killing the pod and the Deployment creating a replacement. In Central Violations, filter policy name and namespace 301-04-runtime.
Optional: confirm the Python app is still the catalog image
oc get deploy python-app -n 301-02-python -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' 2>/dev/null || echo "301-02-python not deployed (optional)"
If 301-02 is up, you now have a digest-pinned Python service and a UBI probe ACS will kill. Hunt both in 301-05.

Debrief

RHACS runtime enforce blocks the violating action by killing the pod. That is EoP/Tampering at runtime, not a new detection product. Build-time is removing the packager from the image (101-11, 201-04). Deploy-time is acs-02.

What breaks without this:

  • Inform-only → the process finishes, the ticket arrives later

  • Alpine-only demos → UBI fleets never exercise the policy they actually need

  • Assuming ACS scales the Deployment to zero → replica comes back, which is correct; the process did not persist

save the cloned policy. Collector must be running on the node that scheduled the probe.
Next is 301-05 — join this kill to kube-apiserver exec in Splunk.
giphy

Cleanup

Deletes 301-04-runtime. The cloned ACS policy stays in Central unless you delete it in the UI (leave it if you are continuing to 301-05).

cd ~/ocp5-rhacs-showroom
bash setup/lab-cleanup.sh --module 301-04