Least Privilege Without Breaking Everything
Everyone agrees with least privilege and almost nobody implements it, because the obvious approach breaks production. Here is an approach that does not.
Least privilege is the principle that an identity should hold exactly the permissions it needs and nothing more. Everyone agrees with it. Very few estates implement it, because the intuitive method — guess a small policy, apply it, see what breaks — breaks things in production.
There is a better order of operations.
Start with the model each platform uses
| Platform | Model | Attached to |
|---|---|---|
| AWS | JSON policies with Allow/Deny on actions and resources | Users, groups, roles |
| Azure | Role definitions assigned at a scope | Users, groups, service principals, managed identities |
| Google Cloud | Roles bound to principals on a resource | Users, groups, service accounts |
| Oracle Cloud | Readable policy statements scoped to compartments | Groups and dynamic groups |
| Alibaba Cloud | RAM policies attached to users and roles | RAM users, roles |
The vocabulary differs; the shape does not. Someone or something is allowed to perform certain actions on certain resources.
The method that works
- Observe first. Turn on the audit log and let it run for two to four weeks under normal load, including a release cycle and a month-end if those matter.
- Generate from evidence. AWS IAM Access Analyzer can generate a policy from CloudTrail history. GCP’s recommender proposes reductions from actual usage. Azure surfaces unused role assignments. Start from what was really called.
- Widen slightly, deliberately. Add the actions you know are needed but were not exercised — disaster recovery, an annual job — rather than leaving them to fail at the worst moment.
- Apply in audit mode where possible, or to a non-production copy first.
- Tighten in stages. Remove the most obviously excessive permissions first. Wide, then narrower, then narrow.
- Keep a break-glass path — a rarely used, heavily monitored, highly privileged role for emergencies.
The observation step is what makes this safe. Without it you are guessing, and guessing is why the previous attempt was abandoned.
Rules that avoid most trouble
- Assign to groups and roles, never to individuals. Personal grants are invisible six months later.
- Prefer roles a workload assumes over keys a workload holds.
- Scope to resources, not just actions.
s3:GetObjecton one bucket is very different from on all of them. - Separate environments. Nothing in development should be able to touch production.
- Beware the wildcard.
*in either actions or resources is where over-permission hides. - Watch privilege escalation paths. Permission to create roles, attach policies or pass a role is effectively permission to grant yourself anything.
That last point is subtle and important. An identity that can modify IAM is not restricted, regardless of what its other permissions say.
Guardrails instead of arguments
Rather than debating every permission, set boundaries that cannot be crossed:
- AWS Service Control Policies at the organisation level — deny whole regions, deny disabling CloudTrail, deny making buckets public.
- Azure Policy — enforce tagging, block public IPs on certain subscriptions, require encryption.
- GCP Organization Policy — restrict which service accounts can be impersonated, disable key creation entirely.
Guardrails are usually easier to agree on than individual permissions, and they hold even when a role is over-granted by mistake.
A review cadence that survives contact with reality
- Monthly: review new identities created in the last month.
- Quarterly: review all human access and remove people who changed teams or left.
- Quarterly: run the platform’s unused-permission report and remove what it flags.
- Annually: review guardrails against how the estate has actually changed.
Quarterly human-access review is the one auditors ask about and the one that most often finds a real problem.
Common questions
Where do I start on an estate with no controls?
Remove admin from anything that is not a person who needs it, enforce MFA, and turn on the audit log. Those three take an afternoon and eliminate most of the risk before any policy work begins.
Are managed roles good enough?
Built-in roles like Contributor or PowerUserAccess are a reasonable starting point and far better than owner-everywhere. They are broader than necessary, so treat them as a first step rather than a destination.
How do I handle contractors?
Time-bound access, scoped to the resources they work on, with an expiry date set at creation. Where the platform supports just-in-time elevation, use it.
Does least privilege slow the team down?
Badly implemented, yes. Implemented from observed usage with a break-glass path, it is mostly invisible — which is the sign it was done correctly.
Where to go next
See API keys and secrets management for the credential side, and audit logging for the evidence this method depends on.