Skip to content

Step 3.5 — Governance

Generated by Bicep Planner agent | 2026-03-11

⬅️ Previous📑 IndexNext ➡️
Architecture Decision RecordDemo IndexImplementation Plan

PropertyValue
MethodAzure REST API (management.azure.com)
Subscriptionnoalz (00858ffc-dded-4f0f-8bbf-e17fff0d47d9)
TenantLord of the Cloud (2d04cb4c-999b-4e60-a3a7-e8993edc768b)
Discovery Date2026-03-11
Total Policy Assignments21
ScopeSubscription + Management Group (inherited)

[!NOTE] Policies discovered via REST API include management group-inherited policies.

ScopeCountMethod
Subscription-level5REST API (/subscriptions/{id}/providers/Microsoft.Authorization/policyAssignments)
Management Group-inherited10REST API (management group scope)
ArcBox resource-group-scoped6REST API (limited to rg-arcbox-swc01, excluded from project)
Total21Matches Azure Portal total

ArcBox-scoped assignments (6, excluded):

  1. Enable Azure Monitor for VMs — scope: rg-arcbox-swc01
  2. Enable Azure Monitor for VMSS — scope: rg-arcbox-swc01
  3. Deploy Dependency Agent for Linux VMs — scope: rg-arcbox-swc01
  4. Deploy Dependency Agent for Windows VMs — scope: rg-arcbox-swc01
  5. Configure Linux VMs to run Azure Monitor Agent — scope: rg-arcbox-swc01
  6. Configure Windows VMs to run Azure Monitor Agent — scope: rg-arcbox-swc01

These 6 assignments only affect resources in the ArcBox resource group and have zero impact on this project’s resources in rg-nff-{env}-swedencentral.


EffectCountImpact on Project
Deny8 assignments (3 initiatives)2 blockers for project resources
Audit / AuditIfNotExists5 assignments (3 initiatives + 2 regulatory)Compliance visibility — no deployment blocks
Modify / DeployIfNotExists2 assignmentsAuto-remediation of tags and blob access
Other6 (ArcBox-scoped)No impact — different resource group scope
PolicyScopeImpactSeverity
JV-Enforce Resource Group Tags v3Management Group⛔ BLOCKER — RG creation fails without 9 mandatory tagsCritical
SFI-ID4.2.2 SQL DB - Safe Secrets StandardManagement Group⛔ BLOCKER — SQL Server requires azureADOnlyAuthentication: trueCritical
MFA for Resource Write ActionsManagement Group⚠️ WARNING — Deployer must have MFA enabledHigh
MFA for Resource Delete ActionsManagement Group⚠️ WARNING — Affects teardown onlyMedium
Block Classic ResourcesManagement Group✅ No impact — project uses ARM resources onlyNone
Not Allowed Resource TypesManagement Group✅ No impact — blocks Classic types onlyNone
Block VM SKUs (H/M/N series)Management Group✅ No impact — project does not use VMsNone
Key Vault HSM Purge ProtectionManagement Group✅ No impact — project uses Standard KVNone
PolicyScopeRelevant Checks
GDPR 2016/679SubscriptionData residency, encryption, access controls
PCI DSS v4SubscriptionNetwork segmentation, encryption, TLS
Azure Security BaselineManagement GroupTLS 1.2, identity, network, monitoring
MCAPSGov Audit (44 policies)Management GroupSQL auditing, threat detection, FTP-S only, TLS, diagnostics
ASC DataProtectionSubscriptionStorage and SQL data protection

Modify / DeployIfNotExists Policies (Auto-Remediation)

Section titled “Modify / DeployIfNotExists Policies (Auto-Remediation)”
PolicyScopeAction
JV - Inherit Multiple Tags from RGManagement GroupAuto-copies 9 tags from RG to child resources
MCAPSGov Deploy & Modify (27 policies)Management GroupDisables blob anonymous access, disables local auth on storage

