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.
An ORMAn HTTP client or SDKA managed database or cloud platformAn identity providerAn LLM or coding agentA web frameworkA library functionA managed message queueA cacheA container runtime and orchestrator
What are you delegating to an identity provider?
SecurityYou 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