Least privilege for cloud IAM, without grinding to a halt
Everyone agrees with least privilege and almost nobody implements it, because the strict version blocks work. Here is a version that survives contact with a real team.
Least privilege is one of those principles that everybody endorses and comparatively few implement, for a straightforward reason: the strict version is slow. Someone needs access, the precise permission set is unknown, work stops while it is worked out, and eventually somebody grants a broad role to unblock the team.
That broad role then stays forever, because removing it risks breaking something nobody can fully enumerate.
A workable approach accepts this dynamic and designs around it.
Start broad in development, narrow in production
The costs of a permission mistake differ enormously by environment. In a sandbox, an over-broad role costs very little. In production it can cost a great deal.
So do not apply the same rigour to both. Give developers wide latitude in an isolated development account where the blast radius is contained, and reserve careful scoping for production. This concentrates the effort where it matters and removes the daily friction that causes people to route around the controls entirely.
The prerequisite is genuine separation: different accounts or projects, not different tags within one. Separation is what makes the permissiveness safe.
Derive policies from observed usage
Guessing which permissions an application needs produces either too many or too few. Both providers and tooling offer a better path: run the workload with broad permissions in a non-production environment, record what it actually calls, then generate a policy from that record.
Most major clouds now offer a native version of this, generating a least-privilege policy from access logs over a period. Where a native tool is not available, the logs themselves are sufficient with some scripting.
Two cautions. Run the observation long enough to capture rare paths, which means including at least one month-end or whatever your least-frequent process is. And review the generated policy rather than applying it blindly, because it encodes whatever the workload happened to do, including anything it should not have been doing.
Prefer roles to long-lived credentials
The largest single improvement available in most estates is eliminating long-lived access keys.
Workloads running on cloud infrastructure should assume a role attached to the instance, the container or the function, receiving short-lived credentials automatically. Nothing is stored, nothing can leak from a repository, and nothing needs rotating.
Human access should come through federated identity from your existing identity provider, with short-lived sessions, rather than individual cloud users with permanent keys.
External systems should use workload identity federation where available, which lets a system outside the cloud exchange its own identity token for temporary credentials, again with nothing long-lived to leak.
Where a long-lived key is genuinely unavoidable, treat it as an exception with an owner, a rotation schedule and an expiry date.
Grant to groups and roles, never to individuals
Permissions attached to individual users are unmaintainable at any size. When someone changes team, their permissions do not, because nobody remembers what was granted directly.
Attach permissions to groups or roles that describe a function, and manage membership. Adding and removing people from a group is a routine action that people actually perform; auditing individual grants is not.
Guardrails over grants
Rather than trying to enumerate everything each role may do, it is often more effective to define a smaller set of things nobody may do, and enforce that above the level where individual permissions are granted.
Typical guardrails: no disabling of audit logging, no deleting of log archives, no creating resources outside approved regions, no making storage buckets public, no modifying the guardrails themselves.
These are few in number, easy to agree on, and they hold regardless of how permissive an individual role is. For most organisations a small set of guardrails plus moderately-scoped roles is far more effective than an attempt at perfectly minimal roles that nobody maintains.
Elevate temporarily rather than permanently
Some tasks genuinely need powerful permissions occasionally. Granting them permanently because they are needed monthly is how administrative access proliferates.
Just-in-time elevation, where a person requests elevated access for a bounded period with a recorded reason, converts a permanent grant into an auditable event. Where a native mechanism is not available, a break-glass role with alerting on every use achieves most of the benefit.
Review what is actually used, not what is granted
Most clouds report when a permission or credential was last used. This turns review from an argument into an observation.
Twice a year, look for roles not assumed in ninety days, credentials not used in ninety days, permissions within roles that have never been exercised, and users who have not signed in. Remove or disable them, with a documented way to restore quickly if removing something turns out to be wrong.
The last part matters. Reviews that cannot be undone easily are resisted; reviews that can be reversed in minutes proceed smoothly.
The realistic target
Perfect least privilege is not the goal, because it is unattainable and pursuing it consumes effort better spent elsewhere.
A realistic target is: no long-lived credentials, environments separated so mistakes are contained, permissions attached to groups rather than people, a small set of enforced guardrails, and a periodic review that removes what is demonstrably unused. That is achievable, maintainable, and removes the great majority of real risk.
The same reasoning applies across providers. The catalogue of cloud accounts sets out where each one fits, if you are still deciding which to build on.
For the vendor’s own reference on the services involved here, see the AWS documentation.
Putting any of this into practice needs an account to work in. We stock AWS accounts in sixteen configurations, and the cloud account catalogue sets them beside nine other providers.
Questions people ask
How do I work out which permissions an application actually needs?
Run it with broad permissions in a non-production environment, record what it calls, and generate a policy from that record. Observe long enough to capture rare paths such as month-end processing, and review the result rather than applying it blindly.
What is the single biggest IAM improvement in most estates?
Eliminating long-lived access keys. Workloads should assume roles attached to the instance, container or function; humans should come through federated identity with short-lived sessions.
Are guardrails better than carefully scoped roles?
They are more durable. A small set of things nobody may do, enforced above the level where permissions are granted, holds regardless of how permissive an individual role becomes, and is far easier to maintain than perfectly minimal roles.
How should I run an access review?
Review what is used rather than what is granted. Most clouds report last-used times, so look for roles, credentials and permissions unexercised in ninety days, and make removal easy to reverse so people are willing to act.


