Skip to main content

Workload Blueprints and Workload Registrations

Concept

A Workload Blueprint is a reusable profile that many workloads share. It records why a group of workloads exists (its Purpose), what kind of workload it is (its type, autonomy tier, and data classification), which models and MCP tools it may use (its one Access Binding), and what it may do inside its container (its one Runtime Binding). A Workload Registration names one workload and attaches it to a Blueprint, with an optional override. An identity binding ties the registration to the one ServiceAccount whose calls AIControls authorizes. Everything is live: when you change a Blueprint or a binding, the workloads that use it follow, after you review the impact.

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.

The pieces​

PieceWhat it isWho changes it
Workload RegistrationOne workload (cluster, namespace, kind, and name) with its own display name and owning team. It takes its Purpose, profile, and bindings from its Blueprint. See Register a workload.Administrators
Identity bindingThe cluster-qualified Kubernetes ServiceAccount, k8s://<namespace>/<serviceaccount>, that this workload's calls use.Administrators
Workload BlueprintA named, reusable profile: a required Purpose, a type, an autonomy tier, an optional answer to whether its workloads act on behalf of a user, an optional data classification, one Access Binding, one Runtime Binding, and a starting mode.Administrators
Access BindingThe models and MCP tools the Blueprint's workloads may use. The same binding can also apply to teams and other identity subjects, and its Applies to section lists every Blueprint that selects it. See Control MCP tool access.Administrators
Runtime BindingThe access levels for network, files, programs, and the Kubernetes API, plus optional overrides of the cluster's environment values. See Configure Workload Protection policy.Administrators
OverrideThe workload's own differences from its Blueprint: extra Access Binding references, blocks, access levels, and a data classification.Administrators

All of these are administrator-only and are recorded in the configuration audit. Nothing about a workload's name, labels, annotations, or owner references grants access.

A Blueprint has no revisions, and a registration doesn't pin or get admitted to anything. A workload always uses the current Blueprint and the current bindings.

The owning team​

Every registration names the team that owns the workload. When the workload's Pod-bound ServiceAccount calls, AIControls records the team on the agent's identity as trusted workload metadata, with source workload-registration. It does so only when the identity has no trusted metadata from another source. A team label the caller sends is never trusted.

The team is used for:

  • Routing. An agent that isn't acting for a user matches Access Binding grants as a member of its team, so a grant to that team that names a route steers the agent's requests. An agent acting for a user matches the user's team and group subjects instead. A grant through the agent's workload or Workload Blueprint outranks a team grant.
  • Attribution. On the LLM gateway, the MCP proxy, and the /authz, /authz/litellm, /ext-authz, and gRPC ext_authz endpoints, the agent's object.agent.teamId is the user's primary team when the agent acts for a user who has one, and its owning team otherwise.

A registration made before the team was required has none and is flagged No team until an edit sets it. See Set the team on a registration that has none.

The principal is the ServiceAccount​

AIControls authorizes the verified, Pod-bound ServiceAccount identity, qualified by the cluster. It does not authorize a workload name. The workload tuple that a call carries identifies which workload the call came from, for audit and attribution, but it never selects a registration or grants access.

This has three consequences:

  • One ServiceAccount is one principal. All Pods that run as the same ServiceAccount in one cluster share the same access.
  • A cluster-qualified identity. The same k8s://prod/checkout-sa in two clusters is two principals, and each has its own bindings and containment.
  • One active binding for each identity. A ServiceAccount can be bound to one workload in a cluster. A second binding for the same ServiceAccount is refused with 409 and the code identity_conflict.

A virtual key, or a ServiceAccount token AIControls can't tie to a Pod (such as a token without a Pod UID), is not a verified Pod-bound identity. When that identity has no configured registration, its calls stay on the default access policy and the legacy Access Bindings that match them. When a registration is configured for that ServiceAccount, its calls are denied with workload-registration-binding-incoherent instead.

Workload Blueprints​

A Workload Blueprint answers the questions that every workload in a group shares:

