Blog Post

Azure Governance and Management Blog
4 MIN READ

Granular control with scoped enforcement actions in Azure Policy for AKS

stevenbucher's avatar
stevenbucher
Icon for Microsoft rankMicrosoft
Nov 09, 2026

Azure Policy for AKS now supports scoped enforcement actions. This feature allows you to define the enforcement action (deny, audit, or warn) with the enforcement point where that action is applied. With Validating Admission Policy (VAP) now generally available, customers gain a new enforcement path and, more importantly, granular control over exactly where and how their policies are enforced. 

What this enables for customers 

Before this release, Azure Policy customers chose an enforcement action but had no granular control over where that action occurred. Compliance auditing and admission-time denial were unified and applied together. 

Now, scoped enforcement actions let you decide whether enforcement happens through compliance auditing, gatekeeper admission webhook (validation), VAP, or any combination of them. 

In short: you didn't have granular control over your enforcement before — now you do. Customers can tune the trade-off between visibility (seeing compliant and non-compliant resources) and hard enforcement (denying violating resources at admission), and they can choose the mechanism that performs the denial. 

Understanding enforcement points 

An enforcement point is where the enforcement action actually happens. Previously there were two enforcement points: 

  • audit.gatekeeper.sh  — shows compliance (reports compliant and non-compliant resources). 
  • validation.gatekeeper.sh  — the Gatekeeper admission webhook; it denies violating resources at admission. 

Previously these were unified: deny, [audit.gatekeeper.sh, validation.gatekeeper.sh] showed non-compliance and denied violating resources together. 

After VAP GA, there are three enforcement points: 

  • audit.gatekeeper.sh 
  • validation.gatekeeper.sh 
  • vap.k8s.io  — Validating Admission Policy, which validates resources at the Kubernetes API server 

 

Note
Open-source Gatekeeper also exposes gator.gatekeeper.sh, but Azure Policy does not support that enforcement point. 

The permutations 

The table below walks through the key combinations of enforcement action and enforcement points, and what each one means for greenfield deployments. 

Enforcement action 

Enforcement point(s) 

Kubernetes API server denies violating resources 

Gatekeeper admission webhook denies violating resource 

Shows compliant resources? 

Shows non-compliant resources? 

Behavior 

deny 

audit.gatekeeper.sh 

No 

No 

Yes 

Yes 

Violating resources are NOT denied at admission because validation.gatekeeper.sh is not an enforcement point. Compliance is always reported. 

deny 

validation.gatekeeper.sh 

No 

yes 

Yes 

No 

Violating resources are denied at admission. Non-compliant resources are not surfaced because audit.gatekeeper.sh is not an enforcement point. 

deny 

audit.gatekeeper.sh, validation.gatekeeper.sh, vap.k8s.io 

Yes 

Yes 

Yes 

Yes 

VAP denies violating resources at the API server before they reach Gatekeeper. If VAP malfunctions, the Gatekeeper admission webhook (validation.gatekeeper.sh) denies as a fallback. Full compliance reporting via audit. 

deny 

vap.k8s.io 

Yes 

No 

Yes 

No 

VAP denies violating resources at the API server. Non-compliant resources are not surfaced because audit.gatekeeper.sh is not an enforcement point. 

VAP runs first, validation is the fallback 

VAP runs before Gatekeeper validation in the request path. When both VAP and validation are selected, VAP normally rejects the violating resource at the API server before it ever reaches the Gatekeeper admission webhook. Gatekeeper validation then acts purely as a fallback if VAP malfunctions, giving customers defense in depth without sacrificing performance. 

Actions vs. points: one action per assignment 

Customers can select multiple enforcement points, but they cannot select multiple enforcement actions in a single policy assignment. For example: 

  • deny, [vap.k8s.io] 
  • audit, [vap.k8s.io] 

The two above require two separate policy assignments, because deny and audit are distinct enforcement actions. 

How warn and effect map to the enforcement action 

The resulting enforcement action is derived from the warn flag and the policy effect: 

warn 

effect 

Resulting enforcement action 

true 

audit 

warn  →  warn, [vap.k8s.io] 

false 

audit 

audit 

true 

deny 

deny 

