Chapter 7: Identity & Security

Security in Azure is built on the principle of Zero Trust: never trust, always verify. This chapter covers identity, access control, secrets, and threat protection.

Microsoft Entra ID (formerly Azure Active Directory)

Microsoft Entra ID is Azure's cloud-based identity and access management (IAM) service. Every Azure subscription is backed by an Entra ID tenant (your organisation's identity directory).

Core Concepts

Microsoft Entra ID Tenant (mycompany.onmicrosoft.com)
├── Users           - human identities (employees, external guests)
├── Groups          - collections of users for bulk permission assignment
├── Applications    - App registrations for OAuth/OIDC flows
├── Service Principals - non-human identities for apps/scripts
├── Managed Identities - automatic service principals for Azure resources
└── Devices         - registered/joined devices

Users & Groups

# Create a user
az ad user create \
  --display-name "Jane Smith" \
  --user-principal-name jane@mycompany.onmicrosoft.com \
  --password "TempP@ss123!" \
  --force-change-password-next-sign-in true

# Create a security group
az ad group create \
  --display-name "Developers" \
  --mail-nickname developers

# Add a user to a group
az ad group member add \
  --group Developers \
  --member-id $(az ad user show --id jane@mycompany.onmicrosoft.com --query id -o tsv)

# List group members
az ad group member list --group Developers --output table

App Registrations

Register an application to obtain credentials for OAuth 2.0 / OIDC authentication:

# Register an app
az ad app create \
  --display-name "MyApp API" \
  --sign-in-audience AzureADMyOrg

# Create a service principal for the app
az ad sp create --id <app-id>

# Create a client secret
az ad app credential reset \
  --id <app-id> \
  --append \
  --display-name "prod-secret" \
  --years 1

# The output includes appId (client_id) and password (client_secret)

Managed Identity

Managed Identities let Azure resources authenticate to other Azure services without storing credentials in code or configuration. Azure handles the credential lifecycle automatically.

TypeDescription
System-assignedTied to one resource; deleted when the resource is deleted
User-assignedCreated separately; can be assigned to multiple resources
# Enable system-assigned managed identity on a VM
az vm identity assign \
  --resource-group myapp-rg \
  --name mywebvm

# Create a user-assigned managed identity
az identity create \
  --resource-group myapp-rg \
  --name myapp-identity

# Assign user-assigned identity to an App Service
az webapp identity assign \
  --resource-group myapp-rg \
  --name myapp-api \
  --identities $(az identity show --resource-group myapp-rg --name myapp-identity --query id -o tsv)

Using Managed Identity in code (Python + Azure SDK):

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

# DefaultAzureCredential uses managed identity in Azure,
# developer credentials locally (az login / env vars)
credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://mykeyvault.vault.azure.net/", credential=credential)

secret = client.get_secret("db-connection-string")
print(secret.value)

Never hardcode connection strings or credentials in your application code. Use Managed Identity + Key Vault references instead.

Role-Based Access Control (RBAC)

Azure RBAC controls who can do what on which resources.

RBAC Model
├── Security Principal  - who  (user, group, service principal, managed identity)
├── Role Definition     - what (a set of allowed actions)
└── Scope               - which (management group / subscription / resource group / resource)

Built-in Roles

RoleDescription
OwnerFull access including the ability to delegate access to others
ContributorFull access to resources, but cannot manage access
ReaderView resources only
User Access AdministratorManage user access to Azure resources
Storage Blob Data ContributorRead, write, delete blobs
Storage Blob Data ReaderRead blobs only
Key Vault Secrets OfficerManage secrets (read, write, delete)
Key Vault Secrets UserRead secrets only
AKS Cluster AdminFull cluster access
# Grant a user the Contributor role on a resource group
az role assignment create \
  --assignee jane@mycompany.onmicrosoft.com \
  --role Contributor \
  --scope /subscriptions/<sub-id>/resourceGroups/myapp-rg

# Grant a managed identity access to a Key Vault
az role assignment create \
  --assignee $(az identity show --resource-group myapp-rg --name myapp-identity --query principalId -o tsv) \
  --role "Key Vault Secrets User" \
  --scope $(az keyvault show --name myapp-kv --resource-group myapp-rg --query id -o tsv)

# Grant storage access using data-plane role (required for managed identity)
az role assignment create \
  --assignee $(az identity show --resource-group myapp-rg --name myapp-identity --query principalId -o tsv) \
  --role "Storage Blob Data Contributor" \
  --scope $(az storage account show --name mystorageacct --resource-group myapp-rg --query id -o tsv)

# List role assignments on a resource group
az role assignment list \
  --resource-group myapp-rg \
  --output table

RBAC Best Practices

  1. Principle of Least Privilege: Grant the minimum permissions needed
  2. Prefer groups over individual assignments: Easier to manage at scale
  3. Use built-in roles before custom: Custom roles are harder to audit
  4. Avoid Owner on individuals: Use Contributor + User Access Administrator separately
  5. Scope as low as possible: Resource-level > resource group > subscription

