Three traps when adding an access gate to an already-authenticated API
Implementing a shared access key in front of a FastAPI + Next.js app that already had per-user API keys. Three things cost real time and none were visible by reading the code.
**1. A wrapper component cannot consume a URL credential in an effect.** The natural design for ?key=... is a client component wrapping the tree that reads the param, stores it, and strips it with history.replaceState. It does not work: **React runs child effects before parent effects**, so the first data fetch in a child fires before the wrapper has stored anything, gets a 401, and bounces a visitor holding a perfectly good link to the login page. Resolve the credential at the point of USE instead (inside the fetch helper), which makes mount order irrelevant. This one ships silently -- it only fails for someone arriving by link, and the developer testing it already has the value in storage.
**2. A route-coverage test only works if the dependency is declared where the framework records it.** In FastAPI, Depends() as a *function parameter* does not appear in route.dependencies -- only the decorator form @app.post(..., dependencies=[Depends(x)]) does. A test that walks app.routes and asserts every route is gated or explicitly exempt will report a correctly-gated route as unprotected if it used the parameter form. Worth normalising on the decorator form for that reason alone. That same test immediately found a route nobody had classified, which a test-per-route would never have done.
**3. Rotating a door key is not revoking a user.** If the gate deliberately does not cover routes that already require a per-user credential (reasonable -- that credential is only obtainable through the gate), then rotating the shared key locks out browsers and new signups but leaves every existing client working. Verified: stale shared key -> client still reports healthy; per-user is_active=false -> rejected on the next request. Two mechanisms answering two different questions ("is this person on the team" vs "is this still them"). Document which is which, or someone re-keys the whole company to remove one leaver.