Adaptation 1: Expanded Tag Requirements (CRITICAL)

Section titled “Adaptation 1: Expanded Tag Requirements (CRITICAL)”

The architecture planned 4 tags (Environment, ManagedBy, Project, Owner). Azure Policy enforces 9 tags on resource groups:

#Tag NamePlanned?SourceExample Value
1environment✅ Yes (as Environment)Architecturedev, prod
2owner✅ Yes (as Owner)Architecturenordic-fresh-foods-team
3costcenterNEWPolicy DenyNFF-001
4applicationNEWPolicy Denyfreshconnect
5workloadNEWPolicy Denyweb-app
6slaNEWPolicy Deny99.9%
7backup-policyNEWPolicy Denydaily-30d
8maint-windowNEWPolicy Denysun-02:00-06:00-utc
9technical-contactNEWPolicy Denycto@nordicfreshfoods.eu

[!IMPORTANT] The ManagedBy and Project tags from the architecture are NOT in the Policy Deny list but remain best practice. The implementation plan includes all 11 tags (9 policy-enforced + 2 best-practice).

Strategy: Define all 9 policy-required tags as Bicep parameters with defaults. Tags set on RG; child resources auto-inherit via Modify policy.

Adaptation 2: Azure SQL Azure AD-Only Auth (Already Aligned)

Section titled “Adaptation 2: Azure SQL Azure AD-Only Auth (Already Aligned)”

Architecture already specifies azureADOnlyAuthentication: true. No change needed — this confirms policy compliance.

Adaptation 3: MFA Prerequisite for Deployment

Section titled “Adaptation 3: MFA Prerequisite for Deployment”

Deployer account must have MFA enabled (MFA Write Enforcement deny policy). This is a control-plane requirement, not a template change. Document in deployment prerequisites.

CI/CD automation path (conditional): Federated workload identity (OIDC) with a service principal is a potential alternative for automated pipelines. However, this path is unverified against this tenant’s write-action enforcement model. The tenant’s Conditional Access policies may treat workload identities differently from interactive MFA sessions. Validation task: Before relying on OIDC for CI/CD, test a federated service principal write operation against this subscription and confirm the MFA deny policy does not block it. Until validated, interactive MFA-authenticated deployment remains the only proven path.

MCAPSGov Deploy policy auto-disables blob anonymous access. Architecture already specifies allowBlobPublicAccess: false — auto-remediation is a safety net.


#BlockerPolicyResolutionStatus
1Resource group creation without 9 tagsJV-Enforce RG Tags v3Add 5 new tags to Bicep parameters🔧 Resolved in plan
2SQL Server without AD-only authSFI-ID4.2.2Already in architecture✅ Pre-resolved
3Deployer without MFAMFA Write EnforcementInteractive MFA required; OIDC conditional (unverified)📋 Documented

// All 9 tags are MANDATORY on resource groups (Azure Policy: Deny)
var rgTags = {
environment: environment // 'dev' | 'prod'
owner: owner // team or individual
costcenter: costCenter // cost center code
application: applicationName // application identifier
workload: workloadName // workload type
sla: slaTarget // SLA percentage
'backup-policy': backupPolicy // backup schedule
'maint-window': maintWindow // maintenance window
'technical-contact': techContact // technical contact email
// Best-practice additions (not policy-enforced):
ManagedBy: 'Bicep'
Project: 'nordic-fresh-foods'
}

Child resources automatically receive all 9 policy-enforced tags from their resource group via the JV - Inherit Multiple Tags Modify policy. Additional resource-specific tags (e.g., ManagedBy, Project) should be set explicitly in templates.


