Workload Protection
Workload Protection separates what you asked AIControls to protect from what is running, what controls are active, and whether those controls are holding.
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.
Where to find it
Inventory → Workloads lists every workload in one table. Three state cards — Discovered, Registered, and Protected — form a single filter group. Select one or more cards to match any of those states (OR). A separate Needs attention switch below the cards narrows that state selection to workloads that need remediation (AND). Its count and the state-card counts cover the complete matching inventory, even when it spans many pages. Search, filters, sorting, and pagination run on the server, so a workload beyond the first page remains discoverable and contributes to the correct count.
The table's Status column shows one summary tag for each row, an attention icon when the row needs remediation, and a second line: the reason, a "N of 8" protection-progress count for a Registered row, or coverage for a Protected row. A Runtime chip — Running, Pending, or Gone — sits under the workload name. The Risk band column ranks each workload for triage — see Deployment risk band — a Critical and High risk bands switch narrows the table to the workloads to look at first, and a Missing signals chip picks out the workloads that are Critical because a signal is missing. For every column and filter, see the Workloads table reference.
Selecting a row opens a detail drawer. At the top, a readiness verdict says whether the workload is Ready to register, needs you to Fix N issues, or needs a Review, and lists what to change. The verdict holds Register… for a workload with no registration (Register anyway… for a suspected one) or Edit registration… for a registered one. An Open full details link goes to the workload's own detail page — see Workload detail below.
Below the verdict, the drawer groups the evidence into panels:
| Panel | What it shows |
|---|---|
| Overview | The protection summary, the reason, the eight-step protection progress, coverage, and a Status detail block listing the four statuses and the raw reason code. Open by default. |
| Kubernetes posture | The Pod Security level with each failing check and the pod spec change that fixes it, the namespace's NetworkPolicy coverage, and the ServiceAccount's RBAC. Open by default. |
| Kyverno policies | Every Kyverno policy that reported on the workload and counts under your policy selection, failing policies first, with each failing rule's message. |
| AI runtime controls | Traffic routing for LLM, MCP, and TLS traffic, and the Runtime policy: the RuntimePolicy AIControls generates for a registered workload, and the enforcement review. |
| Activity | Observed behavior, and Pods and findings: the pods, containers, images, and runtime findings. |
| Security | Security events for the workload. |
| Details | The registration record. A discovered workload has none, so the drawer leaves this panel out. |
The drawer covers half of the window, so the table stays visible beside it. On windows narrower than 900 pixels, it fills the window.
Move between workloads and share a link
Use the arrow buttons in the drawer header, or the ← and → keys, to open the previous or next workload in the table without closing the drawer. The counter shows your position, for example 3 / 40, and the buttons follow your sort and filters and continue across pages. The keys don't run while your cursor is in a text field or while the enforcement review is open over the drawer.
While the drawer is open, the page URL contains the workload, for example /workloads?workload=<namespace>/<kind>/<name>. Copy the URL to share the workload or to bookmark it. If the workload isn't in the current table view, for example because you opened it from a link, the counter shows — and the arrow buttons are disabled until you select a row.
Opening a workload adds an entry to your browser history, so Back closes the drawer. Moving to another workload with the arrows replaces the entry, so one Back still returns you to the table.
Protection summary
AIControls summarizes every workload's protection with one of three summary values, plus a defensive fallback:
- Discovered — no user-created workload registration exists for this workload.
- Registered — a registration exists, but enforcement is not yet confirmed active and holding on every available plane.
- Protected — the workload is registered, and verification currently confirms that enforcement is active and holding.
- Unknown — one of the four statuses carries a value this console does not recognize, for example after a server upgrade adds a new status. The row shows an Unknown tag with the raw status values, always needs attention, is not counted in the Discovered, Registered, or Protected cards, and is not a
?status=filter value. Turn on the Needs attention switch to find these rows. Unknown is never rendered as a clean state.
Registered and verified are both required for Protected. Enabling enforcement does not make a workload Protected on its own: it moves Enforcement to Enable pending, and the summary stays Registered until verification catches up. This keeps the summary consistent with the design decision that enablement records your intent, and verification requires evidence — see The four statuses behind the summary.
The summary is a presentation layer only. AIControls computes it in the console from the four statuses it already serves; it is never stored, never returned by the API, never exposed to CEL policies, and never published as a controller annotation. Policies and the annotation feed keep matching on the four status fields, not on the summary. Because verification is non-sticky, if it stops holding, the summary drops from Protected to Registered on the next reconcile pass, with the reason shown alongside it.
Needs attention
A row needs attention when its status calls for a remediation step, not just more time. The reasons include:
- stale, invalid, or incomplete registration;
- failed control generation, including a saved registration that doesn't compile while the previous rules stay in place;
- incomplete enablement;
- recreation since enablement;
- enable pending, with the policy not yet live on every plane;
- degraded enforcement with no available plane;
- controls that remain observation-only; and
- activity outside the registered behavior that went through.
Attempts that an enforcing policy blocked never need attention on their own: they show that protection is holding. See Blocked attempts.
Two cases apply regardless of reason:
- An unrecognized status or reason value. AIControls never renders an unrecognized value as clean. It shows the raw value and marks the row as needing attention.
- Verified without a registration. A discovered workload whose evidence reports verified enforcement is shown as Discovered with a security warning — "Verified without a registration — review and complete registration" — never as Protected. Review the workload and complete its registration.
When reconciliation records Discovered · Verified, AIControls also records a system event in the configuration audit trail. The event identifies the workload, the verification reason, and who enabled enforcement. It appears once when the condition starts, including the first observation after upgrading, and again only if the workload leaves the condition and later returns. Repeated reconciliation and replica restarts do not repeat the event. This audit event does not change any protection status.
Runtime
The Runtime chip reports whether AIControls currently observes the workload running: Running, Pending (registered or discovered, but not yet observed), or Gone (previously observed, now absent; its record and protection history are preserved). The chip carries no timestamp.
Traffic routing
The drawer's AI runtime controls panel and the full detail page's Overview show a Traffic routing card for LLM, MCP, and TLS traffic. It uses the last hour of retained observations, limited to the current workload instance. Routing evidence never changes the four protection statuses, enables enforcement, or proves that all traffic uses the proxy.
| Routing status | What it means |
|---|---|
| Verified via proxy | LLM or MCP calls have verified identities with exact Pod UID bindings to this workload, and the selected occurrence-history window is complete. This establishes an observed path, not exclusive routing. |
| Bypass observed | AI SDK or credential access, local MCP execution, or an unsuppressed external destination was observed outside the proxy. Split traffic means proxy calls were also observed; they do not clear the bypass evidence. |
| Unknown | Fresh binding or classification evidence is missing, the window is incomplete, or no attributable activity was observed. Unknown does not mean safe. |
LLM evidence includes direct AI access and unsuppressed catalogued AI hosts. MCP bypass evidence means a local MCP server was observed, not through the proxy. TLS never reports Verified via proxy: positive TLS proxy attribution is not supported. Its Not observed explanation requires complete occurrence history, a recently applied network observation policy, and a recent, strongly bound network observation in the window. A quiet or unavailable sensor cannot establish this conclusion.
LLM proxy evidence is route- and provider-neutral. It does not identify which OpenAI-compatible, Bedrock, or Vertex route carried a call; provider-native route attribution is unavailable in this view.
The snapshot must be no more than 30 minutes old. Pod-name reuse, controller recreation, missing suppression facts, or bounded evidence limits produce Unknown until fresh evidence is available. Identities tracked by their latest Pod UID can omit earlier calls from another pod sharing the same ServiceAccount; AIControls does not attribute those calls by name alone.
Positive proxy counts start after the latest completed exact Pod binding snapshot, rounded up to the next second when needed. Earlier calls are not assigned retroactively to a controller that adopts the same pod. The panel shows this later Proxy evidence starts boundary separately. A quiet workload remains Unknown with an Insufficient post-binding evidence explanation until fresh calls arrive. Binding history is not reconstructed.
The Governance scorecard and its export read routing the same way readiness rule R6 does: the window clips to the start of the sensor's current unbroken healthy run, and a sensor outage or a gap inside the window keeps Traffic through the proxy from being met. The traffic routing card and the /routing API use the unclipped window instead.
Occurrence history starts when the delta ledger is installed and is retained for 90 days. Earlier lifetime counters are not reconstructed. Incomplete evidence coverage explains this gap separately from the routing status: a valid observed bypass still counts, but proxy-only verification and the TLS Not observed explanation require complete window coverage.
Register, observe, enforce
You move a workload through three operator actions:
- Register the workload record and its expected behavior.
- Observe generated controls without blocking, and review what enforcement would deny.
- Enforce after the evidence and coverage are ready.
Verification is not a fourth action. AIControls derives it from current evidence. Enabling enforcement records your intent and initially reports Enable pending · Not verified. The workload becomes Verified — and the summary becomes Protected — only after every available enforcement plane confirms that controls are active and holding.
Unregistered workloads
A Kubernetes workload that calls a model or an MCP server through the gateway without a registration is a shadow AI workload. AIControls handles it in three ways:
- Block or record. In the default Enforce mode, the gateway denies the call with the reason
workload_not_registered. In Audit mode, it allows the call and records it as shadowed. Developer, personal access token, and human sessions aren't affected. See Unregistered workloads for which calls the mode covers and how new and upgraded installations start. - Record a security event. Calls roll up into one security event per workload, target, outcome, and day.
- Discover the workload. The first call lists the workload as Discovered and Suspected, with the evidence shown. Runtime egress straight to a known AI provider counts as evidence too. See Observed AI activity.
Registering the workload lifts the block within a second. See Register a workload.
The four statuses behind the summary
The protection summary is a projection over four statuses that AIControls computes and serves independently. They remain the authoritative, filterable detail: deep links ?registration=, ?enforcement=, and ?verification= keep working, and the additive ?status= and ?attention=1 links filter by summary and by the needs-attention flag. State-card counts and the needs-attention count describe the complete matching inventory across all pages.
| Status | Values | What it answers |
|---|---|---|
| Registration | Discovered, Registered | Did a user create a workload registration? |
| Runtime | Pending, Running, Gone | Is the workload currently observed running? |
| Enforcement | Not ready, Observing, Enable pending, Enforcing, Degraded | What is the operational condition of its generated controls? |
| Verification | Not verified, Verified | Is enforcement confirmed active and holding? |
These statuses do not form a single ladder. A registration created before rollout can be Registered · Pending · Not ready · Not verified. A running workload without a user-created record is Discovered · Running even when an image-repository declaration supplies behavior details.
Registration
Registered means a user created a workload registration. A build or image-repository declaration can help AIControls prepare enforcement, but it never changes Registration to Registered. AIControls reports an observed workload without a registration as Discovered.
Runtime
Pending means a registered workload has not been observed running. Running means it is currently observed. Gone preserves the record and protection history after the Kubernetes workload disappears.
Enforcement
- Not ready: AIControls cannot generate or safely enable applicable controls. Read the reason and coverage details.
- Observing: controls collect evidence without blocking.
- Enable pending: you enabled enforcement, but application has not been confirmed on every available plane.
- Enforcing: applicable controls are confirmed active.
- Degraded: protection has a real gap. Either there is no enforcement plane (nothing is enforced), or activity outside the registration went through: a monitor-mode finding, or any finding an enforcing policy did not deny. An enforcement plane that the sensor reports as unavailable is also a gap and also reads as Degraded. A saved registration that doesn't compile reads as Degraded while AIControls keeps a policy from the last registration that compiled, because those rules don't match the saved one. Without a previous policy, it reads as Not ready. See A registration that doesn't compile keeps the last working policy.
An attempt that an enforcing policy blocks is not a gap. It is protection working, so it never makes a workload Degraded. See Blocked attempts.
Technical policy details may show the raw monitor and restrict modes used by the runtime policy engine. The product statuses remain Observing and Enforcing.
Identity cross-links
Each identity card on the Identity tab links to its filtered Virtual Keys, Access Bindings, and Toolsets lists. The displayed counts use the same filters as those lists. Workload-scoped virtual keys use agent ID, namespace, and the cluster's canonical ID, so the same service-account name in two clusters remains two independent identities. Access Binding agent subjects use the global agent ID, so review that scope before creating a binding from the filtered page.
Verification
Verified means enforcement is both active and holding. It is derived, non-sticky, and cannot be set through an API. A failed application, unavailable plane, workload recreation, or out-of-registration activity that went through drops Verification to Not verified and may make Enforcement Degraded.
Blocked attempts
When a workload's enforcing policy denies an attempt outside its registration — for example, the kernel refuses to run a binary the registration does not allow — the restriction is holding. The workload stays Enforcing and Verified, its summary stays Protected, and step 8, Holding, stays complete. The reason code is verification-confirmed-attempts-blocked.
The console shows the count instead of a failure:
- In the Workloads table, a Protected row adds a line such as "15 attempts outside registration blocked."
- In the detail drawer and on the detail page, a success notice reads "Protected — 15 attempts outside registration blocked" and links to Security → Activity, filtered to that workload's blocked attempts.
Review the blocked attempts. Widen the registration only if the workload needs that behavior; otherwise, no action is needed.
A single out-of-registration finding that was not denied still makes the workload Degraded with "Degraded, activity outside registration was allowed," however many other attempts were blocked. A workload with no enforcement plane reads "Degraded, no enforcement plane — nothing is enforced," so you can tell it apart from a workload that blocked an attack.
Protection meter
Two instruments give you more detail than the summary alone: a checklist showing which gate a Registered workload is at, and a coverage count showing how much of its declared behavior is enforced.
Protection progress
Protection progress is a checklist of eight independent, evidence-backed items, each counted on its own rather than assumed from the items before it:
- Registered
- Running
- Behavior registered for every container
- Registration valid and complete
- Controls generated
- Enforcement enabled
- Policy live on every available plane
- Holding
This is a checklist, not a state or a score: nothing stores it, nothing serves it, and no policy can match on it. For example, a workload with enforcement enabled but not yet confirmed applied on every plane shows 6 of 8. A workload recreated since its enablement was recorded shows 5 of 8, even though an earlier enablement is still on record — recreation invalidates the items that depended on the earlier instance. A discovered workload whose evidence reports verified enforcement shows 7 of 8: every item passes except Registered, which is why it renders as Discovered rather than Protected.
Behavior-plane coverage
For a Protected workload, or a Registered workload with recorded behavior-plane evidence, the meter reports "N of M declared behavior-plane entries enforced." It counts recorded entries per enforcement plane, so one declared network intent can produce two entries — for example, a kernel-network entry and a separate gateway-domain entry.
An entry counts as enforced only when its generated policy is applied in enforce mode and the entry's own plane reports the policy as applied. An entry whose recorded level disagrees with its plane's evidence is flagged as a warning, and the meter never reports that coverage as available. While a workload is Observing, its policy is applied in monitor mode: it collects evidence but restricts nothing, so the meter shows 0 of M with "Observing — nothing is restricted yet."
The count is not a percent and not a grade, and it is never comparable across workloads: two workloads with different declared behavior have different denominators. Depending on what the evidence shows, the meter adds a qualifier instead of a bare count:
- Partial coverage — some, but not all, declared entries are enforced.
- Coverage pending capability review — on the workload's detail view, when a declared file-open or execution entry is enforced or monitored, its enforcement depends on the open/exec hooks, and node capability has not been confirmed. AIControls never reports this coverage as available without positive evidence.
- Coverage evidence unknown (after a count) — AIControls could not establish whether the declared entries are enforced, and it has no missing-hook cause to name: for example, plane evidence that contradicts a recorded level, an unreadable entry, or an unrecognized status value. The Workloads table always uses this wording for unknown coverage, because it does not load the per-entry evidence that would name the hooks.
- No enforcement plane for the declared entries — every declared entry currently lacks an enforcement plane.
- Not available on this build — a gateway (L7) entry, since compiled L7 policy is not installable into the gateway on this build.
- No declared behavior-plane entries recorded — the recorded evidence confirms that no entries are declared for this workload. AIControls never shows this as full coverage.
- Coverage evidence unknown — AIControls could not read whether any entries are declared, for example because the section evidence is missing or unreadable. It never shows this as an empty declaration.
- Coverage evidence unreadable — the coverage counts in the response could not be read, for example a negative count, more enforced than declared entries, or a missing field. AIControls never shows this as coverage.
Examples
- Registered, observing — a workload with registered behavior and generated controls, not yet enabled: Registered, no attention, 5 of 8 protection progress.
- Registered, degraded, needing attention — enforcement lost a plane, or activity outside the registration went through: Registered with the attention icon, the reason named, and progress reflecting the gate it fell back to.
- Protected, attempts blocked — the enforcing policy denied attempts outside the registration: Protected, 8 of 8 progress, no attention icon, and a line stating how many attempts were blocked.
- Protected with partial breadth — verification holds, but only some of the workload's declared behavior-plane entries are enforced: Protected, 8 of 8 progress, coverage showing "partial coverage."
- Unknown coverage — declared file or execution behavior whose enforcement depends on node open/exec hook capability that has not been confirmed: the detail view shows "coverage pending capability review," and the Workloads table shows "coverage evidence unknown," both styled as a warning, not as clean.
- No user registration — a workload with no registration, however active its evidence: Discovered. If that evidence reports verified enforcement, AIControls adds the security warning described in Needs attention rather than showing Protected.
Registered behavior and evidence
The Workload Protection page shows registered behavior separately from Registration. This keeps declaration source and validity from pretending that someone created a workload record. Before enabling enforcement, review what would be blocked, rules the workload did not exercise, evidence gaps, blast radius, and controls that remain observation-only.
Deployment risk band
The deployment risk band ranks workloads so you can decide which to review first. Each workload gets one band — Critical, High, Medium, or Low — from four signals:
| Signal | What AIControls reads | Raises the band when |
|---|---|---|
| Pod Security | The Pod Security Standards level of the workload's pod template: Privileged, Baseline, or Restricted. | The template is at the Privileged level, or at the Baseline level with write RBAC privilege. Baseline or Restricted on its own doesn't raise the band. |
| RBAC privilege | The ServiceAccount's privilege level and the high-privilege flag. See Workload RBAC evidence. | The ServiceAccount has write or cluster-admin privilege, or is high-privilege. |
| NetworkPolicy exposure | Whether the namespace has a NetworkPolicy, and whether one denies all egress by default. | The namespace has no NetworkPolicy, or none of its policies denies egress by default. |
| Intent mismatch | The Kubernetes tier the registration declares, compared with what the RBAC grants. | The registration declares less access than the RBAC grants. An unregistered workload has nothing to compare, so this signal doesn't apply. |
The band comes from a fixed, ordered set of rules, not from a score: there is no number and no weight to tune. For example, a cluster-admin ServiceAccount is always Critical, and so is a Privileged pod template. Low means AIControls read every enabled signal and none of them raised the band. For every rule, see Risk band rules.
The Pod Security signal reads the Pod Security level that discovery computes from the pod template. The Deployment risk band section cites that level and its failing checks.
A missing signal is Critical
Every signal is on by default. When AIControls can't read an enabled signal, the signal is missing, and the band is Critical with the reason Signal missing: signal (fix). The fix names what to do:
| Fix | Meaning | What to do |
|---|---|---|
needs-posture-access | AIControls doesn't read RBAC bindings or NetworkPolicies, because the reader is turned off or its grant is missing. | Turn on the reader. See Workload RBAC evidence. |
source-unavailable | The reader ran but couldn't answer for this workload, for example because discovery hasn't recorded its ServiceAccount. | Check that discovery sees the workload. |
pod-security-not-evaluated | Discovery has no evaluated Pod Security level for the workload: it couldn't read the pod template, or it discovered the workload before AIControls evaluated Pod Security and hasn't scanned it since. | Wait for the next discovery pass, which records the level. For a custom kind, configure its pod template path, or turn the Pod Security signal off. |
This applies on a fresh install, too: until you grant the access a signal needs, or turn the signal off, every workload is Critical. When any signal is missing, the Workloads page shows a banner that counts the missing signals and the workloads they affect, with two actions:
- Grant access opens the documentation for the access a signal needs.
- Disable signal, for admins, opens Risk band signals, where you turn off a signal you can't provide.
AIControls refreshes every signal's source in the background, about once a minute on each replica, and stores each workload's band after every refresh. The Workloads table, its filters and sorting, the drawer, the detail page, and the banner all read the stored band, so browsing never changes a band. A signal doesn't go missing on one failed refresh: AIControls keeps the source's last good value until 3 refreshes of that source have failed in a row, or 15 minutes have passed since its last successful refresh, whichever comes first. The detail view marks a value kept this way as Last successful refresh. Changing Risk band signals re-bands every workload at once.
Turn a signal off
Select Risk band signals on the Workloads page to see each signal and whether it counts. An admin can turn a signal off, and change the two failure-tolerance thresholds. The setting applies to this cluster, and AIControls records every change in the configuration audit log. A disabled signal is left out of every band, and the detail view shows it as Signal disabled by an admin.
Read why a workload has its band
Read the Deployment risk band section on the workload detail page's Overview tab. The drawer doesn't repeat it: its readiness verdict and panels show the same evidence. The section shows the rule that set the band, any missing signals, and each signal with its state and evidence — the bindings, the NetworkPolicies, or the intent mismatch detail — and which signals set the band. Open the evidence goes to the workload's Posture tab.
The band is triage evidence only. It never changes a protection status, never enables or blocks enforcement,
Registration readiness
Registration readiness tells you whether a discovered workload is safe to register, and what to fix when it isn't. AIControls evaluates seven rules on the server, from evidence it already collects. Each rule passes, fails, or is unknown, and an unknown rule never passes: evidence AIControls couldn't read, or that is stale or incomplete, is a reason to review the workload, not a pass.
| Rule | Passes when |
|---|---|
| Pod security | The pod template meets the Restricted Pod Security level. An administrator can accept Baseline instead. |
| Least-privilege RBAC | The ServiceAccount has no Kubernetes API access or read-only access, with no high-privilege capability and no wildcard rule. |
| No direct internet egress | A default-deny egress NetworkPolicy covers the namespace. |
| Kyverno policies | Every Kyverno policy that counts under your policy selection passes. A warning or an error doesn't pass. Under Selected policies, each selected policy that applies to the workload must also have reported, or the rule is unknown. |
| RuntimePolicy | No RuntimePolicy exists yet, because AIControls generates one at registration, or the RuntimePolicy compiled and declares file open and exec limits. |
| Traffic through the proxy | AIControls verified traffic through the AIControls proxy and observed no bypass. This is the only rule that reports a bypass. |
| One workload identity | The workload uses one identity. See Multiple identities. |
For what each rule fails and reads as unknown, see Workload readiness rules. To fix a rule, see Make a workload ready to register.
The verdict is one of these:
- Ready to register: every rule passes. For a registered workload, it reads Meets readiness rules.
- Fix N issues: at least one rule fails. Each failing rule shows what AIControls found and what to change, with a link to the panel that holds the evidence.
- Review: nothing fails, but at least one rule is unknown, for example because AIControls can't read RBAC evidence without the workload posture access, Kyverno isn't installed, or the workload hasn't sent traffic yet.
The verdict appears in two places. The Workloads table has a sortable Readiness column that shows Ready, Fix N, or Review. Filter it in the column header; the filter is saved in the page URL as readiness=ready,fix,review. The verdict block at the top of the workload drawer lists each failing or unknown rule with its fix. Rules that pass appear as tags under the verdict; hover one to see what AIControls found. You can still register a workload that doesn't meet every rule.
By default, the Pod security rule requires Restricted. An administrator can accept Baseline: select Readiness settings on the Workloads page, and set Accepted Pod Security level. The setting applies to the whole deployment, and each change is recorded in the configuration audit log. A Privileged pod template fails at either setting.
The verdict is advisory: it never registers a workload, changes a protection status, or enables enforcement. A cluster-scoped, read-only drawer doesn't show a verdict, because it can't read the RBAC, Kyverno, and RuntimePolicy evidence for that cluster.
Automatic registration
Automatic registration registers a ready workload without the registration wizard. A developer opts a workload in with the label aicontrols.nirmata.io/auto-register: "true", and can name a Blueprint with the annotation aicontrols.nirmata.io/blueprint. Without the annotation, the default Blueprint applies.
AIControls registers the workload, in Audit mode, only when all of these hold:
- An administrator turned on Automatic registration under Settings → Workloads, and the workload's namespace is on the list. System namespaces are never allowed.
- The workload's verdict is Ready to register: every readiness rule passes.
- The workload's Blueprint has Allow automatic registration turned on. Only an administrator can set it.
A label never grants access. Access comes only from the Blueprint's Access Binding, and automatic registration never accepts an access widening. Registering sets the Registration status and nothing else, like any registration.
The workload drawer shows Will auto-register when every condition holds, and shows the reason when one fails. After AIControls registers a workload, it keeps checking. If the workload later stops being ready, loses its label, or its Blueprint stops allowing automatic registration, AIControls marks the registration inactive with a reason, such as readiness-drift. It never deletes the registration. Each registration and refusal is recorded in the configuration audit log with the actor auto-registration-controller.
To set it up, see Register workloads automatically.
Workload detail
When you open full detail from a cluster-scoped drawer, the link retains the selected cluster. The protection record, discovery evidence, and traffic routing all use that cluster, even when another cluster has a workload with the same namespace, kind, and name. An unknown cluster does not fall back to a different cluster's record.
Cluster-scoped drawers and detail pages show a Cluster-scoped read-only view notice. Legacy tuple-only registration, runtime, posture, policy, activity, and enforcement surfaces are temporarily unavailable in these views because their APIs do not yet support explicit cluster selection. This prevents data or actions from another cluster from appearing beside the selected workload's evidence. The Security section is available in the drawer and both full-detail views when the recorded cluster is known. It shows a bounded last-24-hour preview and links to Security → Activity → Correlated findings, preserving the workload and cluster together. Each finding also has a contextual Ask Analyst icon, revealed on hover or keyboard focus and visible on narrow or touch screens. It uses the same exact recorded workload, cluster, and frozen time window as the preview counts and evidence links. Analysis receives bounded authorized recorded context; active administrators can include retained redacted content, with explicit coverage gaps. It may incur provider cost; see AI Analyst. Coverage gaps are explicit; no findings does not establish complete detector coverage.
Existing detail links without a cluster selection continue to use the deployment's default cluster and provide the full set of tabs, including a Posture tab with the Kyverno results by policy category, which the drawer's Kyverno policies panel summarizes:
| Tab | What it shows |
|---|---|
| Overview | The protection summary, reason, protection progress, coverage, Status detail, the shared identity finding when one applies, the deployment risk band with its signals, the Pod Security level, traffic routing evidence, registration, and the tier expansion preview for this namespace's Runtime Binding. |
| Runtime | Discovery facts, pods, containers, and findings grouped by category. |
| Posture | The governance scorecard, and the workload's Kubernetes posture per standard. See Posture tab. |
| Identity | The agent identities bound to this workload, and whether each is bound at the pod-UID rung or only by a last-seen tuple. |
| Policies | Policies that reference this workload's agent identity, plus the controls generated from its registered behavior. |
| Security | Recorded findings for this workload and cluster, evidence links, contextual Ask Analyst actions, and detection coverage gaps. |
| Sessions and activity | The workload's audit events, filtered to this workload. |
| Enforcement review | The full evidence review — the same review you read before selecting Enable enforcement — including the behavior-plane coverage meter. |
Pod Security level
The Overview tab and the drawer show a Pod Security badge: Privileged, Baseline, or Restricted. The badge is the highest Pod Security Standards level that the workload's pod template meets:
| Level | Meaning |
|---|---|
| Privileged | The template fails at least one Baseline check, for example a privileged container, host namespaces, or hostPath volumes. These give a path to root on the node. |
| Baseline | The template passes every Baseline check but fails at least one Restricted check. |
| Restricted | The template passes every Baseline and Restricted check. |
Under the badge, the section lists the checks that keep the template from the next level up. For a Privileged workload, these are the failing Baseline checks. For a Baseline workload, these are the failing Restricted checks.
AIControls computes the level during discovery, with the same evaluator that the Kubernetes API server's Pod Security Admission runs, and pins it to the Pod Security Standards version of the Kubernetes release that AIControls builds against. It needs no policy engine, no Kyverno, and no additional RBAC: discovery already lists the pod templates. AIControls evaluates the complete pod template and then stores only the result: the level, the failing check IDs, the policy version, and the time of evaluation. It never stores the pod template.
The level isn't a Kyverno result, and the two can differ:
- The Pod Security level is a fact about the pod template as written. It exists whenever discovery can read the template, and it doesn't prove that anything enforces it.
- The Kyverno results on the Posture tab come from policy reports. They show which installed policies passed or failed, and they show that admission control is enforcing them. They exist only when you install Kyverno and its policies.
When the two disagree, treat the worse result as the one to act on. The level is a floor that always exists, and the Kyverno results supply per-policy evidence and proof of enforcement.
A workload with no readable pod template, such as a custom kind without a configured template path, shows Not evaluated, and its deployment risk band reports the Pod Security signal missing. The level doesn't change a protection status. For the stored fields, see Pod Security fields.
Posture tab
The Posture tab shows the results below. None of them changes a protection status, and AIControls never combines them into one score.
At the top of the tab, the governance scorecard shows the workload's four governance conditions, and Export evidence downloads the workload's compliance evidence.
Above them, a Kubernetes RBAC card shows the workload ServiceAccount's privilege (None, Read, Write, or Cluster admin), a High-privilege agent tag, the bindings that grant it, and the namespace's NetworkPolicy summary. When a registration declares less Kubernetes access than the RBAC grants, the card shows the mismatch. The drawer shows the same card under Kubernetes posture, in its RBAC section. This is evidence only: it never changes a protection status. When the reader is off or its grant is missing, the card shows Needs cluster posture access with the reason. See Workload RBAC evidence.
- Kubernetes posture lists pass and fail counts grouped by policy category (the
policies.kyverno.io/categoryannotation), read from the reports Kyverno maintains. A category shows Passing only when it has passing results and no failures, warnings, or errors. Unknown means evaluation has not been established — for example, no policy engine is installed or no policy has reported on the workload — and it is never a passing result. Select the expand arrow on a category to list each policy, rule, message, and resource behind its counts. The tab also shows how old the newest report evidence is, and warns when it is more than 24 hours old. Passing results from stale evidence show as Passing (stale), not green. Under Selected policies, the tab lists selected policies that apply to the workload and haven't reported yet under Not scanned yet, and the workload is Unknown. Select Open posture scorecard to review the same workload's evidence and advisory assessment on the Security Posture page. For how posture is read, see Kubernetes posture.
Kyverno policy selection
The Kyverno policies card under Settings → Workloads decides which Kyverno policies count toward the Posture tab, the Kyverno policies panel, and the Kyverno policies readiness rule:
- All policies (the default): every policy that reports on a workload must pass.
- Selected policies: only the policies you select count. A selected policy that applies to the workload's kind but hasn't reported yet leaves the workload Unknown, never passing. For example, a workload is Unknown until the first background scan finishes.
AIControls doesn't map Kyverno policies to compliance standards. For the steps, see Review Kubernetes posture.
Governance scorecard
The governance scorecard answers four questions about one workload. It sits at the top of the workload's Posture tab. Each condition shows Met, Not met, or Not evaluated, a one-sentence reason, and the evidence behind it, with the source and when the source observed it.
| Condition | What it asks | Evidence it reads |
|---|---|---|
| Traffic goes through the proxy | Does the workload's LLM, MCP, or TLS traffic go through the AIControls proxy? | The traffic routing evidence for the last hour: proxy calls attributed to the workload's Pods, and traffic the runtime sensor saw bypass the proxy. |
| Protocols are restricted | Is the workload's network egress restricted? | The namespace's NetworkPolicies, and the runtime policy's behavior.network and behavior.network.domains sections. |
| File access and execution are controlled | Are file access and process execution restricted or monitored? | The runtime policy's behavior.exec and behavior.open sections, the runtime sensor's open and exec observations for the last 24 hours, and the Pod Security level. |
| Credentials are secured | Does the workload reach AI providers with a scoped credential, without access to cluster Secrets? | The ServiceAccount's Secrets access from Workload RBAC evidence, virtual keys issued to identities attributed to the workload, and direct AI access seen outside the proxy. |
The scorecard applies these rules:
- Traffic goes through the proxy is Met when every plane the workload uses is verified through the proxy and no plane shows traffic outside the proxy. A plane counts as used when the registered intent declares it (LLM or MCP) or when the routing evidence observed traffic on it. A plane with neither is not applicable, so an LLM-only workload can be Met. A used plane that isn't verified, for example a declared MCP plane with no attributed proxy calls, makes the condition Not evaluated. Any bypass makes it Not met. When the registration can't be read, the declared planes are unknown, so the condition is Not evaluated with the reason Registration unavailable.
- Protocols are restricted is Met when a default-deny egress NetworkPolicy covers the namespace, or when an enforce-mode runtime policy enforces a network allowlist. A monitor-mode policy observes and doesn't restrict. AIControls doesn't verify that the cluster's CNI enforces NetworkPolicies.
- File access and execution are controlled is Met when the runtime sensor reported both exec and open observations for the workload and the pod template is at the Baseline or Restricted level. A runtime policy's
behavior.execorbehavior.opensection alone is Not evaluated with the reason Open/exec hooks not verified, because kernel enforcement of those sections needs the open/exec hooks on the nodes, and AIControls doesn't verify them. It is Not met when the pod template is at the Privileged level, because a privileged container can bypass these controls. - Credentials are secured is Met when the ServiceAccount can't read Secrets, an active virtual key is issued to an identity attributed to the workload, and the workload's LLM traffic is verified through the proxy. Without verified LLM routing, it is Not evaluated. It is Not met when the ServiceAccount can read Secrets or is cluster-admin, or when direct AI access is seen outside the proxy.
Not evaluated means a source didn't answer, or its evidence can't settle the condition either way. It is never counted as Met. For example, a quiet workload with no declared plane, no proxy calls, and no bypass in the last hour is Not evaluated for routing, and a workload with no virtual key is Not evaluated for credentials, because AIControls can't see how it holds provider credentials.
The scorecard has no score and no ranking; the deployment risk band covers triage. It is evidence only: it never changes a protection status, enforcement, or a kill switch. AIControls evaluates it only for its own cluster. To download the scorecard with the rest of the workload's evidence, see Export workload compliance evidence.
Workload identity rules
Each workload must have exactly one identity, and each identity must belong to exactly one workload. AIControls raises a High finding and sends an alert when a workload breaks either half of that rule: a shared identity when two or more workloads use one identity, and multiple identities when one workload uses two or more. The findings are warnings. They never change a protection status and never block Enforce.
An identity is the cluster-qualified Kubernetes ServiceAccount, for example k8s-cluster://prod-east/agents/research-agent. A workload is the top-level controller (cluster, namespace, kind, and name), so a Deployment's ReplicaSets and a CronJob's Jobs count as one workload.
Shared identity
A shared identity is one ServiceAccount that two or more workloads in the same cluster and namespace use. AIControls finds it in two ways, on every reconcile pass:
- Declared. Two or more discovered workloads name the ServiceAccount in their pod templates. This needs no traffic.
- Observed. Verified calls from two or more workloads used the ServiceAccount at the same time, for at least 15 minutes. See Runtime evidence.
Both kinds of member are one finding, with one alert and one acknowledgment.
- The
defaultServiceAccount is treated like any other. A workload that is the only one ondefaultraises no finding. When two or more workloads usedefault, each of them has a finding. - There are no namespace exemptions. To accept a shared identity, acknowledge the finding.
- The declared check counts only discovered workloads, because it reads each workload's pod template. Registering a workload doesn't add it to the declared check until discovery sees it, and a workload with no readable pod template says nothing about its identity. The observed check also catches workloads that discovery hasn't seen, such as a bare pod. Such a workload has no row in Inventory → Workloads, so its findings appear in the alert, in the other members' Shared identity cards, and in the Runtime Controls findings list.
- Delegation isn't a second identity. A delegating user, an on-behalf-of exchange, a virtual key bound to the same ServiceAccount, and the legacy
k8s://key for the same ServiceAccount raise no finding.
Each affected workload shows the finding in three places:
- Inventory → Workloads shows a Shared identity chip beside the workload name. Hover the chip to see the other workloads.
- The workload drawer and the Overview tab of workload detail show a Shared identity card with a High tag. The card names the ServiceAccount and lists the other workloads that use it. A workload found only from runtime calls is tagged Observed at runtime.
- The Runtime Controls findings list shows the finding under the Shared Identity category, with the identity as its subject.
Pods that share one ServiceAccount are one security principal, so they share the same workload access. AIControls can't tell which workload made a call. The finding is a warning and never gates Enforce, but a configured identity binding that more than one registration pins fails closed. The finding tells you why, and where to fix it: give each workload its own ServiceAccount, then redeploy. A declared member clears on the next reconcile pass after discovery sees the change. An observed member clears 24 hours after its last call with the identity. A workload that is gone no longer counts.
Multiple identities
A workload has multiple identities when verified calls from it used two or more ServiceAccounts at the same time, for at least 15 minutes. AIControls checks this on every reconcile pass from runtime evidence.
Each affected workload shows the finding in three places:
- Inventory → Workloads shows a Multiple identities chip beside the workload name. Hover the chip to see the ServiceAccounts.
- The workload drawer and the Overview tab of workload detail show a Multiple identities card with a High tag that lists the ServiceAccounts.
- The Runtime Controls findings list shows the finding under the Multiple Identities category, with one row for each identity.
A workload that discovery hasn't seen has no row in Inventory → Workloads; find its multiple identities finding in the alert and the Runtime Controls findings list.
Multiple identities split a workload's access decisions and audit history across identities. To fix it, give the workload exactly one ServiceAccount, then redeploy. The finding clears 24 hours after the workload's last call with the extra identity.
Runtime evidence
The observed shared-identity check and the multiple-identities check read the audit log. Each audit event records the caller's identity and the workload its pod belonged to when the call was made. AIControls counts an event only when:
- The identity was verified, so its pod claims were checked. Unverified identities never count.
- The call carries the pod's UID, so the workload was resolved for that exact pod and not by a pod name that another pod could reuse.
- The identity is a Kubernetes ServiceAccount in the workload's own cluster and namespace.
Two uses count as concurrent only when they overlap for at least 15 minutes, and a gap of more than 30 minutes between calls starts a new period of use. A rollout that changes a workload's ServiceAccount, a rollback to the previous one, and a ServiceAccount that moves from one workload to another overlap for a few minutes at most, so they raise no finding. Evidence older than 24 hours is dropped.
Delegation is allowed and never counts as a second identity. An identity obtained by token exchange isn't a ServiceAccount, and a ServiceAccount token minted without a pod binding, for example to assume another role, carries no pod. Neither is attributed to a workload.
Alerts
AIControls sends one workload_identity_shared notification for each identity and set of workloads, and one workload_identity_multiple notification for each workload and set of identities. They reach the in-app inbox, and Slack, Teams, email, and webhook integrations according to your routing. Find the events as Shared Workload Identity and Workload Uses Multiple Identities under Settings → Notifications. By default, they go to admins in the inbox, Slack, and email.
An alert doesn't repeat on every reconcile pass. It fires again when the set changes: a workload joins or leaves the identity, or the workload uses a different set of identities. If a finding is still unresolved after about 35 days, AIControls can send the alert again.
Acknowledge a finding
An administrator can acknowledge a finding when the sharing is intended or accepted for now. An acknowledgment silences the alert and keeps the finding visible, marked Acknowledged, with who acknowledged it, when, and an optional note.
- Open the workload drawer or workload detail from Inventory → Workloads.
- In the Shared identity or Multiple identities card, optionally enter a note, and select Acknowledge.
An acknowledgment covers the set at that moment: the workloads that share the identity, or the identities the workload uses. When the set changes, AIControls removes the acknowledgment on the next reconcile pass, and the finding returns to unacknowledged and alerts. This also holds if the same set of workloads later returns. To bring the alert back, select Clear acknowledgment.
Acknowledging and clearing are administrator actions. Both write to the configuration audit (Security → Activity → Configuration) as workload_identity_ack.created, workload_identity_ack.updated, and workload_identity_ack.deleted, with the administrator's identity taken from the session. The automatic removal when the set changes is also recorded as workload_identity_ack.deleted, attributed to the system.
Workload access
Protection statuses describe the controls around a workload. Workload access describes what its gateway calls can reach. They are independent: registering a workload, switching it to Enforce, or containing a workload changes no protection status.
An administrator binds the workload's ServiceAccount, registers the workload against a Workload Blueprint in Audit mode, and then switches it to Enforce. Containment denies the workload's MCP and LLM requests at once. See Workload Blueprints and Workload Registrations for the model and Workload access for the whole path. The AI access tab on the workload detail page shows the mode, the effective access, the recommendation queue, and containment.
Kill switch
The kill switch is an emergency containment action for one registered workload, separate from the four protection statuses: arming it changes no status. You choose which planes to stop:
| Plane | What stops | How |
|---|---|---|
| Network | All new outbound connections, including DNS | An enforce-mode RuntimePolicy that denies every network destination for the workload's pods |
| File system and exec | New process execs and file opens | An enforce-mode RuntimePolicy that denies every exec and open; needs the open/exec hooks on the node |
| Gateway | All MCP, LLM, and HTTP requests through the AIControls gateway | A generated deny policy over every identity bound to the workload — the same mechanism as blocking one identity |
A kill switch blocks new activity only. It does not evict, restart, or scale down pods, and it does not kill processes that are already running. It always has an expiry (2 hours by default, 24 hours at most), and you can disarm it earlier.
The kernel policy always selects exactly one namespace and a non-empty pod selector made of the workload's own stable labels, and AIControls arms only when one of those labels is unique to the workload in its namespace. That keeps the blast radius equal to the one workload you chose. The File system and exec plane reports itself as unavailable on nodes without the open/exec hooks before you arm, and the armed state reads degraded while any plane cannot enforce everywhere.
The kill switch is off by default; an administrator turns it on under Setup → Settings → General → Features. See Arm a workload kill switch. To deny only a workload's MCP and LLM requests, with no feature flag and no expiry, use containment.