This guide covers security best practices for Azure infrastructure deployed with Farmer, based on the Microsoft Security Best Practices and the OWASP Top 10.
The OWASP Top 10 (https://owasp.org/www-project-top-ten/) defines critical web application security risks. Here’s how they map to Azure infrastructure and Farmer protections:
| OWASP Risk | Azure Context | Farmer Protection |
|---|---|---|
| A01: Broken Access Control | Overly permissive RBAC, public storage | Role-based access control, private storage defaults |
| A02: Cryptographic Failures | Unencrypted SQL, Storage, Cosmos DB | Encryption enabled by default, HTTPS enforced |
| A03: Injection | SQL injection, command injection | Parameterized queries, Managed Identity for DB auth |
| A05: Security Misconfiguration | Public storage, weak NSG rules | Secure defaults, deny-by-default NSG rules |
| A07: Broken Authentication | Weak passwords, no MFA | Azure AD B2C with strong password policies |
| A08: Integrity Failures | Compromised container images | Container Registry scanning, signed deployments |
| A09: Logging Failures | No Application Insights, missing logs | Application Insights integration, diagnostic settings |
Troy Hunt’s Guidance on Authentication: “Passwords are fundamentally broken. Validate new passwords against Pwned Passwords API containing 600M+ breached passwords from real-world attacks.”
Integrate Have I Been Pwned (https://haveibeenpwned.com/) into Azure AD B2C custom policies for password validation. Troy Hunt, Microsoft Regional Director and creator of Have I Been Pwned, maintains the definitive database of compromised credentials used by Microsoft and major tech companies.
Reference: OWASP Top 10 2021 (https://owasp.org/www-project-top-ten/)
Azure security is built on the Zero Trust model, which assumes breach and verifies each request as if it originated from an untrusted network. The Zero Trust model is based on three principles from Microsoft Security:
Verify Explicitly: Always authenticate and authorize based on all available data points including user identity, location, device health, service or workload, data classification, and anomalies.
Use Least Privilege Access: Limit user access with Just-In-Time and Just-Enough-Access (JIT/JEA), risk-based adaptive policies, and data protection.
Assume Breach: Minimize blast radius and segment access. Verify end-to-end encryption. Use analytics to get visibility, drive threat detection, and improve defenses.
Reference: Azure Security Best Practices - Zero Trust (https://learn.microsoft.com/en-us/security/zero-trust/)
Privileged Identity Management provides time-based and approval-based role activation to mitigate the risks of excessive, unnecessary, or misused access permissions. PIM is essential for implementing Just-In-Time access and meeting SOX/SOC 2 compliance requirements.
Key PIM Capabilities:
PIM Configuration (Portal-based):
While Farmer doesn’t directly support PIM configuration, you should configure PIM for the following Azure roles:
PIM Best Practices:
Reference: Microsoft Entra Privileged Identity Management (https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/)
Conditional Access is the policy engine that enforces Zero Trust by evaluating signals from identity, device, location, and risk before allowing access. This is critical for preventing credential-based attacks.
Common Conditional Access Policies:
Conditional Access Configuration (Portal-based):
Farmer doesn’t directly support Conditional Access configuration. Configure these policies in the Azure Portal under Microsoft Entra ID → Security → Conditional Access:
Policy: Require MFA for All Users
- Users: All users
- Cloud apps: All cloud apps
- Conditions: Any location
- Access controls: Grant access, Require MFA
Policy: Block Legacy Authentication
- Users: All users
- Cloud apps: All cloud apps
- Conditions: Client apps (Exchange ActiveSync, Other clients)
- Access controls: Block access
Policy: Require Compliant Device
- Users: All users
- Cloud apps: Office 365, Azure Portal
- Conditions: Any location
- Access controls: Grant access, Require device to be marked as compliant
Conditional Access Best Practices:
Reference: Microsoft Entra Conditional Access (https://learn.microsoft.com/en-us/entra/identity/conditional-access/)
Implement strong authentication with Azure AD B2C.
open Farmer
open Farmer.Builders
let b2cTenant = b2cTenant {
name "myb2ctenant"
sku B2c.Sku.PremiumP1
// Configure in Azure Portal:
// 1. Enable MFA for all users
// 2. Password complexity: minimum 12 characters
// 3. Integrate with Have I Been Pwned API via custom policy
// 4. Implement account lockout after 5 failed attempts
// 5. Use conditional access policies
}
Have I Been Pwned Integration:
Azure AD B2C supports custom policies that can call the Pwned Passwords API to reject compromised passwords:
Reference: Integrate Have I Been Pwned with Azure AD B2C (https://docs.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-password-complexity-haveibeenpwned)
Never hardcode secrets. Always use Azure Key Vault.
open Farmer.KeyVault
let vault = keyVault {
name "mysecurevault"
sku Sku.Standard
// Enable soft delete and purge protection
enable_soft_delete_with_purge_protection
// Restrict network access
add_ip_rule "203.0.113.0"
add_ip_rule "203.0.113.1"
restrict_to_ip_rules
// Add secrets
add_secret "database-password"
add_secret "api-key"
}
// Grant web app access using Managed Identity
let app = webApp {
name "secure-webapp"
system_identity
// Reference Key Vault secret
secret_setting "DbPassword" vault.ResourceId "database-password"
}
Key Vault Security Best Practices:
Reference: Azure Key Vault Security Overview (https://docs.microsoft.com/en-us/azure/key-vault/general/security-features)
Protect SQL databases with multiple layers of security.
open Sql
let database = sqlServer {
name "secureserver"
admin_username "sqladmin"
add_databases [
sqlDb {
name "productiondb"
sku DtuSku.S1
use_encryption
}
]
// Enable Azure services access
enable_azure_firewall
add_firewall_rule "AllowAzureServices" "0.0.0.0" "0.0.0.0"
// Only allow specific IPs
add_firewall_rule "Office" "203.0.113.10" "203.0.113.20"
}
SQL Security Checklist:
OWASP SQL Injection Prevention:
Always use parameterized queries in your application code:
// ❌ BAD: String interpolation in SQL queries (vulnerable to injection)
let badQuery userEmail =
$"SELECT * FROM Users WHERE Email = '{userEmail}'"
// ✅ GOOD: Use parameterized queries in your application code
// This is handled by your data access library (Dapper, Entity Framework, etc.)
// Example with type-safe F# query builders or stored procedures
Reference: Azure SQL Security Best Practices (https://docs.microsoft.com/en-us/azure/azure-sql/database/security-best-practice)
Secure blob storage against unauthorized access.
let storage = storageAccount {
name "securestorage"
sku Storage.Sku.Standard_LRS
// Require HTTPS
enable_data_lake_storage
min_tls_version Tls12
// Disable public access
disable_public_network_access
// Enable soft delete
enable_blob_soft_delete 30<Days>
// Lifecycle management
add_lifecycle_rule "archive-old-data" [
Storage.CoolAfter 30<Days>
Storage.ArchiveAfter 90<Days>
Storage.DeleteAfter 365<Days>
] Storage.NoRuleFilters
}
Storage Security Best Practices:
Reference: Azure Storage Security Guide (https://docs.microsoft.com/en-us/azure/storage/blobs/security-recommendations)
Private Endpoints provide secure connectivity to Azure PaaS services over a private IP address from your VNet, eliminating exposure to the public internet. This is critical for Zero Trust architecture and compliance requirements (HIPAA, PCI DSS).
Private Endpoint Benefits:
Private Endpoint Implementation:
Farmer currently has limited support for private endpoints. Configure via Azure Portal or ARM templates:
// Example: Storage account with network restrictions
let storage = storageAccount {
name "securestorage"
sku Storage.Sku.Standard_LRS
// Disable public network access - force private endpoint usage
disable_public_network_access
// Configure private endpoint in Azure Portal:
// 1. Create private endpoint in your VNet
// 2. Select target sub-resource (blob, file, table, queue)
// 3. Configure private DNS integration
// 4. Approve private endpoint connection
}
Services Supporting Private Endpoints:
Private Endpoint Best Practices:
Reference: Azure Private Endpoint Documentation (https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview)
Azure Bastion provides secure RDP and SSH connectivity to Azure VMs without exposing RDP/SSH ports to the public internet. This eliminates a major attack vector for brute-force attacks and is essential for production environments.
Azure Bastion Architecture:
Azure Bastion is a fully managed PaaS service that acts as a jump server (bastion host) deployed inside your VNet. It provides secure connectivity over TLS from the Azure Portal directly to your VMs without needing public IP addresses on VMs.
Security Benefits:
Azure Bastion Deployment:
Farmer currently doesn’t support Azure Bastion builder. Deploy via Azure Portal or Azure CLI:
// Example: VNet with dedicated Bastion subnet
let vnet = vnet {
name "production-vnet"
add_address_spaces [
"10.0.0.0/16"
]
add_subnets [
subnet {
name "AzureBastionSubnet" // Required name
prefix "10.0.0.0/26" // Minimum /26 CIDR
// Reserve for Azure Bastion only
}
subnet {
name "web-tier"
prefix "10.0.1.0/24"
}
subnet {
name "data-tier"
prefix "10.0.2.0/24"
}
]
}
// Deploy Azure Bastion via Azure CLI:
// az network bastion create \
// --name MyBastion \
// --resource-group production-rg \
// --vnet-name production-vnet \
// --location eastus \
// --sku Standard
Azure Bastion SKUs:
| Feature | Basic SKU | Standard SKU |
|---|---|---|
| RDP/SSH via Azure Portal | ✓ | ✓ |
| Native RDP/SSH client support | ✗ | ✓ |
| File transfer | ✗ | ✓ |
| IP-based connection | ✗ | ✓ |
| Host scaling | ✗ | ✓ |
| Shareable links | ✗ | ✓ |
Azure Bastion Best Practices:
/26 subnet named AzureBastionSubnetReference: Azure Bastion Documentation (https://learn.microsoft.com/en-us/azure/bastion/)
Azure DDoS Protection defends against Distributed Denial of Service attacks that can make your applications unavailable. DDoS attacks can cost thousands of dollars per hour in lost revenue and resource scaling charges.
DDoS Attack Types:
Azure DDoS Protection Tiers:
Basic (Free):
Standard (Paid):
DDoS Protection Implementation:
// DDoS Protection Standard is configured at the subscription level
// Deploy via Azure CLI or Portal
// Example: VNet ready for DDoS Protection
let vnet = vnet {
name "protected-vnet"
add_address_spaces [ "10.0.0.0/16" ]
add_subnets [
subnet {
name "web-tier"
prefix "10.0.1.0/24"
}
]
}
// Create DDoS Protection Plan via CLI:
// az network ddos-protection create \
// --resource-group production-rg \
// --name production-ddos-plan \
// --location eastus
//
// Then associate it with VNet:
// az network vnet update \
// --resource-group production-rg \
// --name protected-vnet \
// --ddos-protection-plan production-ddos-plan \
// --ddos-protection true
DDoS Protection Standard Costs:
DDoS Protection Best Practices:
DDoS Attack Response:
Reference: Azure DDoS Protection (https://learn.microsoft.com/en-us/azure/ddos-protection/)
Protect web applications from OWASP Top 10 attacks using Azure WAF.
open Farmer.ApplicationGateway
let appGateway = appGateway {
name "secure-gateway"
// Enable WAF with OWASP rules
sku_capacity 2
sku ApplicationGatewaySku.WAF_v2
// Configure in Azure Portal:
// 1. Enable OWASP 3.2 rule set
// 2. Set to Prevention mode (not just Detection)
// 3. Enable bot protection
// 4. Configure custom rules for rate limiting
}
Azure WAF Protection Against OWASP Top 10:
Reference: Azure WAF on Application Gateway (https://docs.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview)
Implement defense-in-depth with NSG rules.
let webNsg = nsg {
name "web-tier-nsg"
add_rules [
securityRule {
name "AllowHTTPS"
description "Allow HTTPS from Internet"
services [ NetworkService ("https", 443) ]
add_source_tag TCP "Internet"
add_destination_any
direction Inbound
}
securityRule {
name "DenyAll"
description "Deny all other inbound"
services [ anyProtocol ]
add_source_any
add_destination_any
direction Inbound
priority 4096
access Deny
}
]
}
// Database tier - only allow from web tier
let dbNsg = nsg {
name "data-tier-nsg"
add_rules [
securityRule {
name "AllowSQL"
description "Allow SQL from web tier only"
services [ NetworkService ("mssql", 1433) ]
add_source_address TCP "10.0.1.0/24" // Web subnet
add_destination_address "10.0.2.0/24" // DB subnet
direction Inbound
}
]
}
NSG Best Practices:
Reference: Azure NSG Security Best Practices (https://docs.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)
Microsoft Defender for Cloud (formerly Azure Security Center) is a unified infrastructure security management system that provides advanced threat protection across hybrid cloud workloads. Defender for Cloud is essential for maintaining security posture and detecting threats in real-time.
Core Capabilities:
Defender CSPM (Cloud Security Posture Management):
Defender CSPM provides free and premium capabilities for security posture management:
Free Tier (Foundational CSPM):
Paid Tier (Defender CSPM Plan):
Enabling Defender CSPM:
# Enable Defender CSPM plan via Azure CLI
az security pricing create \
--name CloudPosture \
--tier Standard
# Enable foundational CSPM (free)
# Automatic when you access Defender for Cloud
Attack Path Analysis:
Attack paths show how attackers could potentially exploit your environment by chaining vulnerabilities. Example attack path:
Internet-exposed VM with vulnerabilities
→ Has managed identity
→ Identity has Contributor role
→ Can access sensitive storage account
→ Contains customer PII data
Cloud Security Graph:
The security graph analyzes relationships between resources to identify risks based on:
Defender for Cloud Workload Protection Plans:
| Plan | Protects | Key Features | Typical Cost |
|---|---|---|---|
| Defender for Servers | VMs, VMSS | Vulnerability assessment, JIT access, file integrity monitoring | ~$15/server/month |
| Defender for App Service | Web apps, Function apps | Runtime threat protection, dependency scanning | ~$15/plan/month |
| Defender for Storage | Blob, File, Data Lake | Malware scanning, anomaly detection, sensitive data discovery | ~$10/storage account/month |
| Defender for SQL | SQL Database, SQL MI | Vulnerability assessment, threat detection, sensitive data discovery | ~$15/server/month |
| Defender for Containers | AKS, ACR, Arc K8s | Image scanning, runtime protection, Kubernetes audit logs | ~$7/vCore/month |
| Defender for Key Vault | Key Vault | Anomaly detection, suspicious operations | ~$0.02/10K operations |
| Defender CSPM | All resources | Attack paths, security graph, compliance | ~$5/resource/month |
Microsoft Defender for Cloud Best Practices:
Secure Score Optimization:
Secure score is calculated based on healthy resources / total resources. Focus on high-impact recommendations first:
High-Impact Actions (10+ points each):
Medium-Impact Actions (5-9 points):
Security Governance:
Assign owners and due dates to security recommendations to track remediation progress:
# Assign recommendation owner via Azure CLI
az security task create \
--name "Enable MFA for all users" \
--recommendation-id <recommendation-id> \
--assigned-to security-team@company.com \
--due-date 2025-03-01
Integration with CI/CD:
Defender for DevOps integrates with GitHub Actions and Azure DevOps:
Reference: Microsoft Defender for Cloud Documentation (https://learn.microsoft.com/en-us/azure/defender-for-cloud/)
Enable comprehensive security monitoring across your Azure environment.
let insights = appInsights {
name "security-monitoring"
retention_days 90 // Compliance requirement
log_analytics_workspace_linking_mode Workspace
}
// Enable Microsoft Defender for Cloud
// Configure in Azure Portal:
// 1. Enable Defender CSPM and workload protection plans
// 2. Configure Security Center alerts via email
// 3. Enable Just-In-Time VM access
// 4. Configure adaptive application controls
// 5. Set up continuous export to Log Analytics
Security Monitoring Stack:
Critical Security Alerts to Configure:
Reference: Azure Security Center Best Practices (https://docs.microsoft.com/en-us/azure/defender-for-cloud/security-center-introduction)
Map your Azure security controls to compliance requirements:
OWASP Top 10 Compliance:
PCI DSS (Payment Card Industry):
HIPAA (Healthcare):
GDPR (Data Privacy):
SOC 2 (Service Organization Control):
Reference: Azure Compliance Offerings (https://docs.microsoft.com/en-us/azure/compliance/)
Identity and Access:
Data Protection:
Network Security:
Application Security:
Monitoring and Response:
Compliance:
Microsoft Official:
OWASP Resources:
Troy Hunt Resources:
Azure Security Community:
This guide reflects Azure security best practices as of 2025. Always refer to the latest Microsoft documentation and your organization’s compliance requirements when implementing security controls.