Engineering
Keep authorization rules out of route handlers
Every authorization bug I've seen had the same shape. The rule was correct in one route handler and slightly wrong in another.
User has a direct grant, OR the user's organization owns the resource.
It's easy to say. But written inline across a dozen handlers, it drifts. Someone forgets a check, someone refactors a query, and nobody notices until an audit (or a customer) does.
One pure function
So we pulled the rule out into one pure function. It takes plain values and returns a boolean, with no database and no mocks. A thin async wrapper fetches the two facts it needs and hands them over.
The null check
One line in that function matters more than the rest: the null check. Without it, a user with no organization and a resource with no organization would match, because null === null is true. That's a cross-tenant leak hiding in a single line. Inside a handler full of await calls, you'd almost never spot it. In a pure function, it's one obvious test case.
The bigger lesson
Keep policy separate from data-fetching. The most security-critical code in the repo is now also the easiest to test, review, and trust.
Where in your codebase is a security rule still buried inside a route handler?