Least privilege
Give every user, key, and service the smallest set of permissions that still lets it do its job, and nothing spare.
See it
What it is
Every credential you create is a future blast radius, and the defaults are generous: the Stripe key that can refund anything, the Postgres user that owns the schema, the CI token with write access to every repo in the org. Least privilege is the habit of trimming each one down to the verbs and resources it actually touches, then adding back only what breaks.
The cheap moment to apply it is when the credential is created, not later. Concrete moves: read-only database roles for analytics, a separate API key per service instead of one shared key, restricted Stripe keys, S3 policies scoped to a single bucket prefix, fine-grained GitHub tokens, and short-lived OIDC credentials in CI instead of a long-lived secret sitting in the settings page.
Where it fails is human: an over-tight policy that breaks a deploy at 2am gets replaced with the wildcard version and never trimmed back. Start slightly loose, log what is actually used (AWS IAM Access Analyzer builds policies from real CloudTrail activity), then tighten from evidence. And do not treat read access as harmless: a token that can read every customer record is a breach waiting for a leak.
Ask AI for it
Audit this codebase and its infra config for least privilege violations, then produce the tightened version. For every credential, IAM role, database user, service account, and OAuth scope, list three columns: what it can do today, what the code actually calls, and the minimal policy covering only those calls. Rewrite each policy scoped to specific actions and specific resource ARNs, buckets, or tables, with no wildcards. Split any shared key into per-service keys, replace long-lived CI secrets with short-lived OIDC, and flag every credential that can currently read across all tenants.