Cloud permissions only ever accumulate: roles are granted for a migration, a pilot or an outage, access keys are created for a tool that has since been retired, and cross-account trusts outlive the supplier contract, so a year later nobody can say which grants are still needed. This template is a repeatable cloud IAM review procedure and worksheet for AWS, Microsoft Azure and Google Cloud: what to export, the cross-cloud checks that apply everywhere (unused permissions, wildcard policies, long-lived keys, external trust, break-glass, MFA on privileged roles and logging), the platform-specific checks, and how to track findings and sign off. It uses each provider's own guidance and native tools, so the completed worksheet doubles as audit evidence for NIST SP 800-53 AC-2 and AC-6. It is written for cloud security engineers and identity teams who run cloud IAM audits, and the control owners who must approve the results.
How to use this template
- Replace text in square brackets, such as [Organisation], [Cloud security team] and [90 days], with your own teams and values.
- "Must" is mandatory; "should" is recommended, with exceptions handled under section 10.
- Run one review per AWS organisation, Microsoft Entra tenant with its Azure management group hierarchy, and Google Cloud organisation. Copy the check tables into your tracker and add a result column (Pass, Fail, N/A) and an evidence column.
- A check passes only when the evidence is recorded: an export file, a finding ID, a screenshot of a setting with its date. "Believed to be fine" is not evidence.
- For the design behind these checks, read the Cloud PAM and CIEM Guide; for review campaigns in general, the Access Reviews Guide.
1. Purpose
This procedure ensures that every human and non-human identity with access to [Organisation]'s cloud platforms holds only the permissions it currently needs, at the narrowest scope, with credentials that are short-lived where possible, and that privileged and external access is approved, monitored and recoverable. It implements the account review in NIST SP 800-53 AC-2 item j, "Review accounts for compliance with account management requirements [Assignment: organization-defined frequency]", and the least privilege requirements of AC-6.
2. Scope
- All AWS accounts in [AWS organisation], all Azure subscriptions under [root management group] and the Microsoft Entra roles that administer them, and all projects and folders in [Google Cloud organisation].
- Human identities: workforce users, administrators, contractors and guests, whether federated, synchronised or local.
- Non-human identities: IAM roles and users, service principals, managed identities, Google Cloud service accounts, workload identity federation bindings, access keys, service account keys, application secrets and certificates.
- Resource-based access: bucket and key policies, cross-account and cross-tenant trust, and public grants.
Kubernetes RBAC inside clusters and SaaS admin roles are reviewed under [Platform Access Standard].
3. Roles and responsibilities
- [Head of Cloud Security]: owns this procedure, approves the schedule and signs off each review.
- [Cloud security team]: exports data, runs the checks, raises findings and chairs owner reviews.
- Account, subscription and project owners: confirm or remove grants in their scope within [10 working days] of a request.
- Identity owners for non-human identities: the named team for each role, service principal or service account; they confirm purpose and permissions. See the NHI Ownership Guide.
- [Internal audit or second line]: samples completed reviews; reviewers must not certify their own access.
4. Review cadence and triggers
| Review type | Frequency | Scope |
|---|---|---|
| Privileged access review | [Quarterly] | Root and break-glass, Owner, User Access Administrator, Global Administrator, Organization Administrator, AdministratorAccess and any identity that can grant access |
| Full cloud permission review | [Every 6 months] | All checks in sections 6 to 9 |
| Unused access sweep | [Monthly] | Unused roles, keys, passwords and permissions from native analysers |
| External trust review | [Quarterly] and at every supplier exit | Cross-account roles, guest users, foreign principals, public grants |
| Event-driven review | Within [30 days] | Merger, reorganisation, new landing zone, cloud security incident |
5. Preparing the review: data to export
Export from the platform, not from documentation, and record the export time. Use a 90-day usage window as the default; Google Cloud's role recommender uses at most 90 days of history, so a longer window needs your own log analysis.
| Cloud | Export | Used for |
|---|---|---|
| AWS | IAM credential report per account; IAM Access Analyzer external access and unused access findings at organisation scope; IAM last accessed information; role trust policies; SCPs and RCPs; IAM Identity Center permission set assignments | Checks X-1 to X-8, AWS-1 to AWS-8 |
| Azure | Role assignments at management group, subscription and resource group scope (including inherited); PIM eligible and active assignments; Entra role holders; app registrations with credential expiry; managed identities; guest users; custom role definitions | Checks X-1 to X-8, AZ-1 to AZ-8 |
| Google Cloud | Allow policies at organisation, folder and project level (Cloud Asset Inventory); IAM role recommendations and policy insights; service account insights; service account keys with creation dates; organisation policies | Checks X-1 to X-8, GCP-1 to GCP-8 |
Note the cost and licence dependencies before relying on a source. AWS states that "IAM Access Analyzer offers external access findings for free" and charges for unused access findings per role and user analysed. Google Cloud's basic-role recommendations are free, but other role recommendations and policy insights need Security Command Center Premium or Enterprise. Microsoft Entra access reviews require Microsoft Entra ID Governance or Microsoft Entra Suite licences.
6. Cross-cloud checks
| ID | Check | Pass criteria | Evidence |
|---|---|---|---|
| X-1 | Unused identities | No human or non-human identity unused for more than [90 days] without a documented reason (disaster recovery, annual process) | Access Analyzer unused roles and credentials; Entra sign-in activity; service account insights |
| X-2 | Unused permissions | Roles granting services or actions not used in the window are reduced or replaced; no identity keeps a broad role when its usage shows a narrow one | Access Analyzer unused permissions; IAM role recommender REMOVE_ROLE and REPLACE_ROLE; Azure activity data |
| X-3 | Wildcard and admin-equivalent policies | No custom policy or role with "Action": "*", "Resource": "*" for write actions, or Azure custom roles with * in Actions or DataActions, outside approved admin roles | Policy and role definition export |
| X-4 | Long-lived keys | No IAM user access keys, service account keys or app secrets where a role, managed identity or federation would work; remaining keys under [90 days] old, owned and stored in [secrets manager] | Credential report; key list with creation dates; app credential expiry |
| X-5 | External and cross-account trust | Every principal from outside the organisation or tenant has a named sponsor, a current contract and the narrowest role; no public grants without an exception | Access Analyzer external access; guest and foreign principal list; allUsers and allAuthenticatedUsers bindings |
| X-6 | Privileged roles and MFA | Every human with an administrative role uses phishing-resistant MFA; privileged roles are eligible (just-in-time), not standing, where the platform supports it | IdP authentication method report; PIM and permission set assignments |
| X-7 | Break-glass | Two or more emergency accounts per platform, cloud-only, phishing-resistant authentication, alert on every use, tested in the last [90 days] | Test record; alert rule; last sign-in date |
| X-8 | Logging of IAM changes | Organisation-wide logging of identity and permission changes is on, retained for [1 year], sent to a separate account or workspace and alerted | CloudTrail organisation trail; Entra audit and Azure Activity logs export; Cloud Audit Logs sink |
X-7 follows Microsoft's emergency access guidance ("Create two or more emergency access accounts", "Validate account functionality at least every 90 days") and is good practice on every platform. See the Break-Glass Account Guide.
7. AWS checks
| ID | Check | Pass criteria |
|---|---|---|
| AWS-1 | Root user | Root has MFA (AWS recommends "multiple MFA devices"), no access keys ("do not create access keys for your root user"), and in member accounts root credentials are removed through centralised root access. Root sign-in alerts fire. |
| AWS-2 | Human access through federation | People use IAM Identity Center or another IdP with temporary credentials; AWS: "Require your human users to use temporary credentials when accessing AWS." No IAM users with console passwords except documented exceptions. |
| AWS-3 | IAM users and access keys | Every IAM user with an access key has an owner and a reason it cannot use a role; keys unused for [90 days] are deactivated, then deleted. |
| AWS-4 | Unused access findings | An organisation-scope unused access analyzer runs; open findings for "Unused roles", "Unused IAM user access keys and passwords" and "Unused permissions" are actioned or excepted. |
| AWS-5 | External access findings | All Access Analyzer external access findings are archived with a reason or resolved; role trust policies naming third-party accounts require an external ID. |
| AWS-6 | Admin-equivalent permissions | AdministratorAccess, iam:*, unrestricted iam:PassRole and sts:AssumeRole on * are held only by approved admin roles; policies pass Access Analyzer policy validation. |
| AWS-7 | Guardrails | SCPs deny leaving the organisation, stopping or deleting CloudTrail trails, and creating IAM user access keys where policy forbids them. AWS notes "No permissions are granted by SCPs and RCPs", so review grants separately. |
| AWS-8 | Delegated administration | Teams that create roles do so within a permissions boundary; the boundary policy itself is reviewed. |
Stolen long-lived keys are the common AWS failure: the Codefinger S3 ransomware used stolen keys to encrypt buckets, and the AWS crypto-mining campaign had miners running within minutes of compromised IAM credentials being used. See the AWS IAM Policies and Roles Guide.
8. Azure checks
| ID | Check | Pass criteria |
|---|---|---|
| AZ-1 | Subscription owners | No more than three Owners per subscription. Microsoft: "You should have a maximum of 3 subscription owners to reduce the potential for breach by a compromised owner." |
| AZ-2 | Privileged administrator roles at broad scope | Owner, User Access Administrator and Role Based Access Control Administrator are not assigned at management group or subscription scope unless required; job function roles are used instead where possible. |
| AZ-3 | Standing privileged access | Privileged Azure and Entra roles are eligible through PIM with approval for the highest; CISA SCuBA MS.AAD.7.4v1: "Permanent active role assignments SHALL NOT be allowed for highly privileged roles." |
| AZ-4 | Global Administrators | Between two and eight Global Administrators (SCuBA MS.AAD.7.1v1), cloud-only accounts, phishing-resistant MFA (MS.AAD.3.6v1). |
| AZ-5 | Assignments to groups, not users | Direct user assignments are the exception; group owners and membership rules are reviewed. |
| AZ-6 | Service principals and app credentials | Every app registration with a secret or certificate has an owner; secrets expire within 180 days and certificates within 365 days (SCuBA MS.AAD.5.6v1 and 5.7v1); managed identities replace secrets for Azure-hosted workloads. |
| AZ-7 | Data-plane reach of control-plane roles | Roles that can change access policies or read keys (for example Key Vault Contributor where vaults still use access policies, or storage account key access) are treated as privileged. |
| AZ-8 | Recurring access reviews | Access reviews run for privileged Entra roles and Azure resource roles through PIM, and for guest users through group reviews, at the cadence in section 4. |
AZ-7 matters because control-plane roles can grant data access: the Azure Key Vault Contributor escalation showed a "no data access" role reading every secret, and the Storm-0501 attacks carried on-premises compromise into Azure through sync credentials. See the Azure RBAC and Service Principals Guide and the Privileged Identity Management (PIM) Guide.
9. Google Cloud checks
| ID | Check | Pass criteria |
|---|---|---|
| GCP-1 | Basic roles | No Owner, Editor or Viewer grants in production projects. Google: "In production environments, do not grant basic roles unless there is no alternative." |
| GCP-2 | Scope of grants | Roles granted at organisation or folder level are limited to platform teams; Google: "Grant roles at the smallest scope needed." |
| GCP-3 | Role recommendations | Open REMOVE_ROLE and REPLACE_ROLE recommendations are applied or dismissed with a reason. "The IAM recommender does not apply recommendations automatically." |
| GCP-4 | Service account keys | The "Disable service account key creation" and "Disable service account key upload" constraints are enforced at the organisation, with exceptions listed; Service Account Key Exposure Response is set to DISABLE_KEY. Google warns it "doesn't guarantee that it will detect leaked keys." |
| GCP-5 | Unused service accounts | Service accounts flagged by service account insights as unused for 90 days are disabled, then deleted. |
| GCP-6 | Impersonation rights | Service Account User and Service Account Token Creator are granted on individual service accounts, not at project level, to named principals. |
| GCP-7 | IAM administration roles | Project IAM Admin and Folder IAM Admin, which can change allow policies, are held only by the platform team. |
| GCP-8 | External principals and public access | Domain restricted sharing (iam.allowedPolicyMemberDomains, or the newer managed constraint) limits grants to your organisation; any allUsers or allAuthenticatedUsers binding has an exception. |
Google also advises "Use logs from Cloud Audit Logs to regularly audit changes to your allow policy"; Admin Activity logs are always written, but Data Access logs must be enabled for most services. See the Google Cloud IAM and Service Accounts Guide.
10. Findings, exceptions and remediation
| Severity | Examples | Remediate within |
|---|---|---|
| Critical | Root or Global Administrator without MFA; access key on root; public grant on sensitive data; unknown external principal with admin rights | [3 working days] |
| High | Standing Owner at subscription or organisation scope; service account key older than [1 year]; wildcard admin policy on a workload role | [14 days] |
| Medium | Unused role or key past [90 days]; basic role in non-production; no owner recorded | [30 days] |
| Low | Direct user assignment that should be a group; missing description or tag | Next review |
- Exceptions must name the risk owner, the compensating control (for example extra alerting) and an expiry of no more than [12 months], and be recorded in [risk register].
- Removals go through [change process]. For non-human identities, disable or deactivate first, watch for errors for [14 days], then delete; rollback is re-enabling the key, role or account.
- A finding closes only when the next export shows the change, not when the ticket closes.
Tracking worksheet (one row per finding): Finding ID [IAM-2026-H2-001] · Cloud and scope [AWS 123456789012 / Azure sub-prod / GCP proj-x] · Identity · Check failed [X-4] · Severity · Action · Owner · Change ticket · Due date · Status [Open / In change / Closed / Exception] · Verified by.
11. Review summary and sign-off
| Item | Entry |
|---|---|
| Scope (organisation, tenant, accounts, subscriptions, projects) | [List] |
| Export date and usage window | [Date] / [90 days] |
| Identities reviewed | Human [n]; non-human [n]; external [n] |
| Grants removed or reduced | [n] removed; [n] narrowed |
| Findings by severity, open at sign-off | Critical [n], High [n], Medium [n], Low [n]; open [n] |
| Break-glass test (X-7) | [Date and result per platform] |
| Reviewed by / approved by | [Name, role, date] / [Head of Cloud Security, date] |
| Next review due | [Date] |
12. Framework mapping
| Checks | NIST SP 800-53 Rev. 5 | CIS Controls v8.1 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|
| X-1, AWS-3, GCP-5 | AC-2 j, AC-2(3) Disable Accounts | 5.3 Disable dormant accounts | A.5.18 Access rights |
| X-2, X-3, AWS-6, GCP-1 to GCP-3 | AC-6, AC-6(7) Review of User Privileges | 6.8 Define and maintain role-based access control | A.5.15 Access control; A.8.2 Privileged access rights |
| X-6, AZ-1 to AZ-4 | AC-6(5) Privileged Accounts; AC-2(7) Privileged User Accounts | 5.4 Restrict administrator privileges; 6.5 Require MFA for administrative access | A.8.2 Privileged access rights; A.8.5 Secure authentication |
| X-4, AZ-6, GCP-4 | IA-5 Authenticator Management | 5.5 Establish and maintain an inventory of service accounts | A.5.17 Authentication information |
| X-8 | AC-6(9) Log Use of Privileged Functions; AU-2 Event Logging | 8.2 Collect audit logs | A.8.15 Logging |
Implementation guidance
- Start with privileged and external access: run the first review on section 4's privileged and external trust scope only. It is small, fast and covers the grants attackers want.
- Turn on the analysers before the review, not during it: unused access findings and recommendations need weeks of history. Enable the organisation-scope analyzer and recommender, and confirm licences, at least one usage window ahead.
- Pilot removals on non-production: apply unused-permission and role recommendations to development accounts and projects first, watch access-denied errors (CloudTrail AccessDenied, Azure authorisation failures, Cloud Audit Logs permission denied) for [14 days], then extend to production.
- Prefer prevention after cleanup: once keys are gone, block new ones (SCPs, Google Cloud key constraints, app credential policies) so the next review does not find them again.
- Automate the export: script section 5 so each review is a diff against the last; manual exports are where reviews stall.
Small organisations with one account, subscription or project per environment can run the template in a spreadsheet twice a year, focusing on X-4, X-6, X-7, AWS-1 and AZ-1. Large estates need CIEM-style analysis across clouds, owner data for every non-human identity and review packages split by business unit; see the Multi-Cloud Identity Guide. Common failure patterns: reviewing only human users while service principals and service accounts hold the broad roles; owners approving everything by default; reviewing roles but not resource policies and trust relationships; removing a grant that is re-added by infrastructure as code the next day; and treating inherited assignments at management group or folder level as someone else's problem. Track these measures each cycle:
- Standing privilege: identities with permanent admin roles (target only break-glass).
- Unused access: open unused role, key and permission findings, trended per review.
- Key hygiene: access keys and service account keys older than [90 days] (target zero without exception).
- External trust: external principals without a sponsor (target zero).
- Remediation: findings closed within the severity deadline.
Standards and references
- NIST: SP 800-53 Rev. 5, Security and Privacy Controls (AC-2, AC-6)
- AWS: Security best practices in IAM
- AWS: Findings for external, internal and unused access in IAM Access Analyzer
- Microsoft Learn: Best practices for Azure RBAC
- Microsoft Learn: What are access reviews?
- Microsoft Learn: Manage emergency access admin accounts
- Google Cloud: Use IAM securely
- Google Cloud: Role recommendations
This template is provided for guidance and must be adapted to your organisation. Related NHI Mgmt Group resources: Cloud PAM and CIEM Guide · Access Reviews Guide · AWS IAM Policies and Roles Guide · Google Cloud IAM and Service Accounts Guide · Privileged Identity Management (PIM) Guide