What Are You Delegating?

Every abstraction is a trade: it removes work by making decisions for you. Those decisions are still being made — just not by you, and not visibly. For each abstraction: what it genuinely handles, what remains yours, and the escape hatch.

What are you delegating to an identity provider?
Security
You write
1const session = await auth.signIn({ email, password })
The abstraction handles
  • ✓Password hashing with a sane work factor
  • ✓MFA, passkeys, breach-password detection
  • ✓Rate limiting on credential endpoints
  • ✓Session or token issuance and signing
  • ✓Social login, SSO, the compliance paperwork
Still your responsibility
  • →Authorization — the provider establishes *who*; your code still decides *what they may touch*
  • →Token handling in the browser — HttpOnly, Secure, SameSite, storage location, lifetime
  • →Revocation — a self-contained token outlives the user's logout unless you designed for it
  • →Object-level checks — the user changes an id in the URL; only your code notices
  • →Which database role executes the query — a broad role means one authorization bug reaches every row
Know your escape hatch

When: You need to answer "may this principal do this to this resource" — the provider never had that information.

Drop to: Your own authorization layer: explicit checks at the resource, scoped roles, an audit trail.

Adopting a provider and assuming access control is handled is the most common serious vulnerability in web applications.

Go deeper on this one:One login, all the way down