🛡 Get audit

IAM Best Practices: Locking Down Who Can Access What in AWS and GCP

Identity and Access Management, or IAM, controls who can do what within your cloud environment — which users, services, and applications can read a database, launch a server, or delete a storage bucket. Misconfigured IAM permissions are one of the root causes behind many cloud security incidents covered in our cloud security basics guide, and this guide goes deeper into getting IAM specifically right for a small team managing AWS or GCP infrastructure.

The principle of least privilege, applied practically

Least privilege means granting only the specific permissions a user or service genuinely needs to do its job, nothing broader. In practice, under deadline pressure, it is common to grant broad administrative access “just to unblock this task” with the intention of narrowing it later — a step that in our experience working with small teams rarely actually happens once the immediate task is done.

A more sustainable approach is starting with minimal permissions and adding specific additional permissions only as a genuine, demonstrated need arises, rather than starting broad and hoping to narrow later. This is more upfront friction but avoids the much more common failure mode of permissions that just keep expanding over time with nobody ever removing what is no longer needed.

Users, groups, and roles: structuring access sensibly

Both AWS and GCP support organizing permissions through groups (AWS) or role-based structures rather than assigning permissions to individual users one at a time. Define a small number of clear roles that match how your team actually works — a “developer” role with access to deploy and monitor applications but not manage billing or delete production databases, an “admin” role with fuller access reserved for a small number of people, and any project-specific roles your team’s structure requires.

Assign users to these predefined roles rather than crafting individual custom permission sets per person. This makes onboarding a new team member straightforward (assign them the appropriate existing role) and makes auditing who has what access far easier, since you are reviewing a small number of defined roles rather than potentially dozens of unique individual permission configurations.

Cloud server infrastructure security access controls

Service accounts and machine identities

Beyond human users, your cloud environment likely has service accounts or machine identities — an application server that needs to read from a database, a CI/CD pipeline that needs to deploy new code, a monitoring tool that needs read-only visibility into your infrastructure. These deserve the same least-privilege scrutiny as human users, and arguably more, since a compromised service account credential can often be used at scale and speed that a compromised human login cannot.

Avoid using long-lived static credentials for service accounts wherever your cloud provider offers an alternative. AWS IAM roles for EC2 instances and Lambda functions, and GCP’s workload identity federation, both allow services to obtain temporary, automatically rotating credentials rather than a permanent access key that, if leaked, remains valid indefinitely until someone notices and manually revokes it.

Reviewing and removing unused permissions

Both platforms offer tools specifically for identifying permissions that exist but have not actually been used: AWS IAM Access Analyzer and GCP’s Policy Analyzer / Recommender both surface permissions granted to a user or service that show no evidence of actual use over a defined period. Run these periodically — quarterly is a reasonable cadence for most small teams — and treat unused permissions as a signal to investigate and likely remove, rather than something to leave in place simply because removing it feels like unnecessary work.

This periodic review matters more than a one-time cleanup, since permissions naturally accumulate over time as team members change roles, new projects start, and old ones wind down without anyone circling back to adjust access accordingly.

Root and organization-owner account protection

The AWS root account and GCP’s organization owner account carry unrestricted access to everything in your environment, and should essentially never be used for day-to-day work. Enable multi-factor authentication on these accounts immediately upon account creation, store the credentials securely (ideally in a restricted shared vault as described in our shared vault guide), and create separate, appropriately scoped IAM users or roles for actual daily work rather than using the root/owner account directly.

Conditional and context-aware access policies

Beyond simply defining what a user or role can do, both AWS and GCP support conditional policies that add context-based restrictions — allowing access only from specific IP ranges, only during certain hours, or only when multi-factor authentication has been verified for that specific session. These conditional layers add meaningful protection beyond the base permission grant itself, since even a correctly scoped permission can be misused if the underlying credential is compromised, whereas a conditional restriction (like requiring a specific corporate IP range) adds a barrier that a remote attacker using stolen credentials from elsewhere would still need to overcome.

For a small team, applying conditional access to your most sensitive permissions — production database access, billing management, IAM administration itself — is a reasonable place to start, rather than attempting to apply conditional policies universally across every permission in your environment, which adds complexity that may not be justified for lower-risk access.

Logging and alerting on IAM changes specifically

Changes to IAM policies — a new permission granted, a role modified, a new user added with elevated access — are among the highest-value events to specifically monitor and alert on, since an attacker who has gained some initial foothold in your environment will often attempt to grant themselves broader or more persistent access as a next step. Both AWS CloudTrail and GCP’s Cloud Audit Logs capture these events, and setting up specific alerts for IAM policy changes (rather than relying on someone manually reviewing general logs periodically) gives your team a chance to catch unauthorized privilege escalation quickly rather than discovering it much later.

Cross-account and cross-project access

As teams grow, it becomes common to have multiple AWS accounts or GCP projects — separating production from staging environments, or separating different client engagements. Access granted across these boundaries deserves particular attention, since a permission that seems reasonable within a single account or project can become a much broader exposure if it inadvertently grants access across account or project boundaries that were meant to be isolated from each other.

When setting up cross-account or cross-project roles — often necessary for legitimate reasons like centralized logging or shared tooling — explicitly define and document why the cross-boundary access exists and what it is scoped to, rather than granting broad cross-account trust relationships as a convenience shortcut.

Practical starting checklist

1. Enable multi-factor authentication on the root/owner account if not already done.
2. Define a small set of clear roles matching your team’s actual structure, rather than individual custom permissions per person.
3. Move any service using long-lived static credentials to temporary, automatically rotating credentials where your provider supports it.
4. Run your provider’s unused-permission analysis tool and remove anything genuinely unused.
5. Document any cross-account or cross-project access explicitly, including why it exists.
6. Set a recurring reminder (quarterly) to repeat this review, since access naturally drifts over time.

Frequently asked questions

Is IAM configuration meaningfully different between AWS and GCP?
The underlying principles are identical, though the specific terminology and tools differ — AWS IAM policies and roles vs GCP IAM roles and policies, AWS IAM Access Analyzer vs GCP’s Policy Analyzer. A team comfortable with one platform’s IAM model can generally apply the same logic to the other with some adjustment to the specific tool names and interfaces.

How often should permissions actually be reviewed for a small team?
Quarterly is a reasonable default for most small teams, though any significant team change — someone leaving, a role change, a new major project starting — is also a natural trigger to review relevant permissions immediately rather than waiting for the next scheduled review.

Do we need a dedicated IAM management tool beyond what AWS and GCP provide natively?
For most small teams, the native tools (IAM Access Analyzer, Policy Analyzer) are sufficient. Dedicated third-party identity governance tools become more relevant once your team and infrastructure grow large enough that manual native-tool review becomes impractical to keep up with regularly.

What is the biggest single IAM mistake small teams make?
Granting broad administrative access as a default starting point “to unblock things quickly,” with no follow-up plan to narrow it. This single habit, more than any other specific misconfiguration, tends to be the root cause behind the accumulated over-permissioning we see most often when reviewing a small team’s cloud environment for the first time.

Should we use the same IAM structure across all our cloud projects or accounts?
A consistent structure and naming convention across projects makes management easier and reduces confusion as your team grows, though the specific permissions within that structure should still be scoped appropriately per project based on what each one actually requires, rather than copying identical broad permissions across every project regardless of its individual sensitivity.

For more on securing your cloud infrastructure, see our cloud security basics guide and full hardening guides section.

Leave a Comment