Skip to main content

Security & Compliance

What You’ll Learn

By the end of this chapter, you’ll understand:
  • Security fundamentals - Why security matters and what the real costs of breaches are
  • Defense in Depth - Why one security layer isn’t enough (like having multiple locks on your door)
  • Zero Trust - Why you should “never trust, always verify” (even internal requests)
  • Azure Security Center - How to get a security score and fix vulnerabilities automatically
  • Azure Sentinel (SIEM) - How to detect hackers trying to break into your system
  • Key Vault - Where to store passwords safely (never in your code!)
  • Real-world security patterns - How to actually secure a production web application

Introduction: What is Security? (Start Here if You’re New)

Why Security Matters (Real Numbers)

Security = Protecting your application, data, and users from unauthorized access Think of it like protecting your house:
  • Locks on doors = Authentication (only you have the key)
  • Alarm system = Monitoring (alerts when someone breaks in)
  • Safe for valuables = Encryption (protects important items even if thieves get in)
  • Security cameras = Logging (records what happened)

The Cost of Poor Security (True Stories)

Example 1: Equifax Data Breach (2017)
  • What happened: Hackers stole personal data of 147 million people
  • How: Unpatched vulnerability in web application (known for 2 months, not fixed)
  • Cost:
    • Settlement: $700 million
    • Stock price drop: -35% ($6 billion in market value)
    • CEO resigned
  • Prevention cost: ~$50,000 (security scanning tools + patch deployment)
  • ROI of security: 14,000x
Example 2: Capital One Breach (2019)
  • What happened: Hacker accessed 100 million credit card applications
  • How: Misconfigured firewall on AWS (allowed access from internet)
  • Cost:
    • Fine: $80 million
    • Legal fees: $270 million
    • Reputation damage: Immeasurable
  • Prevention cost: ~$10,000 (proper firewall configuration + security audit)
  • ROI of security: 35,000x
Example 3: SolarWinds Supply Chain Attack (2020)
  • What happened: Hackers inserted malware into software updates, compromising 18,000 organizations
  • Cost: Estimated $90-100 billion in economic damage
  • Lesson: Trust no one (Zero Trust principle)

What “Security” Actually Means

Security is NOT a single thing. It’s multiple layers working together: 1. Authentication (“Who are you?”)
  • Prove your identity
  • Username + Password
  • Multi-Factor Authentication (MFA) = Password + Phone code
2. Authorization (“What can you do?”)
  • Even if you’re authenticated, you can only access what you’re allowed
  • Example: You can read files, but not delete them
3. Encryption (“Scramble data so hackers can’t read it”)
  • Data at rest: Files stored on disk (encrypted hard drive)
  • Data in transit: Files moving across network (HTTPS)
  • Example: Even if hacker steals database backup, they can’t read encrypted passwords
4. Monitoring (“Watch for suspicious activity”)
  • Someone trying 1,000 passwords = Brute force attack
  • User logging in from Russia and USA within 5 minutes = Impossible travel
  • Alert security team immediately!
5. Compliance (“Follow the rules”)
  • GDPR (Europe): Protect user privacy or pay €20 million fine
  • HIPAA (USA): Protect health records or go to jail
  • PCI DSS: Protect credit card data or lose ability to accept payments

Defense in Depth (The Castle Analogy)

Why One Security Layer Isn’t Enough

Medieval Castle Defense:
Layer 1: Moat (prevents attackers from reaching walls)
   ↓ Attacker crosses moat
Layer 2: Outer walls (prevents entry to castle)
   ↓ Attacker scales walls
Layer 3: Inner walls (protects keep)
   ↓ Attacker breaches inner walls
Layer 4: Treasure in locked safe (final protection)
   ↓ Attacker can't open safe without key
Result: Treasure is safe! ✅
Cloud Application Defense (Same concept):
Layer 1: Physical Security (Azure data centers)
   ↓ Hacker can't physically access servers
Layer 2: Network Security (Firewalls, NSGs)
   ↓ Even if they try, firewall blocks unauthorized traffic
Layer 3: Identity & Access (MFA, RBAC)
   ↓ Even if they get past firewall, they need valid credentials + MFA
