Skip to content
Back to skills

2857 04 Governance Constraints A6c5e38f

ASecurity

> Generated by bicep-plan agent | 2026-02-11 | Full REST API discovery > [!NOTE] > πŸ“š See [SKILL.md](../../.github/skills/azure-artifacts/SKILL.md) for visual standards. This document captures the governance constraints and Azure Policy requirements that must be addressed in the Bicep implementation for the PCI-DSS Level 1 payment gateway.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
devopsgosqlnodeazuregitapidatabasesecurity

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2857-04-governance-constraints_a6c5e38f --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2857 04 Governance Constraints A6c5e38f?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2857 04 Governance Constraints A6c5e38f
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2857-04-governance-constraints-a6c5e38f/badge)](https://www.skillsdirectory.com/skills/tools-only-2857-04-governance-constraints-a6c5e38f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Governance Constraints - pci-dss-gw

> Generated by bicep-plan agent | 2026-02-11 | Full REST API discovery

> [!NOTE]
> πŸ“š See [SKILL.md](../../.github/skills/azure-artifacts/SKILL.md) for visual standards.

This document captures the governance constraints and Azure Policy requirements
that must be addressed in the Bicep implementation for the PCI-DSS Level 1 payment gateway.


## Discovery Source

> [!IMPORTANT]
> Governance constraints discovered via **REST API** including management group-inherited policies.
> Previous `az policy assignment list` discovery missed 16 of 21 policies.

| Query              | Result                       | Timestamp            |
| ------------------ | ---------------------------- | -------------------- |
| REST API Total     | **21 assignments**           | 2026-02-11T12:00:00Z |
| Subscription-scope | 5 direct assignments         | 2026-02-11T12:00:00Z |
| RG-scoped          | 7 resource group assignments | 2026-02-11T12:00:00Z |
| MG-inherited       | 9 inherited policies         | 2026-02-11T12:00:00Z |
| Deny-effect        | 3 blockers found             | 2026-02-11T12:00:00Z |
| Tag Policies       | 9 tags required (Deny)       | 2026-02-11T12:00:00Z |

**Discovery Method**: REST API
(`GET /subscriptions/{id}/providers/Microsoft.Authorization/policyAssignments?api-version=2022-06-01`)

**Subscription**: noalz (`00858ffc-dded-4f0f-8bbf-e17fff0d47d9`)

**Tenant**: `2d04cb4c-999b-4e60-a3a7-e8993edc768b`

**Scope**: All effective (subscription + resource group + management group inherited)

> [!CAUTION]
> Previous discovery using `az policy assignment list` only returned 5 subscription-scoped policies.
> REST API revealed 16 additional policies including **critical Deny blockers**.

---


## Azure Policy Compliance

| Category | Constraint | Source | Implementation |
| --- | --- | --- | --- |
| **Tags (Deny)** | 9 lowercase tags required on RGs | JV-Enforce RG Tags v3 | All Bicep RG deployments include all 9 |
| **Tags (Modify)** | 9 tags auto-inherited to children | JV-Inherit Tags | No Bicep action β€” policy handles it |
| **VM SKUs (Deny)** | H, M, N series blocked | MCAPSGov Deny | Using D-series β€” compliant |
| **AKS Pools (Deny)** | Max 10 agent pool profiles | MCAPSGov Deny | Using 2 pools β€” compliant |
| **Classic (Deny)** | All Classic resource types blocked | MCAPSGov Deny + Block ARM | Using ARM β€” compliant |
| **SQL Auth (Deny)** | Azure SQL requires AAD-only | MCAPSGov Deny | Using PostgreSQL β€” N/A |
| **HSM Purge (Deny)** | Purge protection required | MCAPSGov Deny | Enable purge protection in Bicep |
| **Compliance (Audit)** | PCI DSS v4 (269 controls) | Subscription policy | Architecture designed for PCI-DSS L1 |
| **Compliance (Audit)** | GDPR (285 controls) | Subscription policy | EU regions: swedencentral/germanywestcentral |
| **Security (Audit)** | Azure Security Baseline (224) | MG policy | Cloud security benchmark posture |
| **Security (Audit)** | MCAPSGov Audit (44) | MG policy | Tenant baseline compliance |
| **MFA (Audit)** | MFA for write/delete operations | MG policy (Γ—2) | Deploying user must have MFA enabled |
| **Naming** | No naming policy discovered | β€” | Follow CAF conventions from azure-defaults |
| **Location** | No location restriction found | β€” | EU regions: swedencentral/germanywestcentral |

---


### Complete Policy Inventory


### Management Group-Inherited Policies (9)

| # | Display Name | Type | Effect | Sub-Policies | Impact |
| - | --- | --- | --- | --- | --- |
| 1 | **JV-Enforce Resource Group Tags v3** | Policy | **Deny** | 1 | 🚫 BLOCKER β€” 9 lowercase tags required |
| 2 | **MCAPSGov Deny Policies** | Initiative | **Deny** | 11 | ⚠️ VM SKU + AKS pool + HSM constraints |
| 3 | **Block Azure RM Resource Creation** | Policy | **Deny** | 1 | βœ… Classic resources only β€” no impact |
| 4 | MCAPSGov Deploy and Modify Policies | Initiative | DeployIfNotExists/Modify | 27 | Auto-deploys security agents |
| 5 | MCAPSGov Audit Policies | Initiative | Audit | 44 | Compliance reporting only |
| 6 | Azure Security Baseline | Initiative | Audit | 224 | Microsoft cloud security benchmark |
| 7 | JV - Inherit Multiple Tags from Resource Group | Policy | Modify | 1 | Auto-inherits 9 tags from RG to children |
| 8 | MFA Enforcement for Resource Write Actions | Policy | Audit | 1 | MFA required for write operations |
| 9 | MFA Enforcement for Resource Delete Actions | Policy | Audit | 1 | MFA required for delete operations |

### Subscription-Scoped Policies (5)

| # | Display Name | Type | Effect | Impact |
| - | --- | --- | --- | --- |
| 10 | PCI DSS v4 | Initiative (269 controls) | Audit | Architecture must align with PCI DSS |
| 11 | EU GDPR 2016/679 | Initiative (285 controls) | Audit | EU data residency validation |
| 12 | ASC DataProtection | Initiative | DeployIfNotExists | Auto-deploys data protection monitoring |
| 13 | ASC OpenSourceRelationalDatabasesProtection | Initiative | DeployIfNotExists | Auto-deploys Defender for PostgreSQL |
| 14 | Defender for SQL Servers on Machines | Initiative | DeployIfNotExists | SQL Defender (not applicable β€” PaaS only) |

### Resource Group-Scoped Policies (7)

All scoped to `rg-arcbox-swc01` β€” a different resource group. **No impact on this project.**

| # | Display Name | Scope |
| - | --- | --- |
| 15 | (ArcBox) Enable SSH Posture Control audit | rg-arcbox-swc01 |
| 16 | (ArcBox) Enable Azure Update Manager for Arc-enabled Windows machines | rg-arcbox-swc01 |
| 17 | (ArcBox) Tag resources (unnamed) | rg-arcbox-swc01 |
| 18 | (ArcBox) Azure Monitor (unnamed) | rg-arcbox-swc01 |
| 19 | (ArcBox) Enable Azure Update Manager for Arc-enabled Linux machines | rg-arcbox-swc01 |
| 20 | (ArcBox) Enable Azure Update Manager for Azure Windows machines | rg-arcbox-swc01 |
| 21 | (ArcBox) Enable Azure Update Manager for Azure Linux machines | rg-arcbox-swc01 |

---


## Plan Adaptations Based on Policies

### Tag Schema (Updated β€” CRITICAL)

```bicep
// Resource Group tags β€” ALL 9 REQUIRED by JV-Enforce Resource Group Tags v3 (Deny)
// Case-sensitive: ALL lowercase
@description('Deployment environment')
@allowed(['dev', 'staging', 'prod'])
param environment string

@description('Team or individual owner')
param owner string

@description('Cost center code')
param costCenter string

@description('Technical contact email')
param technicalContact string

var requiredRgTags = {
  environment: environment
  owner: owner
  costcenter: costCenter
  application: 'pci-dss-gw'
  workload: 'payment-gateway'
  sla: '99.99'
  'backup-policy': 'daily'
  'maint-window': 'Sun:02:00-06:00'
  'technical-contact': technicalContact
}

// Additional project-standard tags (not policy-enforced but recommended)
var allTags = union(requiredRgTags, {
  ManagedBy: 'Bicep'
  Project: 'pci-dss-gw'
})
```

> [!IMPORTANT]
> Resource groups require ALL 9 tags from `JV-Enforce Resource Group Tags v3`.
> Child resources auto-inherit these 9 tags via `JV - Inherit Multiple Tags from Resource Group`
> (Modify effect). Additional tags (ManagedBy, Project) can be appended but are NOT required.

### Architectural Constraints

| Original Design | Blocking Policy | Effect | Required Adaptation |
| --- | --- | --- | --- |
| 4 PascalCase tags | JV-Enforce RG Tags v3 | Deny | **9 lowercase tags** on all resource groups |
| Key Vault Premium HSM | MCAPSGov Deny (HSM purge) | Deny | `enablePurgeProtection: true` required |
| AKS 2 node pools | MCAPSGov Deny (AKS pool limit) | Deny | βœ… Compliant (2 < 10 limit) β€” document constraint |
| D8s_v5 / D4s_v5 VMs | MCAPSGov Deny (VM SKU) | Deny | βœ… Compliant β€” D-series not blocked |

### Auto-Applied Configurations

| Policy | Effect | What Gets Auto-Applied |
| --- | --- | --- |
| JV - Inherit Multiple Tags from Resource Group | Modify | 9 RG tags auto-copied to all child resources |
| MCAPSGov Deploy and Modify Policies (27 sub-policies) | DeployIfNotExists/Modify | Security agents, diagnostic settings |
| ASC DataProtection | DeployIfNotExists | Data protection monitoring agents |
| ASC OpenSourceRelationalDatabasesProtection | DeployIfNotExists | Defender for PostgreSQL monitoring |
| Defender for SQL on Machines | DeployIfNotExists | SQL Defender agents (N/A β€” PaaS) |

---


## Deployment Blockers

> [!CAUTION]
> **CRITICAL**: Policies that BLOCK deployment. Resolution is REQUIRED before proceeding.

### Blocker 1: JV-Enforce Resource Group Tags v3 (DENY)

**Assignment**: `b1ad1a690a5148ec8707ff17`

**Scope**: Management Group (Tenant Root `2d04cb4c-999b-4e60-a3a7-e8993edc768b`)

**Enforcement Mode**: Default (enabled)

**Effect**: Deny

**Policy Definition**: `27833bcf-5909-4a37-891c-16a3cb06856d`

**Policy Rule**:

- Applies to: `Microsoft.Resources/subscriptions/resourceGroups`
- Excludes RG names matching: `AzureBackupRG*`, `ResourceMover*`, `databricks-rg*`,
  `NetworkWatcherRG`, `microsoft-network`, `LogAnalyticsDefaultResources`, `rg-amba-*`,
  `DynamicsDeployments*`, `MC_myResourceGroup*`
- **Denies creation if ANY of 9 tags are missing** (case-sensitive, all lowercase)

| # | Tag Name             | Required | Case      |
| - | -------------------- | -------- | --------- |
| 1 | `environment`        | Yes      | lowercase |
| 2 | `owner`              | Yes      | lowercase |
| 3 | `costcenter`         | Yes      | lowercase |
| 4 | `application`        | Yes      | lowercase |
| 5 | `workload`           | Yes      | lowercase |
| 6 | `sla`                | Yes      | lowercase |
| 7 | `backup-policy`      | Yes      | lowercase |
| 8 | `maint-window`       | Yes      | lowercase |
| 9 | `technical-contact`  | Yes      | lowercase |

> [!WARNING]
> **Our original plan only had 4 tags (Environment, ManagedBy, Project, Owner) with PascalCase.**
> This policy requires **9 tags** with **lowercase** names. Resource group creation will be
> **DENIED** without all 9 tags present.

**Resolution**: Update all Bicep resource group deployments to include all 9 required tags
with correct lowercase casing. The `ManagedBy` and `Project` tags from our defaults are
supplementary but NOT required by policy.

### Blocker 2: MCAPSGov Deny Policies (11 sub-policies)

**Assignment**: `MCAPSGovDenyPolicies`

**Scope**: Management Group (Tenant Root `2d04cb4c-999b-4e60-a3a7-e8993edc768b`)

**Enforcement Mode**: Default (enabled)

**Effect**: Deny (initiative with 11 policies)

| # | Reference ID | Policy Definition | Effect | Impact on This Project |
| - | --- | --- | --- | --- |
| 1 | BlockVMSKUs_H | VirtualMachine_SKU_Deny | Deny | βœ… Safe β€” we use D-series, not H-series (17 blocked SKUs) |
| 2 | BlockVMSKUs_M | VirtualMachine_SKU_Deny | Deny | βœ… Safe β€” we use D-series, not M-series (44 blocked SKUs) |
| 3 | BlockVMSKUs_N | VirtualMachine_SKU_Deny | Deny | βœ… Safe β€” we use D-series, not N-series (64 blocked SKUs) |
| 4 | AKS_LimitNodeCount | AKS_LimitNodeCount_Deny | Deny | βœ… Safe β€” our plan uses 2 pools (system + CDE), limit is 10 |
| 5 | VMSS_LimitNodesCount | VMSS_LimitNodesCount_Deny | Deny | ⚠️ Verify β€” AKS uses VMSS internally, check node count limit |
| 6 | OpenAI_BlockProvisionedCapacity | AzureOpenAI_ProvisionedCapacity_Deny | Deny | βœ… N/A β€” not in our architecture |
| 7 | Sentinel_Commitment_Deny | Sentinel_Commitment_Deny | Deny | βœ… N/A β€” not in our architecture |
| 8 | AzureSQL_WithoutAzureADOnlyAuthentication_Deny | AzureSQL_WithoutAzureADOnlyAuthentication_Deny | Deny | βœ… N/A β€” we use PostgreSQL, not Azure SQL |
| 9 | AzureSQLMI_WithoutAzureADOnlyAuthentication_Deny | AzureSQLMI_WithoutAzureADOnlyAuthentication_Deny | Deny | βœ… N/A β€” not in our architecture |
| 10 | NotAllowedResourceTypes | 6c112d4e-5bc7-47ae-a041-ea2d9dccd749 | Deny | βœ… Safe β€” blocks 57 Classic (ASM) resource types only |
| 11 | KeyVaultManagedHSM_PurgeProtectionEnabled | KeyVaultManagedHSM_PurgeProtectionEnabled_Deny | Deny | ⚠️ Ensure β€” Key Vault HSM must have purge protection enabled |

**Resolutions**:

1. **AKS agent pool limit**: Architecture uses 2 pools β€” compliant. Document constraint.
2. **VMSS node count**: Verify the exact limit parameter and ensure AKS autoscaler max
   does not exceed it.
3. **Key Vault HSM purge protection**: Set `enablePurgeProtection: true` on Key Vault.
4. **VM SKUs**: Only D-series VMs used β€” compliant. Document blocked families.

### Non-Blocker: Block Azure RM Resource Creation (DENY)

**Scope**: Management Group (Tenant Root)

**Assessment**: This policy ONLY blocks Classic (ASM) resource types:
`Microsoft.ClassicCompute/*`, `Microsoft.ClassicStorage/*`, `Microsoft.ClassicNetwork/*`.

**Impact**: None β€” our Bicep templates use ARM resources exclusively.

---


## Required Tags

### Resource Group Tags (MANDATORY β€” Deny enforced)

```bicep
// These 9 tags are REQUIRED by JV-Enforce Resource Group Tags v3 (Deny)
// ALL lowercase, case-sensitive β€” deployment will FAIL without them
var requiredRgTags = {
  environment: environment          // 'dev' | 'staging' | 'prod'
  owner: owner                      // Team or individual
  costcenter: costCenter            // Cost center code
  application: 'pci-dss-gw'          // Application name
  workload: 'payment-gateway'      // Workload type
  sla: '99.99'                     // SLA target
  'backup-policy': 'daily'         // Backup policy
  'maint-window': 'Sun:02:00-06:00' // Maintenance window
  'technical-contact': techContact  // Technical contact email
}
```

### Resource Tags (Project standard + auto-inherited)

```bicep
// Child resources auto-inherit 9 RG tags via JV-Inherit policy (Modify)
// These additional tags are project convention, not policy-enforced
var additionalTags = {
  ManagedBy: 'Bicep'
  Project: 'pci-dss-gw'
}

var allTags = union(requiredRgTags, additionalTags)
```

---


## Security Policies

| Area | Requirement | Source |
| --- | --- | --- |
| HTTPS Only | TLS 1.2+ on all services | PCI Req 4 (proactive) |
| Public Access | Disabled via private endpoints | PCI Req 1 (proactive) |
| Managed Identity | All service-to-service auth | PCI Req 8 (proactive) |
| Key Vault HSM | Purge protection required | MCAPSGov Deny + PCI Req 3 |
| AAD-Only Auth | Required for all databases | MCAPSGov Deny (SQL) + PCI Req 8 |
| Network Segmentation | Hub-spoke with Firewall IDPS | PCI Req 1 (proactive) |
| Container Security | Defender auto-enabled | MCAPSGov Deploy (auto) |
| Logging | 1-year retention, tamper-proof | PCI Req 10 (proactive) |
| Defender for PostgreSQL | Auto-enabled | ASC policy (auto) |
| Defender for Cloud | Enhanced posture | PCI Req 11 (proactive) |
| MFA Enforcement | Write/delete operations | MG policy (Audit) |
| Security Baseline | 224 controls | MG policy (Audit) |

---


## Cost Policies

| Constraint | Source | Impact |
| --- | --- | --- |
| H/M/N VM SKUs blocked | MCAPSGov Deny (3 policies) | Prevents expensive HPC/GPU VMs |
| OpenAI provisioned capacity blocked | MCAPSGov Deny | Prevents AI spend |
| Sentinel commitment tier blocked | MCAPSGov Deny | Prevents commitment over-provisioning |
| No budget policy found | β€” | Recommend Azure Cost Management alert at $20,000/mo |
| No reservations policy | β€” | Recommend 1-year RI for AKS + PostgreSQL (~35% savings) |

---


## Network Policies

| Policy | Constraint | Impact |
| --- | --- | --- |
| No location restriction | No Deny policy on allowed locations | Using EU regions: swedencentral/germanywestcentral |
| No naming policy | No Deny policy on naming conventions | Following CAF conventions from azure-defaults skill |
| NSG flow logs | MCAPSGov Deploy auto-enables | Auto-applied via DeployIfNotExists |

> [!NOTE]
> No network-specific Deny policies found. Architecture follows PCI-DSS network
> segmentation requirements proactively (hub-spoke, private endpoints, Azure Firewall IDPS).


## References

| Topic | Link |
| --- | --- |
| Azure Policy effects | [Policy effects](https://learn.microsoft.com/azure/governance/policy/concepts/effects) |
| Tag enforcement patterns | [Tag policies](https://learn.microsoft.com/azure/azure-resource-manager/management/tag-policies) |
| PCI-DSS on Azure | [PCI compliance](https://learn.microsoft.com/azure/compliance/offerings/offering-pci-dss) |
| Azure Policy exemptions | [Exemption structure](https://learn.microsoft.com/azure/governance/policy/concepts/exemption-structure) |
| Tag inheritance | [Inherit a tag from RG](https://learn.microsoft.com/azure/governance/policy/samples/built-in-policies#tags) |
| MCAPSGov policies | Tenant Root management group (internal) |
| REST API discovery | [Policy assignments API](https://learn.microsoft.com/rest/api/policy/policy-assignments/list) |

---

*Governance constraints discovered via REST API on subscription `noalz` (`00858ffc-dded-4f0f-8bbf-e17fff0d47d9`).*
*All 21 assignments verified including 9 management group-inherited policies.*
*See [governance-discovery.instructions.md](../../.github/instructions/governance-discovery.instructions.md) for discovery methodology.*

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.