Skip to main content

Deny a grant for one workload

A legacy identity binding or a shared binding can grant a workload more than it needs. You can block one of those grants for a single workload in one step, without changing the binding for anyone else. AIControls adds the block, a deny entry, to the workload's override in one audited transaction. Blueprints have no deny list, so Block for this workload is the way to block a grant for one workload.

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​

  • You need an administrator session. Both endpoints on this page are administrator-only and require the cluster query parameter, the UID of the cluster's kube-system namespace. A write that names the cluster's display name before the UID resolves is refused with 409 cluster_identity_unavailable.
  • The workload needs a Workload Registration. See Register a workload.
  • The block takes effect from the next call in either mode, but only an Enforce workload enforces it. See Workload access.

Block a grant from the AI access tab​

  1. Open Inventory → Workloads, select the workload, open its full detail page, and select the AI access tab.
  2. In the Effective access card, find the grant under Access Bindings (the Blueprint's Access Binding and any binding added for this workload), Extra access for this workload, or Team access rules that also match, and select Block for this workload next to it.
  3. Review the preview. It shows the Adds block value, the Workload blocks after the change, and Resulting effective access, where each grant is marked Granted or Blocked and the one you chose is marked This change.
  4. Select Block for this workload to commit. If the dialog says the access changed since the preview, review the refreshed preview and confirm again.

In Audit, the next matching call is still allowed, and its audit event records the deny as shadowed. After you switch the workload to Enforce, the deny applies.

Deny a grant through the API​

  1. Preview the deny. Name the granting binding and one selector copied from its grants. A whole-server grant uses "tools": ["*"]:

    POST /api/v1/workloads/{namespace}/{kind}/{name}/access/deny/preview?cluster={cluster}
    {"bindingId": "ab_gitlab_agent", "toolSelector": {"servers": ["gitlab"], "tools": ["*"]}}

    For a model grant, send "modelSelector": {"models": ["claude-*"], "providers": ["anthropic"]} instead of toolSelector. The response has entry, deltaDenyBefore, deltaDenyAfter, resultingAccess, mode, alreadyDenied, warnings, and previewHash. A selector that the binding doesn't grant to this workload is refused with 409 invalid_target.

  2. Commit with the same body and the preview hash:

    POST /api/v1/workloads/{namespace}/{kind}/{name}/access/deny?cluster={cluster}
    {"bindingId": "ab_gitlab_agent", "toolSelector": {"servers": ["gitlab"], "tools": ["*"]}, "previewHash": "<previewHash>"}

    The response names the registration's new rowVersion and rowToken.

The commit returns 409 with one of these codes:

CodeWhat to do
preview_staleThe registration, its override, or the binding changed. Preview again.
already_deniedThe workload's deny list already covers the grant. Nothing to do.
invalid_targetThe binding doesn't give this workload that grant.

Next steps​