Layer 4: Application Security (Input validation, WAF)
   ↓ Even if they're authenticated, app blocks malicious requests (SQL injection)
Layer 5: Data Security (Encryption)
   ↓ Even if they access database, data is encrypted and unreadable
Result: Your data is safe! ✅
Real-World Example: Without Defense in Depth (Single firewall):
Hacker bypasses firewall → Gets full database access → Steals everything ❌
Time to compromise: 1 hour
Damage: $10 million
With Defense in Depth:
Hacker bypasses firewall
  ↓ (Layer 2: Network - Still need to get past NSG)
Hacker bypasses NSG
  ↓ (Layer 3: Identity - Still need valid credentials + MFA)
Hacker steals credentials (but doesn't have MFA code)
  ↓ (Layer 3: Identity - MFA blocks them)
Hacker gives up ✅
Time to compromise: Never
Damage: $0

Zero Trust Architecture (Never Trust, Always Verify)

The Old Way (Castle-and-Moat Security) - BROKEN

Traditional Thinking:
  • “If you’re inside the company network, you’re trusted”
  • “Firewall keeps bad guys OUT, everyone INSIDE is safe”
Why it failed:
Scenario: Employee laptop gets virus
  ↓ Laptop is "inside" the network (trusted)
  ↓ Virus spreads to entire company (everyone trusted it)
  ↓ Entire network compromised ❌
Real Example:
  • WannaCry ransomware (2017) infected one computer
  • Spread to 200,000 computers worldwide
  • Cost: $4 billion in damages
  • Why? Internal networks trusted each other blindly

The New Way (Zero Trust) - SECURE

Zero Trust Principles: 1. Verify Explicitly
  • NEVER trust anyone automatically
  • Always authenticate and authorize (even internal requests)
Example:
Before Zero Trust:
Frontend → Backend API (no authentication, "it's internal!")
Hacker compromises Frontend → Calls Backend API freely ❌

After Zero Trust:
Frontend → Backend API (requires authentication token)
Hacker compromises Frontend → Can't call Backend (no valid token) ✅
2. Use Least Privilege Access
  • Give users ONLY what they need (nothing more)
  • “Just-in-time” access (temporary permissions)
Example:
Before:
Database Admin has 24/7 access to production database
  ↓ Admin account gets hacked
  ↓ Hacker has 24/7 access to database ❌

After (Least Privilege):
Database Admin requests access when needed (8 AM - 5 PM only)
  ↓ Access automatically expires at 5 PM
  ↓ Even if account hacked at night, hacker has no access ✅
3. Assume Breach
  • Plan as if hackers are ALREADY inside your network
  • Minimize damage if compromised
Example:
Assume Breach Strategy:
- Segment network (database isolated from web servers)
- Encrypt everything (even internal traffic)
- Monitor everything (detect unusual activity)

Result:
Hacker compromises 1 web server
  ↓ Can't access database (different network segment)
  ↓ Can't read encrypted data
  ↓ Security team notified immediately (monitoring detected unusual behavior)
  ↓ Hacker isolated and blocked ✅

Understanding Azure Security Tools

1. Azure Security Center (Your Security Dashboard)

Think of Security Center as your car’s dashboard:
  • Check Engine Light = Security alerts
  • Speedometer = Security Score (0-100%)
  • Maintenance Required = Recommendations to fix
What it does:
Step 1: Scans all your Azure resources
  ↓ Finds: VM has no antivirus, SQL has no encryption, Storage allows public access

Step 2: Calculates Security Score
  ↓ Your score: 42/100 (Poor security!)

Step 3: Provides recommendations
  ↓ "Enable Azure Defender on VMs" (+12 points)
  ↓ "Enable encryption on SQL Database" (+8 points)
  ↓ "Disable public access on Storage" (+15 points)

Step 4: You fix issues
  ↓ New score: 77/100 (Much better!)
Cost:
  • Free tier: Basic security recommendations
  • Paid tier (Azure Defender): $15/server/month
    • Advanced threat protection
    • Just-in-time VM access
    • File integrity monitoring
    • Network traffic analysis
Real-World Example:
Without Security Center:
Company deploys 100 VMs, doesn't realize 20 have public internet access
  ↓ Hacker finds them in port scan
  ↓ Company breached ❌

With Security Center:
Security Center alerts: "20 VMs have public IP addresses exposed!"
  ↓ Admin fixes in 10 minutes
  ↓ No breach ✅

2. Azure Sentinel (Your Security Detective)

Azure Sentinel = Security Information and Event Management (SIEM) Think of Sentinel as a detective analyzing security camera footage: Without Sentinel (Manual investigation):
Security incident occurs
  ↓ Check firewall logs manually (10,000 lines)
  ↓ Check application logs manually (50,000 lines)
  ↓ Check authentication logs manually (20,000 lines)
  ↓ Correlate events manually (takes 8 hours)
  ↓ By then, hacker has stolen data ❌
With Sentinel (Automated detection):
Sentinel collects logs from everywhere (firewall, apps, Azure AD)
  ↓ AI/ML analyzes patterns automatically
  ↓ Detects: "User logged in from Russia, then USA 5 minutes later" (impossible!)
  ↓ Alert sent in 30 seconds
  ↓ Automated playbook: Disable user account, notify security team
  ↓ Breach prevented ✅
How Sentinel Works: Step 1: Collect logs (Data connectors)
  • Azure Activity Logs
  • Office 365 (email, SharePoint)
  • Firewall logs
  • Application logs
  • Third-party tools (AWS, Google Cloud, on-premises firewalls)
Step 2: Detect threats (Analytics rules)
  • Pre-built rules (Microsoft provides 200+ threat detection rules)
    • Brute force attacks (failed login attempts)
    • Crypto mining (unusual CPU usage + connections to mining pools)
    • Data exfiltration (large file uploads to external storage)
  • Custom rules (you write your own KQL queries)
Step 3: Investigate (Visual timelines)
  • See exactly what happened
  • Example: User A logged in → Accessed database → Downloaded 10 GB → Uploaded to external site
Step 4: Respond (Automated playbooks)
  • Automatic actions:
    • Block IP address
    • Disable user account
    • Isolate VM from network
    • Send email/Slack notification to security team
Cost:
  • First 10 GB/day: FREE
  • After 10 GB: $2.76/GB/day
  • Typical small company: ~$200-500/month
  • Typical large company: ~$5,000-20,000/month
ROI: Average company saves $2.5 million per year by detecting breaches early (IBM Security Report 2023)

3. Azure Key Vault (Your Digital Safe)

Key Vault = Secure storage for secrets The Problem (Storing secrets in code): BAD CODE (Never do this!):
// appsettings.json - VISIBLE IN SOURCE CONTROL!
{
  "DatabasePassword": "SuperSecret123!",
  "ApiKey": "abc123xyz789",
  "StripeSecretKey": "sk_live_51H..."
}

Risk:
Developer commits to GitHub
GitHub repo is public (or gets hacked)
  ↓ Hacker finds credentials in 30 seconds (automated bots scan GitHub 24/7)
  ↓ Hacker accesses production database ❌
Real Example:
  • Uber breach (2016): API keys hardcoded in GitHub
  • Cost: $148 million fine
The Solution (Key Vault): GOOD CODE:
// appsettings.json - NO SECRETS!
{
  "KeyVaultUrl": "https://myvault.vault.azure.net/"
}

// Application code
var client = new SecretClient(
    new Uri(Configuration["KeyVaultUrl"]),
    new DefaultAzureCredential() // Uses Managed Identity (no passwords!)
);

string password = await client.GetSecretAsync("DatabasePassword");
How it works:
Step 1: Store secret in Key Vault (one time)
  ↓ az keyvault secret set --vault-name myvault --name DatabasePassword --value "SuperSecret123!"

Step 2: Application requests secret (at runtime)
  ↓ Application authenticates using Managed Identity (automatic, no credentials in code)
  ↓ Key Vault checks: "Does this app have permission to read DatabasePassword?"
  ↓ If yes → Returns secret value
  ↓ If no → Denies access

Step 3: Secret value used in memory (never written to disk)
  ↓ Even if hacker reads source code → No secrets found ✅
Key Vault Benefits:
  1. Centralized secret management
    • One place to store all secrets (not scattered across 50 config files)
    • Update secret once → All apps use new value immediately
  2. Automatic secret rotation
    • Secrets expire every 90 days
    • Key Vault rotates automatically
    • Example: Database password changes automatically, apps don’t notice
  3. Audit logging
    • Who accessed which secret? When?
    • Example: “User X accessed StripeSecretKey at 3 AM on Sunday” → Suspicious!
Cost:
  • Standard tier: 0.03per10,000operations( 0.03 per 10,000 operations (~5-10/month for typical app)
  • Premium tier: $1/month per key (hardware security module - HSM)

Azure Defense in Depth

1. Defense in Depth

[!TIP] Jargon Alert: Zero Trust The security philosophy of “Never trust, always verify.” Just because a request came from “inside the building” (or VNet) doesn’t mean it’s safe. Every request requires authentication and authorization.
[!WARNING] Gotcha: Just-In-Time (JIT) VM Access JIT is great for security (closing ports when not in use), but it takes 1-2 minutes to request access and open the port. Do not use this for automated scripts that expect instant connections.

2. Azure Security Center

Security Center provides unified security management and threat protection.

Security Posture

Secure Score

Measure security posture (0-100%)
  • Recommendations with impact
  • Track improvements over time

Regulatory Compliance

Track compliance with standards:
  • PCI DSS
  • ISO 27001
  • HIPAA
  • SOC 2

Key Features

# Enable Security Center Standard
az security pricing create \
  --name VirtualMachines \
  --tier Standard

# Get security recommendations
az security assessment list

# Enable auto-provisioning (Log Analytics agent)
az security auto-provisioning-setting update \
  --name default \
  --auto-provision On

3. Azure Sentinel (SIEM)

Sentinel is Azure’s cloud-native SIEM for intelligent security analytics.

Data Sources

  • Azure Activity Logs
  • Office 365 Logs
  • Firewall Logs
  • Threat Intelligence
  • Custom Logs

Example Hunting Query

// Detect potential brute force attacks
SigninLogs
| where TimeGenerated > ago(1h)
| where ResultType != 0  // Failed sign-ins
| summarize
    FailedAttempts=count(),
    Locations=make_set(Location)
    by UserPrincipalName, IPAddress
| where FailedAttempts > 5
| project UserPrincipalName, IPAddress, FailedAttempts, Locations

4. Key Vault

Key Vault manages secrets, keys, and certificates securely.
# Create Key Vault
az keyvault create \
  --name myvault \
  --resource-group rg-prod \
  --enable-soft-delete true \
  --enable-purge-protection true

# Add secret
az keyvault secret set \
  --vault-name myvault \
  --name DatabasePassword \
  --value "SuperSecretPassword123!"

# Access from application (using Managed Identity)
SecretClient client = new SecretClient(
    new Uri("https://myvault.vault.azure.net"),
    new DefaultAzureCredential()
);

KeyVaultSecret secret = await client.GetSecretAsync("DatabasePassword");
string password = secret.Value;

5. Azure Policy

Azure Policy enforces organizational standards and compliance.

Example Policies

{
  "displayName": "Require tag on resources",
  "policyRule": {
    "if": {
      "field": "tags['Environment']",
      "exists": "false"
    },
    "then": {
      "effect": "deny"
    }
  }
}
# Assign built-in policy
az policy assignment create \
  --name require-tags \
  --scope /subscriptions/{subscription-id} \
  --policy /providers/Microsoft.Authorization/policyDefinitions/...

# Common policies:
# - Allowed VM sizes
# - Require encryption
# - Enforce naming conventions
# - Geographic restrictions

6. Security Best Practices

Zero Trust

Never trust, always verify. Verify explicitly, least privilege, assume breach.

Encryption Everywhere

Data at rest, in transit, and in use. Customer-managed keys for sensitive data.

Network Isolation

Private endpoints, NSGs, Azure Firewall. No public IPs on backends.

Identity is Perimeter

MFA, Conditional Access, PIM. Azure AD for all authentication.

Monitor Everything

All logs to Log Analytics. Alerts on suspicious activity.

Incident Response

Have a plan, test regularly, document lessons learned.

7. Advanced Security Patterns

Web Application Firewall (WAF) Configuration

Azure WAF protects against OWASP Top 10 vulnerabilities. Available on Azure Front Door and Application Gateway.

WAF Policy with Custom Rules

# Create WAF policy
az network front-door waf-policy create \
  --name MyWAFPolicy \
  --resource-group rg-prod \
  --mode Prevention \
  --sku Premium_AzureFrontDoor

# Enable OWASP ruleset
az network front-door waf-policy managed-rules add \
  --policy-name MyWAFPolicy \
  --resource-group rg-prod \
  --type Microsoft_DefaultRuleSet \
  --version 2.1

# Enable Bot Manager rules
az network front-door waf-policy managed-rules add \
  --policy-name MyWAFPolicy \
  --resource-group rg-prod \
  --type Microsoft_BotManagerRuleSet \
  --version 1.0

Custom Rule: Block Traffic from Specific Countries

{
  "name": "BlockBadCountries",
  "priority": 1,
  "ruleType": "MatchRule",
  "matchConditions": [
    {
      "matchVariable": "RemoteAddr",
      "operator": "GeoMatch",
      "matchValue": ["CN", "RU", "KP"]
    }
  ],
  "action": "Block"
}

Custom Rule: Rate Limiting

{
  "name": "RateLimitPerIP",
  "priority": 10,
  "ruleType": "RateLimitRule",
  "rateLimitThreshold": 100,
  "rateLimitDurationInMinutes": 1,
  "matchConditions": [
    {
      "matchVariable": "RemoteAddr",
      "operator": "IPMatch",
      "matchValue": ["0.0.0.0/0"]
    }
  ],
  "action": "Block"
}
[!WARNING] Gotcha: WAF False Positives OWASP rules might block legitimate requests (e.g., SQL keywords in user input). Always test in Detection Mode first, review logs, then switch to Prevention Mode. Create exclusions for known false positives.
Real-World Example: An API endpoint /search?query=SELECT * FROM products gets blocked by WAF because “SELECT” triggers SQL injection detection. Solution: Add exclusion for that specific query parameter.

DDoS Protection Strategies

Azure DDoS Protection Standard

# Create DDoS protection plan
az network ddos-protection create \
  --resource-group rg-prod \
  --name MyDDoSPlan

# Enable on VNet
az network vnet update \
  --resource-group rg-prod \
  --name myVNet \
  --ddos-protection true \
  --ddos-protection-plan MyDDoSPlan
DDoS Protection Tiers:
FeatureBasic (Free)Standard ($2,944/month)
Always-On Monitoring
L3/L4 Attack Mitigation
Adaptive Tuning✅ (Per workload)
Application Layer Protection✅ (with WAF)
Cost Protection✅ (Azure credits)
Real-time Metrics
DDoS Rapid Response Support

Monitoring DDoS Attacks

// Azure Monitor query for DDoS metrics
AzureMetrics
| where ResourceProvider == "MICROSOFT.NETWORK"
| where MetricName in ("DDoSAttack", "VipAvailability")
| where TimeGenerated > ago(24h)
| summarize
    MaxAttack = max(Maximum),
    AvgAvailability = avg(Average)
    by Resource, MetricName
| project
    Resource,
    MaxAttackIntensity = MaxAttack,
    AvailabilityPercent = AvgAvailability
[!TIP] Best Practice: Multi-Layer DDoS Defense Combine Azure DDoS Protection (L3/L4) with Azure Front Door WAF (L7) for comprehensive protection. DDoS handles volumetric attacks; WAF handles application-layer attacks.

Zero Trust Implementation

Zero Trust Principles:
  1. Verify Explicitly - Always authenticate and authorize
  2. Use Least Privilege - Just-in-time and just-enough-access
  3. Assume Breach - Minimize blast radius and verify end-to-end encryption

Conditional Access Policies

# Enable Conditional Access requiring MFA for admins
az rest --method POST \
  --uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" \
  --body '{
    "displayName": "Require MFA for Admins",
    "state": "enabled",
    "conditions": {
      "users": {
        "includeRoles": ["62e90394-69f5-4237-9190-012177145e10"]
      },
      "applications": {
        "includeApplications": ["All"]
      }
    },
    "grantControls": {
      "operator": "AND",
      "builtInControls": ["mfa"]
    }
  }'

Risk-Based Access with Identity Protection

{
  "displayName": "Block High-Risk Sign-Ins",
  "conditions": {
    "signInRiskLevels": ["high"],
    "userRiskLevels": ["none", "low", "medium"]
  },
  "grantControls": {
    "operator": "OR",
    "builtInControls": ["block"]
  }
}
Impossible Travel Detection:
// Sentinel query: Detect user signing in from 2 countries within 1 hour
SigninLogs
| where TimeGenerated > ago(1h)
| where ResultType == 0  // Successful sign-ins
| summarize
    Locations = make_set(Location),
    Count = count()
    by UserPrincipalName, bin(TimeGenerated, 1h)
| where Count > 1 and array_length(Locations) > 1
| extend
    Distance = geo_distance_2points(
        toreal(Locations[0].latitude), toreal(Locations[0].longitude),
        toreal(Locations[1].latitude), toreal(Locations[1].longitude)
    )
| where Distance > 1000000  // 1000 km

Privileged Identity Management (PIM)

Problem: Admins have permanent elevated access. If their account is compromised, attacker has full control. Solution: Just-in-time (JIT) access. Admins activate privileges only when needed, with approval workflow.

Enable PIM for Azure Resources

# Assign eligible role (not active)
az role assignment create \
  --assignee [email protected] \
  --role "Virtual Machine Contributor" \
  --scope /subscriptions/{subscription-id} \
  --assignee-object-id {user-object-id} \
  --assignee-principal-type User \
  --description "JIT access for VM maintenance"

Activation Workflow

{
  "roleDefinitionId": "/subscriptions/.../providers/Microsoft.Authorization/roleDefinitions/...",
  "principalId": "user-object-id",
  "requestType": "SelfActivate",
  "scheduleInfo": {
    "startDateTime": "2026-01-21T10:00:00Z",
    "expiration": {
      "type": "AfterDuration",
      "duration": "PT8H"
    }
  },
  "justification": "Need to troubleshoot production VM issue #12345"
}
Access Review:
# Create recurring access review (quarterly)
az ad pim access-review create \
  --name "Review Global Admins" \
  --start-date "2026-01-21" \
  --interval 3 \
  --reviewers "[email protected]"
[!WARNING] Gotcha: Emergency Access Account Always have a “break glass” account (excluded from MFA and Conditional Access) for emergencies. Store credentials in physical safe. Use Azure Monitor alerts if this account is ever used.

Threat Detection with Sentinel

Advanced Threat Detection Rules

Detect Crypto Mining:
// High CPU + Outbound connections to known mining pools
Perf
| where TimeGenerated > ago(1h)
| where ObjectName == "Processor" and CounterName == "% Processor Time"
| where CounterValue > 80
| join kind=inner (
    CommonSecurityLog
    | where TimeGenerated > ago(1h)
    | where DestinationIP in ("45.76.13.12", "pool.minexmr.com", "xmr.pool.minergate.com")
) on Computer
| project Computer, CounterValue, DestinationIP, Activity
Detect Credential Dumping (Mimikatz):
SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == 4688  // Process creation
| where Process has_any ("mimikatz", "procdump", "gsecdump")
    or CommandLine has_any ("sekurlsa::logonpasswords", "lsass.exe")
| project TimeGenerated, Computer, Account, Process, CommandLine
Detect Data Exfiltration:
// Unusual volume of data uploaded to external storage
AzureActivity
| where TimeGenerated > ago(1h)
| where OperationNameValue == "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
| summarize
    TotalSizeMB = sum(todouble(Properties.contentLength)) / 1024 / 1024,
    FileCount = count()
    by Caller, CallerIpAddress
| where TotalSizeMB > 1000  // More than 1GB

Automated Response Playbooks

{
  "definition": {
    "triggers": {
      "When_Azure_Sentinel_incident_creation_rule_was_triggered": {
        "type": "MicrosoftSentinelIncident"
      }
    },
    "actions": {
      "Check_if_severity_is_high": {
        "type": "If",
        "expression": "@equals(triggerBody()?['Severity'], 'High')",
        "actions": {
          "Disable_user_account": {
            "type": "ApiConnection",
            "inputs": {
              "host": {
                "connection": {
                  "name": "@parameters('$connections')['azuread']['connectionId']"
                }
              },
              "method": "post",
              "path": "/v1.0/users/@{triggerBody()?['CompromisedEntity']}/accountEnabled",
              "body": { "accountEnabled": false }
            }
          },
          "Send_email_to_SOC": {
            "type": "ApiConnection",
            "inputs": {
              "host": { "connection": { "name": "@parameters('$connections')['office365']" } },
              "method": "post",
              "path": "/v2/Mail",
              "body": {
                "To": "[email protected]",
                "Subject": "High Severity Incident: @{triggerBody()?['Title']}",
                "Body": "Account @{triggerBody()?['CompromisedEntity']} has been disabled."
              }
            }
          }
        }
      }
    }
  }
}

Network Security Deep Dive

Problem: Azure SQL, Storage, etc. have public endpoints. Even with firewall rules, they’re exposed to the internet. Solution: Private Endpoint maps PaaS services to a private IP in your VNet.
# Create private endpoint for Azure SQL
az network private-endpoint create \
  --resource-group rg-prod \
  --name pe-sql \
  --vnet-name myVNet \
  --subnet data-subnet \
  --private-connection-resource-id /subscriptions/.../sqlservers/myserver \
  --group-id sqlServer \
  --connection-name sql-connection

# Create Private DNS Zone
az network private-dns zone create \
  --resource-group rg-prod \
  --name privatelink.database.windows.net

# Link DNS zone to VNet
az network private-dns link vnet create \
  --resource-group rg-prod \
  --zone-name privatelink.database.windows.net \
  --name sql-dns-link \
  --virtual-network myVNet \
  --registration-enabled false
Result: myserver.database.windows.net now resolves to 10.0.2.5 (private IP) instead of public IP.

Azure Firewall Configuration

# Create Azure Firewall
az network firewall create \
  --name MyFirewall \
  --resource-group rg-prod \
  --location eastus \
  --sku AZFW_VNet \
  --tier Premium

# Application rule: Allow HTTPS to specific domains
az network firewall application-rule create \
  --firewall-name MyFirewall \
  --resource-group rg-prod \
  --collection-name allow-microsoft \
  --name allow-microsoft-sites \
  --protocols Https=443 \
  --source-addresses 10.0.0.0/16 \
  --target-fqdns "*.microsoft.com" "*.azure.com"

# Network rule: Block all except DNS and NTP
az network firewall network-rule create \
  --firewall-name MyFirewall \
  --collection-name allow-dns-ntp \
  --name allow-infrastructure \
  --protocols UDP \
  --source-addresses 10.0.0.0/16 \
  --destination-addresses "*" \
  --destination-ports 53 123

User Defined Routes (Force Tunneling)

# Create route table
az network route-table create \
  --resource-group rg-prod \
  --name rt-firewall

# Add route: All internet traffic → Firewall
az network route-table route create \
  --resource-group rg-prod \
  --route-table-name rt-firewall \
  --name default-route \
  --address-prefix 0.0.0.0/0 \
  --next-hop-type VirtualAppliance \
  --next-hop-ip-address 10.0.1.4  # Firewall private IP

# Associate with subnet
az network vnet subnet update \
  --resource-group rg-prod \
  --vnet-name myVNet \
  --name app-subnet \
  --route-table rt-firewall

Security Monitoring & Alerts

Critical Security Alerts

// Alert: Admin role assigned outside business hours
AuditLogs
| where TimeGenerated > ago(1h)
| where OperationName == "Add member to role"
| where Result == "success"
| extend Role = tostring(TargetResources[0].displayName)
| where Role in ("Global Administrator", "Security Administrator")
| extend Hour = hourofday(TimeGenerated)
| where Hour < 6 or Hour > 22  // Outside 6 AM - 10 PM
| project TimeGenerated, Caller = Identity, Role, TargetUser = TargetResources[0].userPrincipalName
// Alert: Large number of resources deleted
AzureActivity
| where TimeGenerated > ago(1h)
| where OperationNameValue endswith "/delete"
| summarize DeleteCount = count() by Caller, CallerIpAddress
| where DeleteCount > 10

Security Checklist for Production

Before going live, ensure:
  • Identity: MFA enabled for all admin accounts
  • Identity: Conditional Access policies active (block legacy auth, require compliant devices)
  • Identity: PIM enabled for privileged roles (no standing access)
  • Network: No public IPs on backend VMs
  • Network: Private Endpoints for all PaaS services (SQL, Storage, Key Vault)
  • Network: Azure Firewall or NVA with forced tunneling
  • Network: NSGs on all subnets (deny all by default)
  • Application: WAF enabled on Front Door/App Gateway (Prevention mode)
  • Application: DDoS Protection Standard (for critical apps)
  • Application: All secrets in Key Vault (no config files)
  • Data: TDE enabled on databases
  • Data: Customer-Managed Keys (CMK) for sensitive data
  • Monitoring: All logs flowing to Log Analytics
  • Monitoring: Sentinel enabled with threat detection rules
  • Monitoring: Alerts for suspicious activity (failed sign-ins, admin actions, data exfiltration)
  • Compliance: Azure Policy enforcing standards (tagging, allowed regions, encryption)
  • Incident Response: Runbook documented and tested

8. Interview Questions

Beginner Level

Answer:
  • RBAC: Controls WHO can do what (User Alice can create VMs). Focus: User Actions.
  • Azure Policy: Controls WHAT can be created (VMs must be in East US). Focus: Resource Properties.
RBAC allows access; Policy limits what that access can generate.
Answer: To securely store and manage:
  1. Secrets (Passwords, Connection strings)
  2. Keys (Encryption keys)
  3. Certificates (SSL/TLS certs)
It decouples security material from application code.

Intermediate Level

Answer: A security strategy using multiple layers of defense, so if one fails, others provide protection. Layers: Physical -> Identity -> Networking -> Compute -> Application -> Data. Example: Even if a hacker gets past the Firewall (Network), they still need MFA (Identity) and Database encryption (Data).
Answer: Sentinel is a Cloud-Native SIEM (Security Information and Event Management) + SOAR (Security Orchestration, Automation, and Response).
  1. Collect: Ingests logs from everywhere (Azure, AWS, On-prem firewall).
  2. Detect: Uses AI/ML rules to find threat patterns (e.g., Impossible Travel).
  3. Investigate: Visualizes the attack timeline.
  4. Respond: Triggers automated playbooks (e.g., block IP, disable user).

Advanced Level

Answer:
  1. Front Door/WAF: Filter malicious traffic (SQLi, XSS) at the edge.
  2. DDoS Protection: Enable standard protection if critical.
  3. Network: Use VNet injection, deny all inbound except from WAF.
  4. Identity: Use Managed Identity for backend resources.
  5. Data: Encrypt SQL with TDE and CMK (Customer Managed Keys).
  6. Secrets: Store all secrets in Key Vault.
  7. Monitoring: Enable App Insights and Sentinel.

8. Key Takeaways

Zero Trust

Assume breach. Verify every request explicitly. Use least privilege access.

Azure Policy

Use Policy to enforce compliance (e.g., Tagging, Regions) and prevent configuration drift.

Centralized Security

Use Azure Security Center (Defender for Cloud) and Sentinel for a unified view of security posture.

Key Vault

Never store credentials in config files or code. Centralize them in Key Vault.

Defense in Depth

Layer security controls. Don’t rely on a single perimeter firewall.

Next Steps

Continue to Chapter 11

Master Azure DevOps, CI/CD pipelines, and Infrastructure as Code