FieldWhat it answers
PurposeOne sentence on what the workloads are for. Required, 1 to 500 characters. Every workload that uses the Blueprint inherits it.
Type and Autonomy tierWhat kind of workload it is, and how much a person oversees what it does, from T1 to T4. The tier is the one policies see for each member's identity, unless the member's override replaces it. If a member's identity already has a different tier assigned on the Identities page, policies see the stricter of the two until an admin resolves the conflict. See the workload types and Where the tier comes from.
Acts on behalf of a userOptional. Whether its workloads act as themselves, with a virtual key, or for a user, presenting that user's token. The workload's identity is still its ServiceAccount. It's advisory: registration shows the credential to expect, and nothing enforces it yet.
Data classificationThe highest class of data the workloads may access. Optional. See Data classification.
Access BindingThe one Access Binding that grants models and MCP tools.
Runtime BindingThe one Runtime Binding that sets the network, files, programs, and Kubernetes API access levels.
Starting modeLearn first (Audit) or Enforce, the mode that the registration wizard suggests for a new workload. It never changes a workload that's already registered.
Allow automatic registrationOff by default. Only an administrator can turn it on. When on, a ready workload that opts in with a label can register against this Blueprint without the wizard, always in Audit mode. A label never grants access: the workload gets what this Blueprint's Access Binding grants. The administrator's namespace scope also applies to registrations the controller already made: when a namespace leaves the scope, the registration goes inactive and grants nothing until it is restored. See Register workloads automatically.

The Blueprint has no list of blocks. To stop a grant for the whole group, remove it from the Blueprint's Access Binding. To stop it for one workload, use Block for this workload, which writes the workload's override.

One Access Binding and one Runtime Binding​

Each Blueprint has exactly one Access Binding and exactly one Runtime Binding. When you create a Blueprint, you choose for each kind:

  • Use an existing binding. Later Blueprints can reuse any binding, so a binding can be shared by many Blueprints.
  • Create a new binding. The new binding's name defaults to the Blueprint's name, and you can edit it until you create the Blueprint. After that, the name is fixed. The API refuses an Access Binding rename with 400 binding_name_immutable, and a Runtime Binding edit has no name field.

You choose one or the other for each kind, never both. Binding names are unique.

Bindings are live​

A binding edit applies at once to every Blueprint and workload that uses it, including workloads in Enforce. Because that's powerful, every edit goes through the same flow:

  1. Preview. AIControls shows where the binding is used and what changes. For example: "gives 3 Enforce workloads new access" or "changes runtime rules on 2 enforced workloads."
  2. Confirm. You confirm the impact. If the binding, or the workloads that use it, change after the preview, AIControls refuses the save with 409 impact_changed and the current preview, and you confirm again. A save with no preview hash is refused with 409 impact_unconfirmed. An Access Binding that only people use, with no Blueprint and no registration, needs no confirmation.
  3. Audit. AIControls records the edit in the configuration audit (access_binding.updated, runtime_binding.updated, and the matching created, restored, and deleted events) with the impact counts.
  4. History. AIControls appends a revision to the binding's history. You can compare any revision with the current one and Restore it. A restore goes through the same preview and confirmation, and it appends a new revision rather than rewriting history.

History is a record, not a pin. No workload is tied to an old revision.

A binding that a Blueprint selects can't be deleted. AIControls refuses the delete with 409 binding_in_use and lists the Blueprints. Blueprints have no history of their own, and the configuration audit is their record. A Blueprint edit that changes the profile, swaps a binding, or changes the starting mode still gets an impact preview, a confirmation, and an audit event.

The Access Binding​

The Access Binding is the only thing that grants models and MCP tools. Its subjects are the workloads whose Blueprint selects it, plus any workload whose override references it. Each of those workloads becomes a derived subject of the binding. A workload's own references are the way to give one workload an extra shared binding.

The Runtime Binding​

The Runtime Binding holds the four access levels that the Blueprint's workloads run with: Network, Files, Programs (with Allow kubectl exec), and Kubernetes API. It also holds optional overrides of the cluster's environment values.