Why use the enforcement points feature 

  • To have granular control when selecting where enforcement occurs. 
  • Customers decide which enforcement points get enforced — balancing compliance visibility, admission-time denial, and the performance of VAP-based enforcement. 

Assignment example: 

{ 
  "properties": { 
    "displayName": "[addon-end-to-end-tests] Test custom-cel-scoped-enforcement-action deny audit", 
    "parameters": { 
      "effect": { 
        "value": "deny" 
      }, 
      "enforcementPoints": { 
        "value": [ 
          "audit.gatekeeper.sh" 
        ] 
      }, 
      "namespaces": { 
        "value": [ 
          "cel-scoped-enforcement-action-deny-audit-e2e" 
        ] 
      }, 
      "excludedNamespaces": { 
        "value": [ 
          "kube-system" 
        ] 
      }, 
      "message": { 
        "value": "The resource has been denied" 
      } 
    } 
  } 
} 

Definition Example:

{ 
  "policyType": "Custom", 
  "mode": "Microsoft.Kubernetes.Data", 
  "displayName": "[E2E Custom Policy Test] Test scoped enforcement action deny audit", 
  "policyRule": { 
    "if": { 
      "field": "type", 
      "in": [ 
        "Microsoft.Kubernetes/connectedClusters", 
        "Microsoft.ContainerService/managedClusters" 
      ] 
    }, 
    "then": { 
      "effect": "[parameters('effect')]", 
      "details": { 
        "templateInfo": { 
          "sourceType": "Base64Encoded", 
          "content": "YXBpVmVyc2lvbjogdGVtcGxhdGVzLmdhdGVrZWVwZXIuc2gvdjFiZXRhMQ0Ka2luZDogQ29uc3RyYWludFRlbXBsYXRlDQptZXRhZGF0YToNCiAgbmFtZTogazhzZTJldGVzdHNlYWRlbnlhdWRpdA0Kc3BlYzoNCiAgY3JkOg0KICAgIHNwZWM6DQogICAgICBuYW1lczoNCiAgICAgICAga2luZDogSzhzRTJFVGVzdFNlYURlbnlBdWRpdA0KICAgICAgdmFsaWRhdGlvbjoNCiAgICAgICAjIFNjaGVtYSBmb3IgdGhlIGBwYXJhbWV0ZXJzYCBmaWVsZA0KICAgICAgICBvcGVuQVBJVjNTY2hlbWE6DQogICAgICAgICAgdHlwZTogb2JqZWN0DQogICAgICAgICAgcHJvcGVydGllczoNCiAgICAgICAgICAgIG1lc3NhZ2U6DQogICAgICAgICAgICAgIHR5cGU6IHN0cmluZw0KICB0YXJnZXRzOg0KICAgIC0gdGFyZ2V0OiBhZG1pc3Npb24uazhzLmdhdGVrZWVwZXIuc2gNCiAgICAgIGNvZGU6DQogICAgICAtIGVuZ2luZTogSzhzTmF0aXZlVmFsaWRhdGlvbg0KICAgICAgICBzb3VyY2U6DQogICAgICAgICAgdmFsaWRhdGlvbnM6DQogICAgICAgICAgLSBleHByZXNzaW9uOiAib2JqZWN0LnNwZWMucmVwbGljYXMgPD0gNSINCiAgICAgICAgICAgIG1lc3NhZ2U6ICJtZXNzYWdlIGV4YW1wbGUi" 
        }, 
        "apiGroups": [ 
          "apps" 
        ], 
        "kinds": [ 
          "Deployment" 
        ], 
        "enforcementPoints": "[parameters('enforcementPoints')]" 
      } 
    } 
  }, 
  "parameters": { 
    "effect": { 
      "type": "String", 
      "metadata": { 
        "displayName": "Effect", 
        "description": "'audit' allows a non-compliant resource to be created or updated, but flags it as non-compliant. 'deny' blocks the non-compliant resource creation or update. 'disabled' turns off the policy." 
      }, 
      "allowedValues": [ 
        "audit", 
        "deny", 
        "disabled" 
      ], 
      "defaultValue": "audit" 
    }, 
  } 
} 

 

Published Nov 09, 2026
Version 1.0
No CommentsBe the first to comment