Company: Acme Corporation
Acme Corp is a mid-sized SaaS company with 500+ employees and Azure infrastructure managing critical customer data. Last month, their annual security audit revealed serious identity and access control gaps:
Audit Findings:
Your Role: Identity Security Engineer
Mission: Implement all 8 best practices to remediate these findings and pass a follow-up audit.
Success Criteria: Complete all parts, implement all best practices, document findings.
Required Knowledge:
Required Permissions:
Total: 250 minutes (~4+ hours)
Difficulty: Advanced
Acme Corp has a "just give them Owner role" culture. Your first task: identify over-privileged users and reduce their access to minimum required.
Step 1: Audit Current Role Assignments
- Owner roles (should be <5 people)
- Contributor roles (should be business-justified)
- Reader roles (should be majority)
Example Documentation Format:
Current State Analysis:├─ Owner (10 users - reduce to 3)
│ ├─ Alice Smith (CTO) - KEEP
│ ├─ Bob Johnson (DevOps Lead) - REDUCE to Contributor
│ └─ Charlie Lee (Developer) - REDUCE to specific contributor role
├─ Contributor (35 users - acceptable)
├─ Reader (80 users - acceptable)
└─ Custom Roles (0 - NEED TO CREATE)
Step 2: Identify Principle of Least Privilege Violations
Create a table with each user and recommended action:
| User | Current Role | Job Function | Recommended Role | Justification |
| ------ | ------------- | -------------- | ------------------ | --------------- |
|---|
| Charlie Lee | Owner | Debug issues | Reader + VM Contributor (staging only) | Should not have production access |
Step 3: Create Custom Roles (If Needed)
For users needing specific permissions that don't fit built-in roles:
- Permissions: Read blobs, Upload blobs, Delete own blobs
- Exclude: Delete storage account, Change access policies
Storage Blob Operator - DevelopmentStep 4: Remove Over-Privileged Access
For each user identified in Step 1:
Example actions:
Alice Smith: Owner (KEEP) - CEO needs full accessBob Johnson: Owner → Contributor (reduce from Owner, keep deployment capability)
Charlie Lee: Owner → Container Registry Acrpush role (only push images)
Diana Park: Contributor → Reader + Virtual Machine Contributor (read-only, can only manage VMs)
✅ Complete: Privilege surface reduced by minimum 40%
✅ All Owner roles are business-justified
✅ Custom roles created for specific job functions
✅ Access changes documented with justification
Acme has 23 inactive employee accounts with active access. Find and clean up orphaned accounts and permission creep.
Step 1: Identify Inactive Accounts
- Last sign-in date > 90 days ago (or never signed in)
- Still assigned to groups/roles
- Status: Active (should be Disabled if not needed)
- Name
- Department
- Last sign-in date
- Current groups
- Current role assignments
Example Inactive Accounts Found:
Michael Brown├─ Department: Engineering (transferred to DevOps)
├─ Last Sign-in: 180 days ago
├─ Groups: grp-engineers-deploy, grp-production-access
├─ Roles: Contributor (test subscription)
└─ Status: INACTIVE - should be disabled
Sarah Davis
├─ Department: Marketing (left company 6 months ago)
├─ Last Sign-in: 200 days ago
├─ Groups: grp-all-users, grp-marketing
├─ Roles: Reader (production)
└─ Status: ORPHANED - should be deleted
Step 2: Conduct Quarterly Access Review
For each user with access, ask:
Access Review Questionnaire:
- Is this user still employed? → If NO, disable/delete
- Are they in the correct role for their current job? → If NO, update
- When was their access last used? → If >90 days, question necessity
- Do they still need each group membership? → If NO, remove
- Any suspicious activity on this account? → If YES, investigate
Step 3: Remediate Findings
For each finding:
If User is Inactive (>90 days, employed):
If User Has Left Company:
If Permission Creep (user has many roles they don't need):
Step 4: Document Access Review
Create a summary:
Q2 2024 Access Review Summary────────────────────────────
Actions Taken:
├─ 6 inactive users: Removed from groups and roles
├─ 4 departed employees: Accounts deleted
├─ 12 users: Updated roles to match current job
├─ 8 users: Removed from unnecessary groups
Permission Creep Eliminated:
├─ 23 unnecessary role assignments removed
├─ 15 obsolete group memberships cleaned
Next Steps:
└─ Schedule Q3 review for [date]
✅ Complete: Removed access for all orphaned accounts
✅ Cleaned up minimum 20 unnecessary role assignments
✅ Documented quarterly review process
✅ Established future review schedule
Zero MFA protection on 12 administrative accounts. Implement MFA and configure conditional access for risk-based authentication.
Step 1: Configure MFA for Global Admin Roles
- Users: Select role: Global Administrator
- Cloud apps or actions: All cloud apps
- Conditions: None required (applies to all sign-ins)
- Grant: Require multi-factor authentication
Step 2: Test MFA Enforcement
Step 3: Configure Risk-Based Conditional Access
Create a policy that requires MFA only for risky sign-ins:
- Users: All users
- Cloud apps: All cloud apps
- Conditions:
- Sign-in risk: High, Medium
- Grant: Require multi-factor authentication
Step 4: Set Up Unusual Location Detection
- Users: All users (except emergency access accounts)
- Cloud apps: All cloud apps
- Conditions:
- Locations: Exclude Trusted locations, Include All other locations
- New/Unfamiliar locations: Yes
- Grant: Require multi-factor authentication
Step 5: Test Conditional Access Policies
Test scenarios:
Step 6: Register MFA Methods for All Users
For successful MFA, users need registered devices:
- Send them: "Please register MFA: https://aka.ms/setupsecurityinfo"
- Ask them to register:
- Primary: Authenticator app (Microsoft Authenticator)
- Backup: Windows Hello or FIDO2 key
✅ Complete: All admins require MFA on every sign-in
✅ Risk-based MFA configured for all users
✅ Unusual location detection active
✅ MFA methods registered and tested
No alerting for suspicious sign-ins. Configure monitoring to detect breach patterns and create alerts.
Step 1: Review Sign-in Logs
- Failed sign-in attempts (>5 from same user)
- Sign-ins from unusual locations
- Sign-ins outside business hours
- Bulk changes by unusual users
- Access to sensitive resources
Sign-In Analysis (Last 7 Days)────────────────────────────
High Risk Findings:
├─ User: john.smith@acme.com
│ ├─ Failed attempts: 12 in 1 hour (password guessing attempt?)
│ ├─ Location: Unknown (VPN detected)
│ ├─ Time: 2:00 AM (unusual)
│ └─ Action: INVESTIGATE - potential compromise
│
├─ User: admin@acme.com
│ ├─ Bulk access changes: Added to 5 sensitive groups
│ ├─ Location: Malaysia (company is US-based)
│ ├─ Time: Outside business hours
│ └─ Action: VERIFY - possible unauthorized access
Step 2: Create Azure Monitor Alerts
- Resource: Entra ID
- Signal: Sign-in activity (Entra ID logs)
- Condition:
- > 5 failed sign-in attempts
- Within 5 minutes
- Action: Email to security team
- Condition:
- Sign-in risk level = High
- Unfamiliar location detected
- Action: Email admin, create ticket
- Condition:
- Multiple role assignments by single user
- Multiple group membership changes by single user
- Action: Require manual review before completion
Step 3: Create Incident Response Playbook
Document what to do when alerts fire:
Incident Response Playbook═══════════════════════════
Alert: Multiple Failed Sign-in Attempts
──────────────────────────────
- Check alert: How many failed attempts?
- Contact user: "Is this you? Any account issues?"
- If user: "Use password reset or MFA recovery"
- If compromised: Lock account immediately
- Document: When, who, what actions taken
Alert: Sign-in from Unusual Location
──────────────────────────────
- Check alert: Where is the location?
- Contact user: "Did you sign in from [location]?"
- If YES: Approve and add location to trusted list (optional)
- If NO: Password reset + full account audit
- Document: Security incident
Alert: Bulk Changes by User
──────────────────────────────
- Review: What changes were made?
- Verify: Are they legitimate/authorized?
- If legitimate: Document business reason
- If suspicious: Roll back changes immediately
- Contact user: Investigate if account compromised
Step 4: Test Monitoring & Alerts
Simulate suspicious activity:
- Verify: Account locks after 5 failed attempts
- Verify: Alert fires
- Verify: Email received
- Verify: Location shows differently
- Verify: Conditional Access triggers MFA
- Verify: Alert created (if configured)
✅ Complete: Monitor alerts detect suspicious sign-in patterns
✅ All alerts configured and tested
✅ Incident response procedures documented
✅ Security team knows escalation process
180+ individual role assignments instead of group-based. Migrate all human access to groups for scalability.
Step 1: Plan Group Structure
Create a group naming scheme and structure:
Group Naming Convention: grp-[department]-[role]Examples:
├─ grp-engineering-contributors (Contributor role)
├─ grp-engineering-readers (Reader role)
├─ grp-operations-admins (Owner role on OPS resources)
├─ grp-marketing-readers (Reader role)
├─ grp-finance-auditors (Reader role on billing)
├─ grp-support-vm-managers (VM Operator role)
└─ grp-security-admins (Global Admin)
Step 2: Create Security Groups
For each group:
Example creation:
Group: grp-engineering-contributors├─ Type: Security
├─ Description: Engineering team with Contributor role on development resources
├─ Members: (to be populated)
└─ Owners: Engineering Lead + Security Team
Step 3: Populate Groups
- Go to Entra ID > Groups > [Group Name]
- Click Members > Add members
- Select all users needing that role
- Click Select
Migration Plan──────────────
grp-engineering-contributors:
├─ From: 15 individual Contributor assignments
├─ To: grp-engineering-contributors (15 members)
├─ Verification: Each member can still perform their job
└─ Status: ✅ Migrated
grp-operations-admins:
├─ From: 8 individual Owner assignments
├─ To: grp-operations-admins (8 members)
├─ Verification: OPS team confirms access
└─ Status: ✅ Migrated
Step 4: Assign Roles to Groups
- Role: [Appropriate role - e.g., Contributor]
- Assign access to: Groups
- Members: Select group (e.g., grp-engineering-contributors)
- Click Assign
- Go back to Access control (IAM)
- Confirm group appears with assigned role
Step 5: Remove Individual Assignments
Once groups are in place and tested:
- If they're now in a group with same role: Remove individual assignment
- Click their role, select Remove
- Confirm removal
Individual Assignments Removed:├─ Alice Smith: Removed Contributor (now in grp-engineering-contributors)
├─ Bob Johnson: Removed Contributor (now in grp-operations-admins)
├─ Charlie Lee: Removed Reader (now in grp-marketing-readers)
└─ Total: 45 individual assignments removed
Step 6: Audit Group Membership
Create a process for regular group audits:
Group Audit Checklist (Monthly)──────────────────────────────
For each group:
``
<h3 id="validation-checklist">Validation Checklist</h3>
<h3 id="success-criteria">Success Criteria</h3>
✅ Complete: All human access is group-based
✅ All individual assignments migrated
✅ Group audit process established
✅ Scalable, auditable access model in place
<h2 id="part-6-approval-workflows-entitlement-management">Part 6 – Approval Workflows & Entitlement Management</h2>
<h3 id="the-challenge">The Challenge</h3>
No formal approval process. Implement Entitlement Management so privileged roles require proper authorization.
<h3 id="what-youll-learn">What You'll Learn</h3>
<h3 id="step-by-step-tasks">Step-by-Step Tasks</h3>
<strong>Step 1: Enable Entitlement Management</strong>
<strong>Step 2: Create Sensitive Role Access Package</strong>
<strong>Access Package 1: Production Contributor Access</strong>
Name: Production-Contributor-Access
Description: Request Contributor role on production subscription
Purpose: Deploy and manage production resources
Catalog: Default
Resources:
├─ Subscription: Production (Add)
├─ Role: Contributor
└─ Scope: Subscription
Who can request:
├─ Users: All employees (members)
├─ Admin: All employees (members)
Approval Policy:
├─ Approver 1: Direct manager (auto)
├─ Approver 2: Security team (manual)
├─ Approver 3: Resource owner (manual)
├─ Same person cannot approve own request
├─ Auto-denial if no approval in 7 days
Access period:
├─ Duration: 90 days
├─ Auto-review: Yes (before expiration)
├─ Recertification: Quarterly
<strong>Step 3: Set Up Approval Workflow Details</strong>For each access package, define:
Approval Workflow: Production Contributor Access
═════════════════════════════════════════════════
Request Submission:
Approval Stage 1 - Manager Review (24 hrs):
├─ Approver: Direct manager
├─ Question: "Does [user] need this for their job?"
├─ Options: Approve / Deny / Request more info
├─ If Approved: → Go to Stage 2
├─ If Denied: → Notify user, process ends
Approval Stage 2 - Security Review (48 hrs):
├─ Approver: Security team
├─ Question: "Are there security concerns with this assignment?"
├─ Review: User's history, role sensitivity, usage patterns
├─ If Approved: → Go to Stage 3
├─ If Denied: → Notify user and manager, process ends
Approval Stage 3 - Resource Owner Review (48 hrs):
├─ Approver: Production subscription owner
├─ Question: "Should this person have access to production?"
├─ If Approved: → Provision access
├─ If Denied: → Deny request, process ends
Provisioning:
├─ System auto-assigns group to Contributor role
├─ Start date: Immediately (or scheduled)
├─ Expiration date: 90 days from approval
├─ Notification: User + manager + approvers
Post-Approval:
├─ Day 60: Reminder to user access expires in 30 days
├─ Day 85: Auto-review reminder for everyone
├─ Day 90: Access expires, role automatically removed
├─ User can re-request for extension (repeats approval process)
<strong>Step 4: Test Approval Workflow</strong>
- Create a test user account (or have colleague test)
- Request access: Go to <strong>Access packages</strong> (as test user)
- Find: "Production-Contributor-Access"
- Click <strong>Request access</strong>
- Submit request with business justification
Track approval flow:
<strong>Step 5: Document Approval Audit Trail</strong>
Verify audit trail is captured:
- Requester
- What was requested
- Approval chain
- Who approved when
- When access was provisioned
- When access expires
Document in audit log:
Access Request Audit Trail Example
───────────────────────────────────
Request #1 - Production Contributor Access
├─ Requester: John Smith (john@acme.com)
├─ Submitted: 2024-06-15 10:30 AM
├─ Business Justification: "Deploy new feature to production API"
├─ Approval 1: Manager (Sarah Johnson) - Approved 2024-06-15 11:00 AM
├─ Approval 2: Security (sec-team@acme.com) - Approved 2024-06-15 2:30 PM
├─ Approval 3: Owner (ops-lead@acme.com) - Approved 2024-06-15 3:45 PM
├─ Provisioning: 2024-06-15 3:50 PM
├─ Access Type: Group membership in grp-production-contributors
├─ Expiration: 2024-09-13
└─ Status: ✅ Approved & Provisioned
(Full audit trail available for compliance/investigation)
<h3 id="validation-checklist">Validation Checklist</h3>
<h3 id="success-criteria">Success Criteria</h3>
✅ Complete: Formal approval process for all privileged access
✅ Separation of duty enforced (no self-approval)
✅ All approvals logged with full audit trail
✅ Access automatically expires after 90 days
<h2 id="part-7-secure-offboarding-account-cleanup">Part 7 – Secure Offboarding & Account Cleanup</h2>
<h3 id="the-challenge">The Challenge</h3>
Former employees still have access. Implement rapid offboarding process to disable accounts within 24 hours.
<h3 id="what-youll-learn">What You'll Learn</h3>
<h3 id="step-by-step-tasks">Step-by-Step Tasks</h3>
<strong>Step 1: Create Offboarding Process</strong>
Employee Offboarding Checklist
═══════════════════════════════
Employee Name: _____________
Department: __________
Last Day: __________
Departure Date: _____________
BEFORE Last Day (Day -1):
├─ [ ] Request IT to disable account access
├─ [ ] Collect company laptop, phone, badges
├─ [ ] Transfer file ownership (OneDrive, Teams)
├─ [ ] Download/backup employee data
ON Last Day (Day 0):
├─ [ ] Disable Entra ID account (immediately)
├─ [ ] Revoke group memberships
├─ [ ] Remove role assignments
├─ [ ] Disable MFA phone/app
├─ [ ] Revoke Teams/Office 365 access
AFTER Last Day (Day +30):
├─ [ ] If not needed: Delete Entra ID account
├─ [ ] Audit for any remaining access
├─ [ ] Verify mailbox retention policy active
└─ [ ] Mark as complete in audit log
<strong>Step 2: Disable Account (Immediate)</strong>Simulate offboarding for a test user:
- Go to <strong>Entra ID</strong> > <strong>Users</strong>
- Find employee to offboard
- Click their name
- Click <strong>Disable account</strong>
- Confirm: Account is now disabled
Verify disabled:
<strong>Step 3: Remove All Access</strong>
For the disabled user, remove:
<strong>Remove from Groups:</strong>
- Click group name
- Click <strong>Members</strong>
- Find user
- Click <strong>Remove</strong>
Example removals:
Group Removals for Departing Employee:
├─ Removed from: grp-all-employees
├─ Removed from: grp-engineering-contributors
├─ Removed from: grp-production-access
├─ Removed from: grp-aws-access
└─ Total: 8 groups
<strong>Remove Role Assignments:</strong>
- Go to <strong>Subscriptions</strong> > <strong>Access control (IAM)</strong>
- Search for user
- For each role:
- Click role
- Click <strong>Remove</strong>
- Confirm
<strong>Step 4: Verify All Access Removed</strong>
- Try to sign in as departing employee:
- Username: [their email]
- Password: [any password]
- Expected: "Sign in failed" message
- ✅ Verification: Cannot sign in
- Check no remaining access:
- Go to <strong>Entra ID</strong> > <strong>Users</strong> > [User]
- Group memberships: None
- Role assignments: None
- MFA methods: Disabled
<strong>Step 5: Delete Account (After 30 days)</strong>
If employee data retention period passed:
- Go to <strong>Entra ID</strong> > <strong>Users</strong>
- Click disabled user
- Click <strong>Delete user</strong>
- Confirm deletion
- Log deletion in audit trail
<strong>Step 6: Audit for Orphaned Accounts</strong>
Monthly task - find accounts we missed:
- Go to <strong>Entra ID</strong> > <strong>Users</strong>
- Filter: Status = Disabled
- For each disabled user >30 days old:
- Verify: They were supposed to be disabled
- Verify: No lingering access
- Action: Delete if retention passed
- Create audit report
Monthly Orphaned Account Audit
────────────────────────────────
Disabled accounts found: 12
Accounts properly cleaned: 12
├─ 4 deleted (retention period passed)
├─ 8 still in retention (delete after: [date])
No access found for disabled accounts ✅
Recommendations:
└─ Continue monthly audits
<h3 id="validation-checklist">Validation Checklist</h3>
<h3 id="success-criteria">Success Criteria</h3>
✅ Complete: All departing employees disabled within 24 hours
✅ Zero access remains for disabled accounts
✅ Offboarding process documented
✅ Monthly audit process established
<h2 id="part-8-app-authentication-best-practices">Part 8 – App Authentication Best Practices</h2>
<h3 id="the-challenge">The Challenge</h3>
12 apps using hardcoded passwords for Azure authentication. Migrate to managed identities (zero secrets).
<h3 id="what-youll-learn">What You'll Learn</h3>
<h3 id="step-by-step-tasks">Step-by-Step Tasks</h3>
<strong>Step 1: Audit Current App Authentication</strong>
Document how each app authenticates:
Application Authentication Audit
═════════════════════════════════
App 1: DataExport Service
├─ Current: Hardcoded password in appsettings.json
├─ Location: Web server (production)
├─ Risk Level: 🔴 HIGH (password in code)
├─ Change to: Managed Identity
App 2: Backup Automation
├─ Current: Hardcoded password in environment variable
├─ Location: Automation account
├─ Risk Level: 🔴 HIGH (password in config)
├─ Change to: Managed Identity
App 3: Legacy Service
├─ Current: Service principal with certificate
├─ Location: On-premises
├─ Risk Level: 🟡 MEDIUM (certificate needs rotation)
├─ Change to: Renew certificate, set rotation reminder
Summary:
├─ Apps using passwords: 9 (CRITICAL - must migrate)
├─ Apps using certificates: 2 (OK - set rotation reminder)
├─ Apps using managed identity: 1 (BEST PRACTICE)
└─ Action Items: Migrate 9 to managed identity
<strong>Step 2: Create Managed Identity for Azure App</strong>For apps running ON Azure (VM, App Service, Container, Function):
<strong>Scenario: WebApi running on Azure App Service</strong>
- Go to <strong>Azure Portal</strong> > <strong>App Services</strong> > [App Name]
- Click <strong>Identity</strong> (left menu)
- Click <strong>System assigned</strong> tab
- Set <strong>Status</strong>: ON
- Click <strong>Save</strong>
Verify managed identity created:
<strong>Step 3: Grant Permissions to Managed Identity</strong>
The managed identity needs permissions to access Azure resources:
- <strong>Role</strong>: Appropriate for app (e.g., Contributor for deployment)
- <strong>Assign access to</strong>: Managed Identity
- <strong>Members</strong>: Select your app (e.g., "WebApi-prod")
Verify permissions:
<strong>Step 4: Update App Code to Use Managed Identity</strong>
Update app to use managed identity instead of password:
<strong>Before (Hardcoded Password - INSECURE):</strong>
// NEVER DO THIS!
var credential = new UsernamePasswordCredential(
username: "app@acme.com",
password: "SuperSecretPassword123!" // In code = BAD!
);
var client = new BlobContainerClient(
new Uri("https://storage.blob.core.windows.net/container"),
credential);
<strong>After (Managed Identity - SECURE):</strong>
// CORRECT: Use managed identity
var credential = new ManagedIdentityCredential();
var client = new BlobContainerClient(
new Uri("https://storage.blob.core.windows.net/container"),
credential);
No credentials needed!<strong>Step 5: Remove Hardcoded Passwords</strong>
Once app is updated and tested:
- Remove password from code:
- Delete from appsettings.json
- Delete from appsettings.production.json
- Delete from environment variables
- Delete from Key Vault (if stored there)
- Remove old service principal:
- Go to <strong>Entra ID</strong> > <strong>App registrations</strong>
- Find old app service principal
- Click <strong>Delete</strong>
- Verify no passwords remain:
- Code review
- Configuration check
- Grep for "password" in codebase
<strong>Step 6: Compare Authentication Methods for Off-Azure Apps</strong>
For apps NOT running on Azure (on-premises, external cloud):
| Method | Security | Effort | Use Case |
|---|---|---|---|
| <strong>Password</strong> | 🔴 Low | ⚠️ Minimal | Never. Seriously. |
| <strong>Certificate</strong> | 🟢 Good | 📌 Medium | Off-Azure apps, set rotation reminder |
| <strong>Managed ID</strong> | 🟢️ Best | ✅ None | Apps on Azure only |
<strong>For On-Premises Apps: Use Certificate</strong>
On-Premises App: Legacy Service
────────────────────────────
Authentication: Service Principal + Certificate
Certificate Thumbprint: ABC123DEF456...
Expiration Date: 2025-06-15
Rotation Reminder: 2025-05-15 (30 days before)
Rotation Steps:
├─ Generate new certificate
├─ Upload to app service principal
├─ Update app config with new thumbprint
├─ Test with new cert
└─ Decommission old cert
<strong>Step 7: Create Secrets Cleanup Checklist</strong>
- Audit all passwords/secrets still in use:
`
find . -type f \( -name "<em>.json" -o -name "</em>.config" \) \
| xargs grep -l "password\|secret\|credential"
`
- For each found:
<h3 id="validation-checklist">Validation Checklist</h3>
<h3 id="success-criteria">Success Criteria</h3>
✅ Complete: All hardcoded passwords removed
✅ Zero secrets in code
✅ Apps using zero-secret authentication
✅ Certificate rotation process documented
<h2 id="final-assessment-security-hardening-checklist">Final Assessment: Security Hardening Checklist</h2>
After completing all 8 parts, verify all best practices are implemented:
SECURITY HARDENING FINAL CHECKLIST
════════════════════════════════════
✅ Part 1: Least Privilege
├─ [ ] Owner roles reduced to essential only
├─ [ ] Custom roles created for specific needs
├─ [ ] All users have minimum necessary access
└─ [ ] 40%+ privilege surface reduced
✅ Part 2: Access Reviews
├─ [ ] Quarterly access review process defined
├─ [ ] Inactive accounts identified (>90 days)
├─ [ ] Orphaned accounts disabled/deleted
└─ [ ] Permission creep cleaned up
✅ Part 3: MFA & Conditional Access
├─ [ ] MFA required for all admins
├─ [ ] Risk-based MFA configured for all users
├─ [ ] Unusual location detection active
└─ [ ] MFA methods registered and tested
✅ Part 4: Sign-in Monitoring
├─ [ ] Failed sign-in alerts configured
├─ [ ] Unusual location alerts active
├─ [ ] Suspicious activity detected and investigated
└─ [ ] Incident response playbook created
✅ Part 5: Group-Based Governance
├─ [ ] Security groups created for all roles
├─ [ ] 50+ individual assignments migrated to groups
├─ [ ] Zero individual user assignments remain
└─ [ ] Group membership audit process established
✅ Part 6: Approval Workflows
├─ [ ] Entitlement Management enabled
├─ [ ] Access packages created for sensitive roles
├─ [ ] 3-stage approval workflow implemented
├─ [ ] Separation of duty enforced
└─ [ ] Audit trail captured for all requests
✅ Part 7: Offboarding
├─ [ ] Offboarding checklist created
├─ [ ] Accounts disabled within 24 hours
├─ [ ] All access removed immediately
├─ [ ] Monthly orphaned account audit established
└─ [ ] Zero access remains for former employees
✅ Part 8: App Authentication
├─ [ ] App authentication audit completed
├─ [ ] Managed identities implemented for Azure apps
├─ [ ] All hardcoded passwords removed
├─ [ ] Certificate rotation process documented
└─ [ ] Zero secrets in code
OVERALL SECURITY POSTURE
════════════════════════
Before (Audit Findings):
├─ 47 over-privileged users with Owner
├─ 23 inactive accounts with access
├─ 0 MFA on admin accounts
├─ No monitoring or alerts
├─ 180+ individual access assignments
├─ No approval process
├─ 8 departed employees with access
└─ 12 apps with hardcoded passwords
Result: 🔴 HIGH RISK - Multiple critical findings
After (Implementation Complete):
├─ Owner roles: 3 only (essential)
├─ Inactive accounts: 0 (all cleaned)
├─ MFA: 100% on admins, risk-based for all
├─ Monitoring: Active with alerts
├─ Access: 100% group-based
├─ Approvals: Formal workflow with audit trail
├─ Offboarding: 24-hour SLA
└─ Passwords: 0 in code, all managed identities
Result: ✅ COMPLIANT - Audit findings remediated
COMPLIANCE EVIDENCE
═══════════════════
Generate audit report for security team:
Next Steps:
├─ Schedule follow-up audit: 90 days
├─ Establish monthly review cadence
├─ Update security policies with new procedures
└─ Train team on new processes
``
✅ Least Privilege - Give minimum access needed, nothing more
✅ Regular Reviews - Quarterly access audits catch permission creep
✅ MFA - Makes password theft much less valuable
✅ Monitoring - Sign-in logs detect compromise early
✅ Groups - Easier to manage than individual assignments
✅ Approvals - Formal workflow prevents unauthorized access
✅ Offboarding - Disable accounts within 24 hours
✅ Secrets - Zero hardcoded passwords, use managed identities
After completing this lab, you should:
✅ Understand how to audit and enforce least privilege
✅ Know how to conduct quarterly access reviews
✅ Be able to implement MFA and conditional access
✅ Understand sign-in log analysis
✅ Know how to scale access with groups
✅ Be able to implement approval workflows
✅ Understand rapid offboarding procedures
✅ Know when to use managed identities vs certificates