Environment values are the concrete cluster facts that the levels expand against: cluster Services, gateway Services, expected domains, base files, interpreters, and exec setup files. Your platform team sets them once for the cluster, as Environment defaults in Settings → Workloads. A Runtime Binding inherits every default and can override a field. An absent field inherits, and a present field, even an empty one, replaces the default. Editing the environment defaults previews the runtime-rule change for every workload in the cluster.

A Runtime Binding edit recompiles the runtime rules of every workload whose Blueprint selects it, so the impact preview lists the runtime-enforced workloads and the rule changes, computed against their running pods now.

The default Blueprint​

A new installation has a Workload Blueprint named default, so you can give the first workload access without designing a Blueprint first. Its Purpose is "Default role for new AI workloads." It has an empty Access Binding named default, a Runtime Binding named default, the starting mode Learn first, and a conservative profile: a supervised agent with network access to the AIControls gateway and in-cluster destinations, and nothing else.

This profile is safe in Learn first: runtime rules render in monitor mode until you enable enforcement, and gateway access still comes only from the Access Binding. When you govern agents in Kubernetes, the setup wizard's Model step adds the model you connect, and its upstream, to the default Access Binding through the same preview-and-audit flow as any other binding edit.

AIControls creates the default Blueprint once, the first time it starts, and records the creation in the configuration audit. A restart, another replica, or an upgrade never creates a second one or resets your edits. If a Blueprint named default already exists, AIControls leaves it alone and creates aicontrols-default instead.

When you register a workload, the wizard suggests the default Blueprint unless you choose another one. A workload in Learn first against it starts in Audit with nothing granted, so its calls follow the default access policy and become recommendations. Promote fills the workload's own binding, so the default Blueprint stays empty and shared.

To make another Blueprint the default for new registrations, open it in the Blueprints view and select Set as default for new registrations. The Default tag marks the current one. Changing the default doesn't move workloads that are already registered.

Edit a Blueprint​

The Blueprints view of Inventory → Workloads lists Blueprints, marks the default Blueprint, and shows each one's Purpose, Access Binding, Runtime Binding, starting mode, and usage: how many workloads use it. A Blueprint marked Purpose needs review came from an upgrade where its members disagreed. Confirm or edit its Purpose to clear the mark.

The Blueprint editor has four sections:

SectionWhat it holds
AboutThe Name (create only), the Purpose, the type, the Autonomy tier, Acts on behalf of a user, and the Highest data classification this workload may access.
AccessUse an existing Access Binding or Create a new Access Binding.
Runtime bindingsUse an existing Runtime Binding or Create a new Runtime Binding, with the Network, Files, Programs, and Kubernetes API levels and the Environment values.
ReviewThe Starting mode, a summary, Advanced (JSON), and, for an edit, the impact preview and confirmation.

For the steps, see Edit a Workload Blueprint.

Changing a Blueprint's profile, swapping one of its bindings, or changing its starting mode applies to its workloads after an impact preview. Editing the contents of a binding is a separate edit of that binding, with its own preview, history, and Restore, and it also affects every other Blueprint that uses the binding.

Data classification​

A Blueprint's data classification sets a ceiling: the highest class of data its workloads may access. It uses the same scale as MCP server and tool classification, from least to most sensitive: Public, Internal, Confidential, and Restricted. Not classified sets no ceiling.

The ceiling is audit-only in this release. It never changes which tools you can grant, and it never blocks a call:

  • Gateway. The CEL fact object.agent.dataClassification is the calling workload's ceiling, and empty when it has none. The built-in workload-data-ceiling policy, in Audit mode, flags an MCP call whose object.mcp.dataClassification ranks above the ceiling. Unclassified servers and tools pass.
  • Impact preview. The grant-above-data-ceiling risk factor, with member counts, names each granted MCP tool classified above the ceiling.
  • Editor. The Access section lists the granted tools above the ceiling as a read-only warning.

A workload override can set its own ceiling. Raising it is a widening that needs an acknowledgment. Lowering it narrows. A Blueprint edit that changes the ceiling goes through the impact preview, which flags granted tools above the new ceiling. The Data column on the Workloads list and the Data chip on the workload detail show the effective ceiling.

Observed beyond intent​

A Blueprint's drawer aggregates its members' open intent recommendations under Observed beyond intent, for example "3 of 12 members exec a shell". Each row names an access level and lists the workloads that need it. When the behavior is specific to one workload, open its AI access tab and select Promote to this workload, which writes that workload's override. When it belongs to the whole group, open the AI access tab of one of the workloads and select Promote to the Runtime Binding. AIControls opens the impact preview for the Runtime Binding, which lists every Blueprint and workload it reaches before you confirm.

Create a Blueprint from a workload​

You don't have to write a Blueprint from scratch. When a workload has learned its access in Audit and you've promoted its recommendations into its own binding, Create Blueprint from this workload on its AI access tab creates a Blueprint from the workload's effective profile. You select or create each binding, the same as in the editor. You can also move the source workload onto the new Blueprint in the same step, which clears its override. The new Blueprint takes the current Blueprint's starting mode. See Turn a workload's learned access into a Blueprint.

What a workload uses​

A workload's effective intent is computed from three inputs:

  1. The Blueprint's About details: the type, the autonomy tier, and the Purpose.
  2. The Runtime Binding's access levels: network, files, programs, and the Kubernetes API.
  3. The workload's override: sections it replaces, and a data classification.

An override replaces a whole section, such as network. AIControls stores the effective result with the registration and recomputes it whenever the registration, the Blueprint, or the Runtime Binding changes, so the gateway and the reconcile pass read one consistent value. The cluster's environment values never enter the effective intent. They affect only how the levels expand into concrete rules.

  • Widening needs an acknowledgment. An override can narrow the Blueprint freely. An override that widens it, for example a wider access level, an extra Access Binding reference, or allowKubectlExec, is refused with 409 widening_unacknowledged and the list of widened fields until you acknowledge it. Onboarding with Enforce never accepts a widening.
  • Each reconcile pass checks it. The runtime pass recomputes the effective intent from the Blueprint, the Runtime Binding, and the override. If the stored intent doesn't match, the pass doesn't compile it: it keeps the last applied policy and records intent-integrity-mismatch beside intent-policy-held-compile-failed.

Where AIControls shows it:

  • Workloads list. The Blueprint column, for administrators, names the Blueprint. Customized means the override sets intent or access, and Enforce marks a workload in Enforce.
  • Registration section. On the workload's drawer and detail page, each access level names its source: Blueprint, Runtime Binding and its name, or This workload. A Wider than Blueprint tag marks an override that widens the Blueprint's intent.
  • AI access tab. The Effective access card's Intent block shows the Blueprint's profile and data classification, the override (This workload), and the effective result, with each widening.
  • Runtime tab. The Runtime answers card shows the network, files, programs, and Kubernetes API answers the same way.

The access policy ID​

A call from the bound ServiceAccount publishes an opaque access policy ID as object.agent.workload.accessPolicy. Workloads of one Blueprint that have no override share one ID. A workload whose override adds references or blocks has its own. See Policy context: workload access.

When AIControls fails closed​

A workload with no configured identity binding keeps the behavior it had before: the default access policy and the legacy Access Bindings decide. After you bind a workload's identity to its verified ServiceAccount (a pod_uid binding), AIControls no longer guesses. A virtual_key binding keeps the legacy path. It denies the workload's calls, with the workload-registration-binding-incoherent policy, when any of these is true:

  • The identity binding exists, but the registration doesn't name a Blueprint, or the Blueprint's Access Binding or Runtime Binding no longer exists.
  • Another registration also uses the same identity, or the binding is not the only active binding for that ServiceAccount in the cluster.
  • A verified Kubernetes identity arrives without a cluster ID.
  • The store can't be read.

A missing Runtime Binding also holds the last compiled runtime policy and records an integrity finding, so a broken reference never silently loosens a workload's runtime rules.

Deleting a registration removes its override. You change a workload's own differences by editing its override with Customize for this workload. You can't delete a binding that a Blueprint selects.

A deny from the fail-closed rule is not exemptible, and Audit mode never shadows it. It does not use the default access policy, so an organization default of Allow can't turn a broken configuration into open access.

Findings about shared or multiple identities are warnings. They never gate Enforce, and acknowledging one never makes an ambiguous configured binding valid.

Next steps​