RequirementPolicy SourceImplementation
Azure AD-only auth for SQLMCAPSGov DenyazureADOnlyAuthentication: true
TLS 1.2 minimumAzure Security Baseline (Audit)minTlsVersion: 'TLS1_2' on all services
HTTPS-onlyAzure Security Baseline (Audit)httpsOnly: true on App Service
No blob public accessMCAPSGov Deploy (Modify)allowBlobPublicAccess: false
SQL threat detectionMCAPSGov AuditEnable in SQL Server config
SQL auditingMCAPSGov AuditEnable diagnostic settings
MFA for writesManagement Group DenyDeployer prerequisite
Managed IdentityAzure Security Baseline (Audit)System-assigned MI on App Service

PolicyEffectImpact
Budget alert (planned)N/A (custom)Aggregate €1K + per-env budgets with 80/100/120% forecast alerts
Anomaly detection (planned)N/A (custom)Separate Cost Management anomaly alert (not part of budget resource) — via Microsoft.CostManagement/scheduledActions or Portal
VM SKU restrictionsDeny (H/M/N)No impact — no VMs in project
AKS node limitDenyNo impact — no AKS in project

[!NOTE] No cost-specific Deny policies affect planned resources. Budget monitoring is implemented via Microsoft.Consumption/budgets resource with forecast thresholds at 80%, 100%, 120%. Anomaly detection is a separate Cost Management capability implemented via Microsoft.CostManagement/scheduledActions (subscription scope) or configured in Azure Portal — it is NOT a property of the budget resource.


RequirementSourceImplementation
Private Endpoints for data servicesArchitecture + PCI DSS v4 (Audit)PE for SQL + Storage + Key Vault in pe-subnet
VNet integrationArchitectureApp Service delegated to app-subnet
Public network access disabledArchitecture + Azure Security BaselinepublicNetworkAccess: 'Disabled' on SQL, Storage, and Key Vault
NSG on all subnetsArchitecture + Azure Security BaselineNetwork Security Groups on snet-app, snet-data, and snet-pe

[!IMPORTANT] The FreshConnect application uses redirect-based tokenization for payment processing. Card data is handled exclusively by the third-party payment provider (e.g., Stripe/Adyen hosted payment fields). No cardholder data (CHD) enters or is stored in the Azure environment.

ComponentPCI ScopeRationale
App Service (public tier)Out of scopeServes redirect/iframe to hosted payment fields; no CHD transits App Service
Azure SQL DatabaseOut of scopeStores order data, user profiles — no PAN, CVV, or track data
Storage AccountOut of scopeProduct images, static assets — no payment data
Application Insights / Log AnalyticsOut of scopeNo payment payload logging; request/response bodies are NOT captured
Key VaultOut of scopeStores connection strings and app secrets — no payment cryptographic keys

Compensating controls on public web tier:

  • TLS 1.2+ enforced on all inbound traffic
  • HTTPS-only (httpsOnly: true)
  • Managed Identity for all backend connections (no credential exposure)
  • FTPS-only (ftpsState: 'FtpsOnly')
  • Content Security Policy headers to restrict iframe sources to approved payment provider domains

If the application evolves to process CHD directly, this boundary assessment must be revisited and the App Service/SQL/Storage tier re-scoped into the CDE.


flowchart TD
    A["Deploy Request"] --> B{"9 RG Tags Present?"}
    B -- Yes --> C{"SQL AAD-Only Auth?"}
    B -- No --> D["⛔ Deny: Tag Policy"]
    C -- Yes --> E{"MFA Enabled?"}
    C -- No --> F["⛔ Deny: SQL Policy"]
    E -- Yes --> G["✅ Deploy Allowed"]
    E -- No --> H["⛔ Deny: MFA Policy"]
    style D fill:#D83B01,color:#fff
    style F fill:#D83B01,color:#fff
    style H fill:#D83B01,color:#fff
    style G fill:#107C10,color:#fff
DocumentLink
Azure Policy definition referenceMicrosoft Learn
GDPR compliance on AzureMicrosoft Learn
PCI DSS on AzureMicrosoft Learn
Azure Security BaselineMicrosoft Learn