One request, start to finish

J
John Doe
|
Jan 15, 2024
|
5 min read
#react
#javascript
#frontend

I am going to rename one of my own organizations and watch what happens to the click. Giant Context, the website platform I build, is multitenant, one database serving many companies, and I am one of its customers like any other, with an account, organizations, and a settings page. The rename takes about two hundred milliseconds. In that time the request crosses the platform's entire identity and permission system, and the system asks it five questions. I built every one of those gates, and it buys me nothing.

A screenshot of a dark-themed software dashboard showing the settings page for a platform named Giant Context.
The organization settings page, the rename form and the save button, the moment before the click.

What leaves my browser is small:

What leaves the browser

PATCH /api/organizations/{organizationId}Authorization: Bearer eyJhbGciOi…{ "name": "…" }

A method and a path saying what I want to change. A body with the new name. And a token, the long string on the Authorization line, which is about to do a lot of work.

Question one, is this token real

The token came from sign-in. When I logged in this morning, my password went to Google Cloud's Identity Platform, a rented service that stores credentials, runs the sign-in flows, and issues signed tokens. My password never touched my own platform, and it never will. Credential handling is the most attacked, most commoditized job in software, so I buy it from a company that does nothing else, and what my API receives instead is this token, a signed statement saying who I am.

The API checks the signature. Forged or expired, the request dies here, at the cheapest possible point, having touched nothing. My name being on the incorporation papers is not a signature.

Question two, who are you here

The token identifies me to the provider. It does not identify me to the platform. The two are different, and one column joins them. The platform keeps its own users table, its own record of who I am, and the verified token resolves to that internal user id the moment the request clears the boundary. From this point on, the provider is out of the story. Every table that matters, memberships, grants, files, events, references the internal id, which means I could swap identity providers next month and this request would not know.

At this station I am a uuid. So is everyone.

I built every one of those gates, and it buys me nothing.

Question three, do you belong to this organization

The path names an organization, and organizations are the boundary between tenants. Whether I can touch this one is a membership question. A person exists once in the platform's directory and has one membership row per organization, each row carrying the role held there, owner, admin, member, viewer, or collaborator.

I have a membership row for this organization. For one of my test organizations, deleted last month, I no longer do, and if this request named it, the request would end here, and not with a permission error. An organization you have no membership in does not exist for you. That applies to me too.

Question four, may you do this

The membership row settles where I stand. The next question is about the operation itself. A rename changes the organization's own settings, and settings changes are limited by role. Only an owner or an admin of the organization may make them. My membership row says owner, so the write is allowed.

One level deeper, inside an organization's projects and apps, the questions get more granular. Operations there ask for named permissions with a service and an action in the name, email:write to edit an email template, files:delete to remove a file, and roles bundle those permissions so an auditor can always answer who can do what. The pattern is deliberate. The closer a request gets to the tenant boundary, the blunter the instrument. The deeper it goes, the finer the grain.

And the answer is computed now, from the schema, at the moment of this request. It is never read from the token. If I had revoked my own access this morning, my perfectly valid token would change nothing, because a token proves who you are, not what you may do. The distinction between those two is most of what the word IAM, identity and access management, means.

Question five, did it survive

The rename is saved. On its way out, the write produces two more outputs.

First, an event, stamped with my internal user id, recording who changed what. Events outlive memberships, so if this organization someday has owners who are not me, the record of today's rename stays whole.

Second, a notification, because the platform's data layer is reactive:

The notification

{"event":{"action":"refetch","target":"organizations", "payload":{"id":"…","operation":"UPDATE"}}}

Every screen showing this organization receives it and refetches. I keep a second browser window open on the same page when I work on the reactive layer, and the new name appears there before my mouse button comes back up.

Wiring this up yourself

None of this requires building an identity service. The crossing needs two halves, and only one of them is work you own.

The rented half is the identity provider. On Google Cloud, enable Identity Platform, point your client at its sign-in SDK, and verify its tokens on your server with the provider's library. On Azure, the same role is played by AD B2C, which I ran in production for two years. Either way, this half is roughly an afternoon, and most of it is configuration.

The owned half is your own users table, which you were building anyway. Add one column for the provider's id. Resolve every verified token to your internal user id at the API boundary, and key memberships, grants, and events to your id, never theirs. The walls and the roles are ordinary tables plus a check that runs on every request. The hard part is not the machinery. It is holding the line that authorization always comes from the schema and never rides the token.

The crossing, from the inside

Two hundred milliseconds, five questions. Is the token real. Who are you here. Do you belong to this organization. May you do this. And after the write, a record of who did it and a signal to everyone watching.

Every request this platform serves crosses the same stations, a console click, the generated data hooks behind it, an SDK call, an API key. I wrote the gates, I control the keys to the database they run in, and when I push code the pipeline deploys them, and none of that buys my requests a shorter crossing. That is the property to build for. A permission system you can vouch for is one that would stop you too, and mine would. If you are building multitenant software, that is the crossing your every request should make, and the test worth running is whether it holds against the person who built it.

A permission system you can vouch for is one that would stop you too, and mine would.

Have questions?

If you're interested in my work or Giant Context, contact me!

Contact Jesse
Legal
Privacy Policy
Terms of Service
Cookie Policy

© 2026 Giant Context. All rights reserved.

One request, start to finish