33

Least privilege

#
  • practice
  • established
  • fragment

A component gets exactly the permissions its task requires, because the cost of a bug and the cost of a compromise are set not by the component’s intentions but by its capabilities. This is not only about IAM and securityContext: in code, the same principle is a narrow interface. A reporting service handed an OrderReader instead of the whole repository has no means to corrupt an order — neither by malice nor by typo.

The classic statement is in Jerome Saltzer and Michael Schroeder, “The Protection of Information in Computer Systems” (Proceedings of the IEEE, 1975), one of eight design principles: every program and every user of the system should operate using the least set of privileges necessary to complete the job. Their reason is the one above — it limits the damage from an accident or an error — plus a second one that is easy to forget: with fewer privileges, fewer programs need to be audited when a privilege is misused. The same paper gives fail-safe defaults (deny unless granted), which is how least privilege is enforced in practice.

Code example (fragment)
fragment
Go
// Minimum rights per component; in code, these are narrow capability interfaces
type OrderReader interface{ GetOrder(ctx context.Context, id OrderID) (Order, error) }
type OrderWriter interface{ PutOrder(ctx context.Context, o Order) error }

// the report service gets OrderReader; it physically cannot write
Kubernetes
securityContext:
  runAsNonRoot: true
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities: { drop: ["ALL"] }

The layers stack. A nightly export job gets a database role with SELECT on three tables, a storage credential that can write to one bucket prefix, a service account with no Kubernetes API access, and a container that cannot write its own filesystem. If the job is compromised through a dependency (35), the attacker gets read access to three tables and one prefix — not the cluster. Each grant is a line in code under review, not a console click.

Where it costs. Narrow grants break when tasks change, and the usual response — widen to * to unblock a release — is how most over-privileged roles are born. The remedies are generating policies from observed access and reviewing unused permissions, not giving up. Static credentials undermine all of it; short-lived, workload-bound identity (102) is what makes narrow grants practical. For agents the same rule has its own card (49).

Last technical review: 2026-08-04 · Reference · 112 principles