Azure & Entra ID Hardening
Cloud Fast, Cloud Tight
Cloud environments change rapidly. That's why security here must be standard and automated.
For Azure & Entra ID Hardening, automation is leading: guardrails in code, least privilege, and continuous drift control.
This way you maintain speed in the cloud, without security depending on manual luck.
Immediate measures (15 minutes)
Why this matters
The core of Azure & Entra ID Hardening is risk reduction in practice. Technical context supports the choice of measures, but implementation and assurance are central.
Defense measures
Conditional Access
Conditional Access is the most important defense layer in Entra ID. A well-configured Conditional Access policy makes many of the attacks in this chapter impossible or significantly harder.
Essential policies:
| Policy | Description | Which attack it mitigates |
|---|---|---|
| MFA for all users | Requires MFA for every authentication | Password spraying |
| Block legacy auth | Block IMAP, POP3, SMTP AUTH, etc. | MFA bypass via legacy protocols |
| Block device code flow | Block the device authorization flow | Device code phishing |
| Require compliant device | Only managed devices | Token theft from unmanaged devices |
| Block risky sign-ins | Block on "high" risk score | Various |
| Named locations | Restrict to trusted IP ranges | Brute force from unknown locations |
| Require app protection | Require Intune-managed apps | Data exfiltration via unmanaged apps |
# Audit: retrieve all Conditional Access policies
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" | \
python3 -c "
import sys,json
policies = json.load(sys.stdin).get('value',[])
for p in policies:
state = p.get('state','unknown')
name = p.get('displayName','')
print(f'[{state.upper():8}] {name}')
"Privileged Identity Management (PIM)
PIM implements just-in-time privileged access: roles are not permanently assigned, but must be activated when needed. Activation requires a justification and can require MFA and approval.
PIM reduces the attack surface by: - Fewer permanently active Global Admins - Time-bound role activation (max 8 hours default) - Audit trail of role activation - MFA requirement on activation (even if the session already has MFA)
Workload Identity Federation
Workload Identity Federation is the successor to client secrets for app registrations. Instead of a secret that can be stolen, it uses a federated trust relationship with an external identity provider. No secret, no risk of secret leakage.
# Check if there are still apps with client secrets (that should be migrated)
az ad app list --query "[?passwordCredentials[0]!=null].{App:displayName,Created:passwordCredentials[0].startDateTime,Expires:passwordCredentials[0].endDateTime}" -o tableAdditional Recommendations
| Measure | Description |
|---|---|
| Disable user consent | Prevent illicit consent grant attacks |
| Enable audit logging | Azure AD sign-in logs + audit logs to SIEM |
| Rotate storage keys | Automatic rotation via Key Vault |
| Disable public blob access | Enforce at subscription level |
| Monitor Managed Identity usage | Anomaly detection on token requests |
| Azure AD Connect hardening | Dedicated server, restricted admin access |
| PRT protection | Token protection (Windows 11+) |
Reference table
| Subject | Technique | Tool | MITRE ATT&CK | Difficulty |
|---|---|---|---|---|
| Tenant enumeration | Unauthenticated recon | curl, browser | T1589 (Gather Victim Identity Information) | Low |
| Directory enumeration | Authenticated user enum | az cli, ROADtools, Graph API | T1087.004 (Cloud Account Discovery) | Low |
| Password spraying | Credential Access | MSOLSpray | T1110.003 (Password Spraying) | Low |
| MFA bypass (legacy auth) | Legacy protocol abuse | curl, Thunderbird | T1078.004 (Cloud Accounts) | Medium |
| Device code phishing | OAuth device flow abuse | Python, TokenTactics | T1528 (Steal Application Access Token) | Medium |
| Consent grant attack | Illicit OAuth consent | Custom app registration | T1528 (Steal Application Access Token) | Medium |
| Conditional Access bypass | Policy gap exploitation | roadrecon, Graph API | T1078.004 (Cloud Accounts) | High |
| RBAC escalation | Role assignment abuse | az cli | T1098.003 (Additional Cloud Roles) | Medium |
| Custom role abuse | Overprivileged custom roles | az cli | T1098.003 (Additional Cloud Roles) | Medium |
| Managed Identity token theft | IMDS token extraction | curl | T1552.005 (Cloud Instance Metadata API) | Medium |
| Key Vault secrets | Secret/key/cert extraction | az cli | T1552.001 (Credentials in Files) | Medium |
| Storage account abuse | SAS token / shared key | az cli, curl | T1530 (Data from Cloud Storage) | Low-Medium |
| Azure AD Connect (PHS) | Sync credential extraction | AADInternals | T1003.006 (DCSync) | High |
| Azure AD Connect (PTA) | Authentication interception | AADInternals | T1557 (Adversary-in-the-Middle) | High |
| Golden SAML | ADFS cert theft + token forge | ADFSDump, AADInternals | T1606.002 (SAML Tokens) | High |
| Automation runbook abuse | Credential dump via runbook | az cli | T1078.004 (Cloud Accounts) | Medium |
| Hybrid Worker exploitation | On-prem code execution | az cli | T1059 (Command and Scripting Interpreter) | High |
| Global Admin escalation | elevateAccess API | az rest | T1098.003 (Additional Cloud Roles) | Low (if you're GA) |
In the next chapter, we leave the Azure world and enter Google's territory -- a place where everything revolves around projects, service accounts, and the inexhaustible trust that Google has in its own infrastructure. Spoiler: that trust is not always justified.
Further reading in the knowledge base
These articles in the portal provide more background and practical context:
- The cloud — someone else's computer, your responsibility
- Containers and Docker — what it is and why you need to secure it
- Encryption — the art of making things unreadable
- Least Privilege — give people only what they need
You need an account to access the knowledge base. Log in or register.
Related security measures
These articles provide additional context and depth: