Every Azure organization has Azure Policy enabled somewhere. Most of them have a half-configured landing zone that enables 30 policies in audit mode and then never moves any of them to deny. That is not a governance strategy; that is a compliance report generator. Azure Policy's actual value is as an enforcement layer — a control plane that blocks resources, configurations, and behaviours from existing in the first place — and using it for supply chain enforcement specifically is one of the highest-leverage controls a platform team can invest in.
This post is the initiative I build in the first 90 days with any Azure-centric organization that wants real supply chain enforcement. The policies are ordered by "how likely are you to already have them" descending, so the new-to-you ones are near the bottom.
What Azure Policy Actually Is
Azure Policy is a Resource Manager extension that evaluates resource requests against rules, with four effects: audit, deny, modify, and deployIfNotExists (DINE). Deny prevents the resource from being created. Modify rewrites properties at creation or updates existing ones. DINE triggers a remediation deployment to create or configure related resources. Audit records non-compliance without blocking.
The supply chain enforcement story lives in deny and modify primarily, with DINE for the cases where enforcement requires creating a missing resource (like a diagnostic setting). audit mode has a place during rollout, but an audit-only policy is a reporting control, not an enforcement control. I draw the distinction sharply because most "we have that policy" claims I hear turn out to be audit-only claims.
The Container Supply Chain Set
Start with the Azure Policy built-in initiative "Kubernetes cluster pod security baseline standards for Linux-based workloads" — that is table stakes, not supply chain. The supply chain-specific policies for AKS are:
- "Container images should be signed by trusted image signing solutions" — deny effect, enforces that images pulled into AKS have valid Notation signatures verifiable against your trust policy. Enabled through the Image Integrity feature (GA 2023) that uses Ratify under the hood.
- "Kubernetes cluster containers should only use allowed images" — deny effect, restricts the image registry prefix to a vetted list. This is the control that keeps an attacker who compromises a namespace from pulling
evil.dkr.ecr.amazonaws.com/backdoor:latest. - "Kubernetes cluster should not allow privileged containers" — deny effect, a pod security baseline control that matters for supply chain because privileged containers can mount host filesystems and exfiltrate credentials from the node.
The first two are the ones most teams skip. Image Integrity requires signatures on every image, which means turning it on breaks deployments until the signing pipeline is in place — so it has to be the last step of a signing rollout, not the first. The allowed-images policy is simpler to roll out because the registry prefix is often already well-known; just enable it in audit mode for a week to catch exceptions, then flip to deny.
For Azure Container Registry specifically, the policy "Container registries should have anonymous authentication disabled" (deny effect) closes a real foot-gun that shipped as a feature in 2022 and is off by default but has been turned on by accident more than once. Disable it organizationally.
The Identity and Credential Set
Long-lived credentials are a supply chain problem because they persist after compromise. The policies that push Azure toward short-lived, identity-based access:
- "App Service apps should have local authentication methods disabled for SCM site" — deny effect, prevents publish profiles and basic authentication on App Service SCM endpoints. Shipped 2023, should be deny everywhere.
- "Azure SQL Database should have Azure Active Directory Only Authentication enabled" — deny effect, blocks creation of SQL databases with SQL authentication. If you have to allow SQL auth somewhere, scope the exception to a specific subscription, not the tenant.
- "Storage accounts should prevent shared key access" — deny effect. Storage account keys are the classic long-lived credential; forcing Azure AD auth on storage account data plane operations eliminates them from new workloads.
- "Key Vault should use RBAC permission model" — deny effect on new vaults. The legacy access policy model is not deprecated formally, but there is no reason to create a new access-policy vault, and RBAC vaults are audited through Azure RBAC, which integrates with everything.
Rolling these out is a sequence. I usually start with Key Vault RBAC-only (lowest disruption — only affects new vault creation) and end with storage shared-key prevention (highest disruption, because many legacy workloads rely on keys).
The Managed Identity Defaults
Managed identities are the right answer for almost every Azure-to-Azure authentication, and Azure Policy can enforce that they are used. Two initiatives to know:
- "System-assigned managed identity should be enabled for [resource type]" — DINE effect, turns on a system-assigned identity if missing. Available for VMs, App Service, Functions, Logic Apps, and API Management.
- "Azure subscriptions should have a log profile for Activity Log" plus the identity-based log forwarding policies — ensure that the identity that writes logs is a managed identity, not a service principal secret.
The more useful pattern than the DINE is a custom policy that denies creation of App Service or Function resources without a managed identity. That is a 20-line Azure Policy definition, and it eliminates the "we'll add an identity later" drift that produces service-principal-backed workloads in places they should not be.
The Provenance and Logging Set
For supply chain observability — the "what did we deploy from where" question — the policies that matter are:
- "Configure diagnostic settings for Azure Key Vault to Log Analytics" (DINE) — captures every secret read, write, and version change. Without this, rotation audits are impossible.
- "Configure diagnostic settings for Azure Container Registry to Log Analytics" (DINE) — captures every push, pull, and repository access. Critical for investigating suspected supply chain tampering.
- "Activity log should be retained for at least one year" (audit, with a DINE counterpart to configure retention) — the Activity Log is the authoritative record of who did what in the subscription, and default retention is 90 days.
Retention is boring until you need it, and then it is the only thing that matters. One-year retention at minimum, two years for regulated workloads.
Custom Policies for Your Supply Chain
Built-ins cover maybe 60% of what a mature supply chain control requires. The other 40% is custom policies against the specific patterns your organization cares about. Common ones I have written:
- Deny creation of any compute resource (VM, AKS node pool, Container App) in regions outside an approved list. This is both a data-residency control and a supply chain control, because compute in unapproved regions often runs without the logging pipeline wired in.
- Deny public IP addresses on resources that should never be internet-exposed (database tier, internal service buses). The policy checks the resource type and the
publicIPAllocationMethodproperty. - Require a specific tag (
owner,cost-center,repo-url) on every resource, with deny effect. This is the enforcement that makes "which repo built this resource" answerable from Azure Resource Graph alone. - Deny use of specific deprecated API versions on resource providers. The resource provider ecosystem deprecates APIs regularly; the deprecated APIs are a supply chain risk because they do not get bug fixes.
Custom policies are written in the same ARM-template-expression language as built-ins. The authoring experience improved significantly in 2023 with the VS Code Azure Policy extension, which provides schema validation and test evaluation against sample resources. Writing a policy is an afternoon; getting the rollout plan right is a week.
Initiative Assignment and Scope
Assign initiatives at the management group level, not at individual subscriptions. A management group hierarchy that mirrors your organization — a root group, a "production" group, a "non-production" group, a "sandbox" group — lets you enforce stricter policies on production without coupling them to specific subscriptions.
Exceptions belong in policy exemptions, not in looser assignments. An exemption is a first-class Azure resource with a time bound and a reviewer; a looser assignment is just a looser assignment with no audit trail. Always prefer exemptions, and review them on the exemption expiry date.
How Safeguard Helps
Safeguard reconciles deployed Azure Policy assignments against a supply chain control baseline and surfaces the gap — which controls are in audit mode when they should be deny, which management groups are missing an initiative, which resources are exempt without a review date. For the specific policies in this post, the platform tracks rollout progress (audit coverage, deny coverage, remediation success) rather than point-in-time compliance, so platform teams can run the 90-day rollout as a program with dashboards instead of a series of tickets. The result is a policy inventory that is actually an enforcement inventory.