Turn a workload's learned access into a Blueprint
After a workload learns its access in Audit and you promote its recommendations, the grants live in a binding that only that workload can use. Create a Blueprint from the workload to reuse that access: AIControls fills the new Blueprint from the workload's effective profile, and you select or create each of its two bindings. You can move the source workload onto the new Blueprint in the same step, with its access unchanged. Register similar workloads against the Blueprint afterward.
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
- You need an administrator session.
- The workload must be registered. To create a new Access Binding from the workload, the workload needs grants to copy, so promote at least one recommendation first. See Promote a recommendation. Without grants, select an existing Access Binding instead.
Create the Blueprint
- Open Inventory → Workloads, open the workload, and select the AI access tab.
- On the Reuse this workload's access card, select Create Blueprint from this workload. The card appears for a registered workload that follows a Blueprint.
- Enter the Blueprint name, and optionally a Purpose. When you leave the Purpose empty, the new Blueprint uses the current Blueprint's Purpose. A Blueprint always has a Purpose.
- For Access, choose Use an existing Access Binding, or choose Create a new Access Binding. The default is a new binding. It copies the workload's effective allow grants, takes the Blueprint's name until you edit it, and you can't rename it later. The workload's own binding stays as it is.
- For Runtime, choose Use an existing Runtime Binding, or choose Create a new Runtime Binding. A new binding copies the workload's effective access levels and takes the Blueprint's name until you edit it.
- Select Move this workload to the new Blueprint to move the workload in the same step. The move clears the workload's override, so its effective access is unchanged. Leave the option cleared to leave the workload as it is.
- Select Preview. The preview lists the new Blueprint and bindings, and compares each grant and each gated MCP server for this workload before and after the move. It says This workload's access is unchanged when nothing differs.
- Select Create Blueprint. If an error says the workload or a binding changed since the preview, select Preview again, review the result, and then select Create Blueprint.
AIControls writes the bindings, the Blueprint, and the optional move in one audited transaction. The new Blueprint's starting mode is the current Blueprint's starting mode, which you can change by editing the Blueprint. When it finishes, the dialog shows Open the Blueprint.
Attach similar workloads
- Register each similar workload, in the same namespace or with the same image, and choose the new Blueprint. Choose Learn first (Audit).
- Watch the workloads' unmatched calls in Audit. When they look right, switch them to Enforce.
Use the API
Preview the Blueprint. Replace
CLUSTER_IDwith the workload's cluster ID:curl -X POST "https://YOUR_WORKSPACE_URL/api/v1/workloads/prod/Deployment/checkout/access/blueprint/preview?cluster=CLUSTER_ID" \-H "Authorization: Bearer $AICONTROLS_TOKEN" \-H "Content-Type: application/json" \-d '{"name": "checkout-access","purpose": "Checks out orders.","type": "agent","autonomy": "T1","startingMode": "audit","accessBinding": {"create": {"name": "checkout-access"}},"runtimeBinding": {"id": "RUNTIME_BINDING_ID"},"moveSource": true}'The body is the Blueprint create body, plus
moveSource. Onlynameis required: the preview fills inpurpose,type,autonomy,dataClassification,startingMode, and any binding you leave out from the workload. A binding the preview proposes takes the Blueprint's name, unless you setaccessBindingNameorruntimeBindingName. The response hasrequest, the complete body with the proposed parts filled in,source(what moving the workload changes for it, withchanged,grants, andruntimeRuleDiff),warnings, and thepreviewHash. The preview writes nothing.Create the Blueprint with the preview's
requestand the preview hash, so the commit matches what you previewed. WhenmoveSourceistrue, also sendexpectedRowVersionandrowToken, whichGET /api/v1/workloads/{namespace}/{kind}/{name}/access?cluster=CLUSTER_IDreturns asregistration.rowVersionandregistration.rowToken:curl -X POST "https://YOUR_WORKSPACE_URL/api/v1/workloads/prod/Deployment/checkout/access/blueprint?cluster=CLUSTER_ID" \-H "Authorization: Bearer $AICONTROLS_TOKEN" \-H "Content-Type: application/json" \-d '{"name": "checkout-access", "purpose": "Checks out orders.", "type": "agent", "autonomy": "T1", "startingMode": "audit", "accessBinding": {"create": {"name": "checkout-access"}}, "runtimeBinding": {"id": "RUNTIME_BINDING_ID"}, "moveSource": true, "expectedRowVersion": 7, "rowToken": "ROW_TOKEN", "previewHash": "<previewHash>"}'
Creating the Blueprint records access_binding.created, workload_blueprint.created, and, when the workload moves, workload_registration.updated in the configuration audit.
Troubleshooting
| Response | Cause | Fix |
|---|---|---|
409 preview_stale | The workload, its access, or a selected binding changed after the preview. | Preview again and save with the new hash. |
409 no_owned_grants | The request names no Access Binding, and the workload has no allow grants to copy into a new one. This code applies only when you create a Blueprint from a workload. | Promote a recommendation first, or select an existing Access Binding. |
409 blueprint_name_taken | A Blueprint with that name exists. | Choose another name. |
409 binding_name_taken | A binding with the name of a new binding exists. | Choose another name, or select the existing binding. |
400 invalid_name or 400 invalid_blueprint | The name isn't a lowercase DNS label, or the proposed Blueprint fails validation. | Fix the field the error names. |
409 conflict | The expectedRowVersion or rowToken is stale. | Read the access again, preview, and retry. |