Principle of Least Privilege
No "just-in-case" rights. Each access is explicit, justified, expiring, audited. There is no "admin" button — there are precise roles.
Problem
A compromise (stolen cred, hijacked container, RCE) inherits all rights of the affected account. If that account has broad rights (admin, root, super-user, IAM PowerUser), the attacker reaches everything. The cost of an incident scales with the compromised account's perimeter. How to reduce that perimeter by default?
Forces
- Granting a right to "quickly unblock" is tempting and sticks.
- Unused rights are never spontaneously revoked.
- Human and machine accounts often share the same roles, which become over-privileged.
- Regular rights audit has a cost but is the only way to detect drift.
- The principle was stated in 1975 (Saltzer & Schroeder) — its permanence proves its difficulty.
Solution
Every identity (user, service account, IAM role) gets only the permissions strictly required for its current known function. If additional rights are needed temporarily (incident, migration), grant them just-in-time with expiration. Roles are segmented by function (reader, operator, admin), not by person. Regularly audit effective vs used permissions (cf. AWS IAM Access Analyzer, GCP Recommender). Prefer deny-by-default then explicit allow.
Mechanisms
- RBAC — Role-Based Access Control: grant rights to roles, not humans.
- ABAC — Attribute-Based Access Control: decision considers attributes (time, IP, sensitivity).
- JIT access — Just-in-Time: approved temporary elevation, audit log.
- Workload Identity — Kubernetes ServiceAccount, AWS IRSA, GCP Workload Identity — no long-lived credentials on pods.
- Permissions boundary (AWS IAM) — hard ceiling on what a role can do, even if more is granted.
EDI implementation
A multi-tenant EDI hub applies LP everywhere: (a) the Walmart partner's API account can only send AS4 INVOICs and only read its own MDNs; (b) the "parse-edifact" Lambda IAM role has read access to the input S3 bucket but no write right elsewhere; (c) the on-call operator has a "DataOps" role separate from "PlatformAdmin" — can replay a failed message but not modify IAM policies; (d) AS2 credentials (private signing key) are scoped to a single partner — no master key. Consequence: a compromised partner certificate only opens its own flows; a Lambda crash cannot erase archives.
Anti-patterns
- Default "PowerUser" role for all devs — first compromise grants everything.
- Kubernetes service accounts with
cluster-admin— a compromised pod = compromised cluster. - Wildcard
"*"in IAM Action — unbounded right. - No annual rights audit — silent drift.
- Permanent elevation instead of just-in-time — audit log loses meaning.
Related patterns
- Zero Trust Architecture — Least Privilege is pillar 3.
- Defense in Depth — Least Privilege is one layer.
- Secrets Management — implementation on credentials side.
- Bulkhead — equivalent isolation for resilience.
Sources
- Saltzer J., Schroeder M. — The Protection of Information in Computer Systems, Proceedings of the IEEE 63(9), 1975. cs.virginia.edu/~evans/cs551/saltzer/
- NIST SP 800-53 — Control AC-6 "Least Privilege".
- AWS IAM Best Practices — Apply least-privilege permissions. docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html