Skip to content
Back to skills

Iam Best Practices

ASecurity

Least-privilege cloud IAM: policy scope, privilege-escalation paths, permissions boundaries, workload identity over static keys, MFA enforced by policy, cross-account trust, and separating deploy from runtime. Use when generating IAM policies, roles, or trust documents, wiring CI/CD service accounts or workload identities, delegating role creation, or designing cross-account access.

  • 22 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
devopstypescriptpythonrustgoexpressrailskubernetesawsgcpazure

Works with

  • api

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add ShieldNet-360/secure-vibe --skill iam-best-practices --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Iam Best Practices?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Iam Best Practices
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shieldnet-360-iam-best-practices-c68d033c/badge)](https://www.skillsdirectory.com/skills/shieldnet-360-iam-best-practices-c68d033c)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
id: iam-best-practices
version: "2.0.0"
title: "Identity & Access Management Best Practices"
description: "Least-privilege cloud IAM: policy scope, privilege-escalation paths, permissions boundaries, workload identity over static keys, MFA enforced by policy, cross-account trust, and separating deploy from runtime. Use when generating IAM policies, roles, or trust documents, wiring CI/CD service accounts or workload identities, delegating role creation, or designing cross-account access."
category: prevention
severity: critical
applies_to:
  - "when generating IAM policies, roles, or trust documents"
  - "when wiring CI/CD service accounts or workload identities"
  - "when delegating role or policy creation to another team"
  - "when reviewing access-key creation, rotation, or revocation"
  - "when designing cross-account or cross-tenant access"
languages: ["hcl", "yaml", "json", "python", "go", "typescript"]
token_budget:
  minimal: 1300
  compact: 1800
  full: 2200
rules_path: "rules/"
related_skills: ["auth-security", "iac-security", "cicd-security", "secret-detection"]
last_updated: "2026-08-12"
sources:
  - "NIST SP 800-53 Rev. 5 (AC-2, AC-3, AC-6, AC-17, IA-2, IA-5)"
  - "CIS Controls v8 (Controls 5 and 6)"
  - "AWS IAM Best Practices"
  - "Google Cloud IAM recommender"
  - "CNCF Kubernetes RBAC Good Practices"
external_tools:
  - name: prowler
    purpose: "live cloud account IAM/security posture assessment (AWS/Azure/GCP)"
    command: "prowler aws"
---

# Identity & Access Management Best Practices

## Rules (for AI agents)

### ALWAYS
- Grant the minimum permissions the workload's stated job requires: deny by default,
  then add concrete actions against concrete resources. A wildcard action on a
  wildcard resource — in a custom policy, in `AdministratorAccess`, or in `iam:*`
  attached to something that runs continuously — is the same finding wearing three
  different names.
- Read a policy for the **privileges it can reach**, not only the ones it names. A
  principal that can write policy (`iam:PutRolePolicy`, `iam:AttachRolePolicy`,
  `iam:CreatePolicyVersion`) can grant itself anything, and a principal that can pass
  a role into a compute service it may also create (`iam:PassRole` with
  `lambda:CreateFunction`, `ec2:RunInstances`, `glue:CreateJob`) inherits that role's
  privileges. These read as narrow grants and are administrative ones.
  `references/escalation-paths.md` lists the combinations worth failing a review over.
- Bound delegated permissions with a **permissions boundary** or an organization-level
  policy (SCP, GCP org policy, Azure management-group policy) when teams may create
  their own roles. The boundary caps what any role they create can do, which is what
  makes self-service role creation safe rather than a privilege-escalation primitive.
- Prefer **workload identity** — IRSA on EKS, GKE Workload Identity, Azure Managed
  Identity, OIDC federation from CI — over a static key. The goal is that no
  long-lived credential exists to leak. Where one is genuinely unavoidable, give it a
  documented rotation cadence and automatic disablement on inactivity, and treat that
  as a temporary state rather than the steady state.
- Enforce MFA for human principals through a **policy condition**
  (`aws:MultiFactorAuthPresent`), not only a directory setting, so a credential that
  bypasses the directory still cannot act.
- Separate the **deploy** identity from the **runtime** identity. The pipeline gets
  permission to create and change infrastructure; the running service gets permission
  to do its job and nothing that mutates IAM. `cicd-security` owns hardening the
  pipeline that holds the deploy role.
- Scope cross-account trust to the actual counterparty. Inside your own organization
  that means a specific principal ARN or `aws:PrincipalOrgID`; for a **third party**
  acting on your behalf it additionally means an `ExternalId` — a per-consumer value
  the third party supplies, which defeats the confused-deputy case where another of
  their customers can name your account. Treat `ExternalId` as an identifier, not a
  secret: it is not one, and relying on its confidentiality is a false assurance.
- Keep sessions short and make the length a deliberate choice. Human and CI roles
  should use the shortest session the workflow tolerates. A longer window on a
  break-glass role is a defensible operational trade — an incident should not expire
  mid-response — but it has to be stated as a decision, paired with alerting, and not
  copied onto ordinary roles.
- For Kubernetes RBAC, scope `Role` and `RoleBinding` to one namespace and reserve
  `ClusterRole` for genuinely cluster-wide objects. Review every `cluster-admin`
  binding at pull-request time, and remember that permission to create workloads in a
  namespace is permission to use every service account in it.
- Log IAM-mutating calls to a tamper-evident sink and alert on them: policy changes,
  `iam:PassRole`, access-key creation, and role assumption from an unexpected
  principal. `logging-security` owns the shape of the record.
- Require out-of-band approval for break-glass use (root, organization owner,
  `cluster-admin`) and alert on every invocation, not on a sample.

### NEVER
- Use the root or organization-owner account for day-to-day work. It gets a hardware
  MFA device, offline storage, and only the tasks that genuinely require it.
- Embed a long-lived access key in source, a container image, a machine image, or a
  CI environment variable where a workload identity or OIDC federation is available.
- Grant `iam:PassRole` with `Resource: "*"`. Pin the exact role ARNs the caller may
  pass, and read that grant together with what the caller can launch.
- Share one principal between multiple humans or multiple services. One identity per
  actor is what makes the audit log mean anything.
- Disable MFA for a principal to resolve a login problem. Rotate the device; the
  requirement stays.
- Persist an OIDC or SAML assertion beyond its stated lifetime. Refresh by
  re-assertion rather than storing the original token.

### KNOWN FALSE POSITIVES
- `Resource: "*"` on APIs that accept no resource ARN — `sts:GetCallerIdentity`,
  `ec2:DescribeRegions` and their equivalents. The wildcard is the only expressible
  value, so the finding is the *action* being unnecessary, not the resource scope.
- Provider-managed service-linked roles carry broader permissions than a role you
  would write. That breadth is the provider's contract and is not yours to narrow.
- A bootstrap operator in a fresh account often needs elevated permissions before the
  guardrails it installs exist. Gate it by tag or organization policy and revoke on
  completion — a bootstrap role that survives bootstrap is a finding again.
- Local development emulators accept any credential. That is a property of the
  emulator, not a grant in your account.
- Enumerating explicit resource ARNs is correct for a bounded set. Attribute-based
  scoping (tags, organization paths) is the answer when the set grows, not a
  security upgrade over naming resources you can name.

## Context (for humans)

Cloud IAM has one property that makes reviewing it different from reviewing other
access control: **the effective permission set is not the stated one**. A role that
can attach a policy can attach `AdministratorAccess` to itself. A role that can pass
another role into a service it can also create runs as that role. Neither policy
contains a wildcard, and both are administrative. Reading a policy for what it says,
rather than for what it can reach, is the failure that produces most
over-permissioned estates.

The second property is that the scalable answer is rarely a better-written policy.
Permissions boundaries and organization policies are what let a platform team hand
role creation to product teams without handing over the account, and attribute-based
scoping is what keeps a policy correct as the resource set grows. Enumerating ARNs
more carefully does not scale past the point where someone starts pasting `*` to make
the deploy pass.

Capital One (2019) and Uber (2022) are the canonical illustrations of the two halves:
an over-permissioned role reached through a server-side request, and a static
credential found in a script after an MFA-fatigue login.

## References

- `references/verifying-findings.md` — confirm or refute a finding, then lock it
- `references/escalation-paths.md` — the permission combinations that are
  administrative without containing a wildcard, and how boundaries cap them
- `rules/iam_policy_invariants.json`
- `rules/key_rotation_policy.json`
- [AWS IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html).
- [Google Cloud IAM recommender](https://cloud.google.com/iam/docs/recommender-overview).
- [CNCF Kubernetes RBAC good practices](https://kubernetes.io/docs/concepts/security/rbac-good-practices/).
- [NIST SP 800-53 Rev. 5](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final).

Files in this skill

  • SKILL.md8.8 KB
  • references/escalation-paths.md4.7 KB
  • references/verifying-findings.md3.1 KB
  • rules/iam_policy_invariants.json3.3 KB
  • rules/key_rotation_policy.json2.5 KB
  • tests/corpus.json4.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.