Azure Key Vault

Key Vault is a centralised secrets store for credentials, certificates, and encryption keys. Never put secrets in environment variables, config files, or source control.

# Create a Key Vault
az keyvault create \
  --resource-group myapp-rg \
  --name myapp-kv \
  --location eastus \
  --sku standard \
  --enable-rbac-authorization true  # Use RBAC (modern approach)

# Store a secret
az keyvault secret set \
  --vault-name myapp-kv \
  --name db-connection-string \
  --value "Server=tcp:myapp-sql-server.database.windows.net..."

# Read a secret
az keyvault secret show \
  --vault-name myapp-kv \
  --name db-connection-string \
  --query value \
  --output tsv

# List secrets
az keyvault secret list --vault-name myapp-kv --output table

# Store a certificate
az keyvault certificate import \
  --vault-name myapp-kv \
  --name myapp-tls \
  --file ./myapp.pfx \
  --password "pfxpassword"

# Rotate (create new version of) a secret
az keyvault secret set \
  --vault-name myapp-kv \
  --name db-connection-string \
  --value "new-connection-string"
# Previous versions are kept and accessible

Key Vault References in App Service

Instead of copying secrets into App Service settings, reference them directly:

# App setting value format: @Microsoft.KeyVault(SecretUri=<uri>)
SECRET_URI=$(az keyvault secret show \
  --vault-name myapp-kv \
  --name db-connection-string \
  --query id -o tsv)

az webapp config appsettings set \
  --resource-group myapp-rg \
  --name myapp-api \
  --settings DATABASE_URL="@Microsoft.KeyVault(SecretUri=${SECRET_URI})"

App Service fetches the secret at startup. Update the secret in Key Vault, then restart the app.

Key Vault Access Policies vs RBAC

There are two access models:

  • Access Policies (legacy): vault-level permissions, coarse-grained
  • RBAC (recommended): standard Azure RBAC, fine-grained, auditable

Always create new vaults with --enable-rbac-authorization true.

Conditional Access

Conditional Access policies define conditions under which users can sign in:

  • Require MFA from outside the corporate network
  • Block access from high-risk locations or untrusted devices
  • Require compliant devices (Intune)

Configured in the Entra ID portal under Security > Conditional Access.

Microsoft Defender for Cloud

Defender for Cloud is a Cloud Security Posture Management (CSPM) and workload protection platform. It continuously assesses your Azure environment.

# Enable Defender for a subscription
az security pricing create \
  --name VirtualMachines \
  --tier standard

az security pricing create \
  --name SqlServers \
  --tier standard

# View security recommendations
az security assessment list \
  --output table

# View alerts
az security alert list \
  --output table

The Secure Score dashboard in the portal gives a 0–100 score and prioritised recommendations.

Microsoft Sentinel

Microsoft Sentinel is a cloud-native SIEM (Security Information and Event Management) and SOAR (Security Orchestration, Automation, and Response) solution. It collects logs from Azure, Microsoft 365, and third-party sources to detect and respond to threats.

Key features:

  • Automated threat detection using ML analytics rules
  • Hunting queries (KQL) for threat investigation
  • Playbooks (Logic Apps) to automate incident response
  • Integration with 300+ data connectors

Security Best Practices Summary

Defence in Depth: Layer Your Controls
┌─────────────────────────────────────────────────────────────┐
│  Physical Security     (Microsoft's data centres)           │
├─────────────────────────────────────────────────────────────┤
│  Identity              Entra ID, MFA, Conditional Access    │
├─────────────────────────────────────────────────────────────┤
│  Perimeter             DDoS Protection, Azure Firewall      │
├─────────────────────────────────────────────────────────────┤
│  Network               VNets, NSGs, Private Endpoints       │
├─────────────────────────────────────────────────────────────┤
│  Compute               Patching, JIT access, Defender       │
├─────────────────────────────────────────────────────────────┤
│  Application           App Gateway WAF, APIM, code scanning │
├─────────────────────────────────────────────────────────────┤
│  Data                  Key Vault, encryption at rest/transit│
└─────────────────────────────────────────────────────────────┘
  1. Enable MFA for all users, especially admins
  2. Use Managed Identity instead of service principal credentials wherever possible
  3. Store secrets in Key Vault, never in code or environment variables
  4. Apply least privilege RBAC at the resource group or resource level
  5. Enable Defender for Cloud and review the Secure Score weekly
  6. Enable diagnostic logs for all critical resources
  7. Use Private Endpoints for databases and Key Vault in production
  8. Lock down NSGs: deny all, then explicitly allow what you need

Next Steps

Continue to 08-serverless.md to learn about Azure Functions, Logic Apps, and event-driven architectures.