getAuthedUser() is the function every authenticated route calls. It resolves the acting org by a documented precedence, then — for anyone who isn't platform-side — verifies the caller is actually a member of the org the URL asked for. Failure returns null, and callers turn null into 401 Unauthorized.
Also called: 401 unauthorized cross tenant · server-side tenant check · API isolation
- 1Precedence for the acting org: impersonation target (platform-side only), then subdomain, then the user's own metadata org, then the linked session org.
- 2Membership is read from publicMetadata.orgId plus publicMetadata.memberships.
- 3The check only blocks users who HAVE memberships — someone mid-onboarding with none falls through to the onboarding flow instead of being locked out of the very endpoints that would set them up.
- 4A block is logged with the user id, the requested subdomain and their membership list.
- 5Non-owners with no resolvable org get null rather than a default account.
The comment states the failure mode and the three exemptions that must not block, in order. The exemptions are the interesting part: a brand-new user has no org yet, and blocking them here 'would prevent the very flows that set up their first orgId' — a gate that locks out new hires is a gate that gets removed. The silent default is called out separately: previously a miss returned the first account's id, which 'silently dropped other tenants' users onto [that tenant's] data when their session was missing the org claim (a frequent state on the apex host).'
- Client-side or middleware-only enforcement can be bypassed by calling the API directly.
- A session missing its org claim used to fall back to a real account instead of failing.
- An over-broad membership check would strand users who haven't finished onboarding.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →