AWS IAM Security Best Practices, and How P0 Applies Them

by Shashwat Sehgal | Sep 24, 2026 | Zero Standing Privilege (ZSP)

8 mins

AWS publishes a clear set of IAM practices, and most teams already know the basics. The one they struggle with is removing standing permissions: access that was needed once and never taken away. This guide covers both, then shows how P0’s own AWS integration is built to the same standard of AWS IAM security, including the threats we designed it against.

At a glance

  • Use federation and temporary credentials for people and IAM roles for workloads; avoid long-term access keys.
  • Require MFA and lock down the root user.
  • Apply AWS IAM least privilege, using IAM Access Analyzer to right-size policies.
  • Remove unused users, roles, permissions and credentials regularly.
  • Reduce standing AWS permissions with just-in-time access that expires on its own.

AWS IAM security best practices

AWS’s own Security best practices in IAM lists 14 practices. Grouped together, these are the AWS access management best practices that matter most.

1. Use temporary credentials, not long-term keys

Have people sign in through federation with an identity provider, such as IAM Identity Center, and have workloads use IAM roles, so both get temporary credentials that expire on their own. That is the heart of AWS temporary credentials best practices: nothing long-lived to leak. Where a use case still needs long-term access keys, update them when needed and keep their number small.

2. Require MFA and protect the root user

Require multi-factor authentication (MFA) for human users, especially anyone with privileged access. Treat the root user as break-glass only: protect its credentials and don’t use it for everyday tasks.

3. Apply least privilege, starting from AWS managed policies

AWS IAM least privilege means granting only the actions and resources a task needs. AWS suggests starting with AWS managed policies, then tightening toward least privilege. IAM Access Analyzer can generate a fine-grained policy from the access activity logged in AWS CloudTrail, which shows what an identity actually uses.

4. Remove what is not used

Regularly review and remove unused users, roles, permissions, policies and credentials. IAM’s last accessed information shows which services and actions an identity hasn’t touched, so you can cut access with evidence rather than guesswork.

5. Use conditions to narrow access

Add conditions to IAM policies to limit when and how a permission applies, for example allowing an action only when the request uses TLS or comes through a specific AWS service such as AWS CloudFormation.

6. Validate policies and external access

Use IAM Access Analyzer to check your work. It runs more than 100 policy checks with actionable recommendations, and it monitors supported resources continuously, generating a finding when a resource allows public or cross-account access.

7. Set guardrails across accounts

In AWS Organizations, use service control policies (SCPs) and resource control policies (RCPs) to set the maximum permissions available in your accounts; they don’t grant access on their own. Within an account, use permissions boundaries to cap what others can grant when you delegate permissions management.

How to reduce standing AWS permissions

Least privilege limits how much access an identity has. Just-in-time access also limits when, so privileged access doesn’t sit idle between tasks. That is the practical way to reduce standing AWS permissions, and it matches AWS’s Security Maturity Model, which advises against perpetual access for occasional work such as troubleshooting.

OptionWhat it isBest for
IAM Access AnalyzerAWS-native: generates policies from CloudTrail activity and validates themRight-sizing standing permissions
TEAM (AWS sample)Open-source Temporary Elevated Access Management for IAM Identity Center: time-bound requests with approval, removed automaticallyTeams that deploy and run it themselves
P0 SecurityJust-in-time requests from Slack or the P0 CLI, approved per policy, removed at expiryRequest and approval workflows across AWS and other clouds

With P0, a request from the P0 CLI looks like this:

p0 request aws role MyReadOnlyRole –account 123456789012 –reason “Investigating S3 access issues” –wait

Learn more about just-in-time access and zero standing privilege, or see the same approach for Google Cloud and Azure.

How P0’s AWS integration follows these practices

A tool that grants AWS access needs powerful IAM permissions itself, so it should meet the same bar. Here is exactly what P0 asks for and how each risk is contained: a scoped role, a strict trust policy, conditions and explicit denies.

Installing our integration

Before I dive into our security model, let’s understand how our integration works.

To install the integration, we ask you to run AWS commands that: create an IAM Role, create a trust relationship that allows P0’s service account to act as this role, and bind an IAM policy (which allows P0 to read and edit your account’s IAM) to this role. The P0 service account resides in P0’s own environment.

The AWS IAM policy allows P0 to:

  • Create and assign identity policies, and list users, role tags and rolessome text
    • List Roles, Policies, Users, User Tags, Role Policy, Attached Role Policies, Attached User Policies, Policy Versions
    • Get Role, Policy Version
    • Add a user to a group
    • Attach Role Policy,  User Policy
    • Detach Role Policy, User Policy
    • Delete Role, Policy, Policy Version
    • Remove User from group

The AWS IAM policy also:

  • Denies P0 from assuming or attaching more policies to itself

The P0 IAM role also has a preconfigured trust relationship that blocks any identity other than the P0 service account from assuming the P0 role.

These permissions are necessary for the core functionality of our tool: Reading and setting IAM identity-based policies is necessary for provisioning access for users.

Attack Vectors

When providing this level of IAM access to a third-party, a key concern is whether the permissions can be abused by malicious actors in a manner that allows them to gain access to your environment.

There are several potential attack vectors to consider:

  • A user in your organization is able to assume P0’s role to escalate their own privileges outside of the tool.
  • A user in your organization is able to hijack P0’s policy to escalate their own privileges outside of the tool.
  • An attacker compromises P0 and attempts to use our privileges to gain access to your account resources.

P0 takes prevents these attack scenarios using conditional IAM and trust policies, as follows:

Scenario 1: A User assumes P0’s Role

Since P0 uses a role inside your AWS account to grant permissions, a plausible scenario is where an existing user or role inside your account might assume P0’s role to escalate their privileges. To mitigate this threat, we use a strict IAM Trust policy [1], which allows only P0’s service account to assume the role through AWS STS. This ensures that no identity other than P0 can assume the P0 Service role in your account.

Scenario 2: A User escalates their privileges using P0’s policy

P0 also uses an IAM policy to define the actions P0 can perform inside your AWS Account. A potential threat is a user who might attach this policy to a user/role outside the P0 tool, and hence elevate their permissions, without going through P0’s approval workflow. To prevent this threat, we use conditional IAM to restrict each of the statements inside the IAM policy, to the P0 role alone. Any identity that is able to attach this policy will be prevented from performing any of the aforementioned IAM actions.

Scenario 3: An attacker compromises the P0 Service Account:

P0’s GCP service account uses STS inside your AWS accounts to gain access to the P0 IAM role. In theory, if an attacker can infiltrate P0’s infrastructure, they would be able to perform AWS IAM actions via the P0 service account. This is a security threat, as the malicious actor might create new roles in your AWS account, which can be assumed from outside the account, and provide escalated permissions on various AWS resources.

To counter this threat:

  • P0’s AWS IAM policy explicitly denies the service account from adopting any roles other than its assumed IAM role.
  • P0’s AWS IAM policy explicitly denies it from attaching any additional policies to, or removing policies from, its assumed IAM role.
  • P0’s AWS IAM policy, via conditional IAM, denies it from attaching any policies to identities outside of the AWS account.

Transparency

The entirety of the above configuration (role, role policies, and trust relationship) resides within your AWS account’s IAM, and is auditable by any user in your account with IAM read permissions, so there’s no need to use the root user. You can additionally view the configuration commands prior to running them in your system.

While the configuration is editable by your account’s users, manually editing it is not recommended, as it may either break your P0 integration, or expose your account to additional security vulnerabilities.

To dive deeper into the world of P0 Security, explore our guided tour of workflows here, or refer to our detailed docs. You can also join our community Slack channel to engage with like-minded users.

Key takeaways

  • AWS’s own IAM best practices start with temporary credentials, MFA and least privilege.
  • Least privilege limits how much access; just-in-time access also limits when.
  • Use IAM Access Analyzer to right-size, and remove what is unused.
  • Reduce standing AWS permissions with requests that expire on their own.
  • A tool that grants access should follow these practices itself; P0’s integration shows how.

Frequently asked questions

How does identity and access management work in AWS for privileged users and roles?

Identity and access management in AWS relies on IAM roles, policies, and users, but privileged access often accumulates as standing permissions that go unreviewed over time.

What are the most common AWS access security risks and how do you reduce them?

The most common AWS access risks are over-permissioned IAM roles and long-lived credentials; teams reduce them by moving to just-in-time, least-privilege access requests.

How do you enforce least-privilege and just-in-time access to AWS resources?

Teams enforce least-privilege, just-in-time access to AWS by granting scoped permissions only for the duration of a task, then automatically revoking them afterward.

How does P0 Security discover and govern privileged access across AWS accounts?

P0 Security discovers and governs privileged access across AWS accounts by auto-inventorying IAM roles and identities, then enforcing runtime authorization on every access request.

What are the most important AWS IAM security best practices?

AWS’s own list starts with federation and temporary credentials instead of long-term keys, MFA and root user protection, least privilege refined with IAM Access Analyzer and regular removal of unused users, roles, permissions and credentials.

How do you reduce standing permissions in AWS?

Right-size existing permissions with IAM Access Analyzer, then grant elevated access just in time through a request and approval workflow, such as AWS’s TEAM sample or P0, so it expires on its own instead of sitting idle.

References:

  1. https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html

‍