Concept · Application & cloud security

Least privilege

Give each person, service and job only the access it needs, for only as long as it needs it.

3 minprinciple of least privilegeRBACblast radius

The principle of least privilege says every identity (a person, a service, a CI job, a container, an AI agent) should have only the permissions its task requires, and only for as long as it needs them. You can't prevent every compromise. What you can control is the blast radius: what an attacker can do with the identity they took over.

In practice

WhereToo broadLeast privilege
Cloud IAMAdministratorAccess on the app's roles3:GetObject on arn:aws:s3:::invoices-prod/* only
DatabaseApp connects as the owner/superuserApp user can SELECT/INSERT/UPDATE its tables; migrations use a separate role
KubernetesPod uses a ServiceAccount bound to cluster-adminNamespaced Role with the few verbs it needs; automountServiceAccountToken: false when unused
CIWorkflow token with write access to everythingpermissions: contents: read by default, elevated per job
ContainersRuns as root with all capabilitiesNon-root user, drop: [ALL], read-only root filesystem (namespaces and cgroups)
AI agentsA tool that runs arbitrary SQL or shellNarrow, read-only tools scoped to the current user (the tool-use loop)

The time dimension

Privilege that never expires gets stolen eventually. Prefer:

  • Short-lived credentials issued on demand over long-lived keys. See short-lived credentials with OIDC.
  • Just-in-time elevation for humans: request production access for an hour, with a reason and an audit trail, instead of having it permanently.
  • Regular cleanup: remove unused roles, keys and permissions. Cloud providers can report which granted permissions were never used, so you can trim from real usage instead of guessing.

Getting there without breaking things

  1. Start from nothing and add what's needed, rather than starting from * and planning to tighten later. Later rarely comes.
  2. Separate identities per workload. If five services share one role, each one has the union of all five's permissions.
  3. Separate read from write, and production from everything else.
  4. Use policy as code and review it like any other change. Lint for wildcards like Action: "*" and Resource: "*".
  5. Log every use of high privilege and alert on the unusual ones.

Least privilege is the standard answer to the "E" in STRIDE, and it's what turns a stolen token from an incident into an inconvenience.

Learn it in depth