Skip to main content

Make a Workload Ready to Register

Tasks

Change a discovered workload so it passes all seven readiness rules and shows Ready to register. Each section matches one rule. Replace the example names with your own.

Self-managed installations only

Workload Trust is available only in private, self-managed AIControls installations, on premises or in a cloud cluster that you run. It needs a dedicated cluster that you run, with Kyverno, Kyverno Runtime, and cluster OIDC and RBAC access in place. Nirmata-hosted (SaaS) workspaces don't include it. See Feature availability.

Before you begin​

  1. Go to Inventory → Workloads and select the workload. The verdict at the top of the drawer lists each rule that fails or is unknown, with what AIControls found and what to change.

  2. To list every workload that needs work, filter the table's Readiness column to Fix or Review.

For what each rule checks, see Workload readiness rules.

R1: Pod security​

Meet the Restricted Pod Security Standard. In the pod template of the workload, set:

spec:
template:
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: agent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
runAsNonRoot: true

Remove privileged: true, hostNetwork, hostPID, hostIPC, hostPath volumes, and host ports. The drawer's Kubernetes posture panel lists each failing check with its fix. If Baseline is acceptable for your fleet, an administrator can accept it under Readiness settings on the Workloads page.

R2: Least-privilege RBAC​

Bind the workload's ServiceAccount to a namespaced Role that reads only what the agent needs, with no wildcard verbs or resources:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: agent-reader
namespace: agents
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: agent-reader
namespace: agents
subjects:
- kind: ServiceAccount
name: agent
namespace: agents
roleRef:
kind: Role
name: agent-reader
apiGroup: rbac.authorization.k8s.io

Remove any binding to cluster-admin, any rule with * in verbs, resources, or apiGroups, and any write access. If the agent needs no Kubernetes API access, remove its bindings. If R2 is Unknown, turn on the workload posture access.

R3: No direct internet egress​

Add a default-deny egress NetworkPolicy to the namespace, and allow egress only to DNS and the AIControls proxy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: agents
spec:
podSelector: {}
policyTypes: ["Egress"]
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: aicontrols
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8443

Adjust the namespace name and ports to match your install. AIControls reads the policy, but it doesn't verify that your network plugin enforces it.

R4: Kyverno policies​

The fix depends on the policy. The Kyverno policies panel lists each failing policy and its message. Change the workload so each policy passes. If R4 is Unknown, check that Kyverno and its policies are installed, that background scans run, and that the policies match this workload. Under Selected policies, the panel names any selected policy that hasn't reported on the workload yet. Results older than 24 hours read as unknown. See Kubernetes posture.

R5: RuntimePolicy​

A workload with no RuntimePolicy passes: AIControls generates one when you register it. If R5 fails after registration, the policy failed to compile or declares no file open or exec limits. Open AI runtime controls for the compile diagnostics, then set the network, file, and exec levels on the Blueprint's Runtime Binding. See Edit a Workload Blueprint and Register a workload.

R6: Traffic through the proxy​

Send all LLM, MCP, and network traffic through the AIControls proxy, and trust its certificate authority (CA):

env:
- name: HTTP_PROXY
value: "http://aicontrols.aicontrols.svc.cluster.local:8443"
- name: HTTPS_PROXY
value: "http://aicontrols.aicontrols.svc.cluster.local:8443"
- name: NO_PROXY
# Only localhost and the AIControls Service itself. Other cluster
# services still go through the proxy.
value: "localhost,127.0.0.1,aicontrols.aicontrols.svc.cluster.local"
- name: SSL_CERT_FILE
value: /etc/aicontrols/ca/ca.crt
- name: NODE_EXTRA_CA_CERTS
value: /etc/aicontrols/ca/ca.crt
volumeMounts:
- name: aicontrols-ca
mountPath: /etc/aicontrols/ca
readOnly: true

Adjust aicontrols.aicontrols.svc.cluster.local in all three variables to your release name and namespace. Mount the CA certificate from a ConfigMap as the aicontrols-ca volume. For the proxy address, the credential, and the CA, see Enable network egress filtering. Then run the workload so AIControls can verify traffic through the proxy: with no observed traffic, R6 is Unknown. A library that ignores HTTPS_PROXY shows as a bypass and fails R6.

R6 passes when AIControls verified traffic from the workload's Pods through the proxy and found no bypass. It needs two kinds of evidence: verified calls through the proxy, and routing evidence from the cluster (a fresh Pod binding snapshot that matches the workload's current Pods).

R6 doesn't wait for the full window after you install AIControls. It looks at traffic since the runtime sensor began reporting healthy on every node without a break, and the passing evidence says so. A new install with a workload that makes verified gateway calls passes R6 as soon as the sensor has been healthy for one probe cycle.

A sensor outage fails R6 closed. If the sensor is down or unhealthy now, or it had a gap inside the readiness window, a bypass could have gone unseen, so R6 shows Fail with a reason that names the outage, the workload's verdict is Fix, and automatic registration doesn't run. AIControls records each outage, with its start and recovery, as a runtime_sensor_outage security event, shows a Runtime sensor row on the Health page, and sends admins a Runtime Sensor Outage notification when a healthy sensor run ends and a Runtime Sensor Recovered notification when it resumes. Route both under Settings → Notifications. A probe counts as healthy only when AIControls listed every node, each node's sensor is fresh, and the ingest gap detector shows no possible loss. AIControls fails closed on every ingest tick: any tick where the detector reports loss, a scrape error, or a stale scrape ends the healthy run, even if the next tick is clean. A new run starts only at a probe that sees a recent, clean status. To fix it, restore the sensor on every node and check that runtime events reach AIControls. R6 passes again once the gap leaves the window. R6 also fails when runtime controls aren't running on the AIControls replica that answers, because nothing is checking the sensor, and an earlier healthy run isn't current proof. The governance scorecard's Traffic goes through the proxy condition shows the same outage as Not met. If a deployment has never recorded a healthy sensor probe, R6 stays Unknown instead of failing. Demo mode simulates a healthy sensor, so demo workloads can reach Ready.

When R6 is Unknown, the evidence names the blocker. Common reasons:

  • No traffic observed: the evidence reads "No traffic has been observed yet." The workload hasn't made a call through the proxy in the window. Run the workload.
  • Stale or missing observation or snapshot: AIControls hasn't received a recent workload observation or routing snapshot from the cluster. Check that the runtime sensor is running, then wait for the next report.
  • Pod bindings changed or don't match: the workload's Pods changed, for example after a rollout. R6 recovers after the next observation.
  • Gateway-owned traffic: AIControls excludes its own gateway workload from bypass checks.

R7: One workload identity​

Give the workload its own ServiceAccount, and don't share it with other workloads:

apiVersion: v1
kind: ServiceAccount
metadata:
name: agent
namespace: agents
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent
namespace: agents
spec:
template:
spec:
serviceAccountName: agent

Check the result​

Reopen the workload's drawer. AIControls re-reads the evidence each time you open it. A rule that depends on discovery, Kyverno reports, or traffic can take a few minutes to update. When every rule passes, the verdict reads Ready to register, and you can register the workload.