Lesson 13 · Senior auth & authz

Token exchange, trust boundaries, and identity translation

The senior reading of Shamir: not just “mint a token,” but decide exactly which identity facts are trusted, translated, and re-issued across a boundary.

Your win: explain token exchange as a trust-boundary design, not just a login step, and describe what Shamir is really asserting when it mints a first-party Manabie token.

In plain English Plain English: token exchange is how the platform says, “I trust that you were authenticated there, and I am now translating that into the identity shape I enforce here.”

The beginner reading vs the senior reading

The beginner version of this lesson is: “a user signs in somewhere, and later the system gives them a JWT it can use internally.” That version is not wrong. It is just incomplete.

The senior version is more precise: a boundary is being crossed. An external identity provider proved something. Shamir now has to decide what part of that proof it trusts, what internal user it maps to, what tenant and user-group context it assigns, and what claims it is willing to sign in the repo’s own name.

That is why token exchange matters. It is not a transport trick. It is the point where the platform stops being a passive consumer of outside identity and starts becoming an active author of inside authority.

The mental model External identity proves who authenticated. Shamir decides what that identity means inside this platform.

What question is Shamir really answering?

If you only ask “where does the token come from?”, you will miss the deeper security question. The better question is: what survives the trust boundary?

That is what makes this lesson feel more senior than the earlier auth material. Earlier lessons helped you trace the gates. This lesson asks who is allowed to define the identity that those gates will trust afterward.

What Shamir is actually doing

exchangeVerifiedToken verifies the original token, resolves the user in the repo’s data model, rejects deactivated users, fills a new TokenInfo, and signs a new Manabie JWT. That means the repo is not outsourcing final authorization identity to Firebase or Auth0.

Instead, it is saying: “we saw an externally authenticated identity, we mapped it onto our own user record and our own tenant model, and now we are asserting the claims the rest of the platform should trust.”

Backend use case When a user can log in successfully but still gets the wrong tenant, role, or user-group behavior, this translation step is often where the mismatch was introduced.
Common mistake Treating token exchange like a transparent pass-through. It is not. It is a policy decision about how outside identity maps to inside authority.
Read this next

RFC 8693 + the Shamir flow

Read the general token-exchange pattern, then map it back onto the repo’s exchange path so it becomes concrete.

RFC 8693 — OAuth 2.0 Token Exchange
internal/shamir/transports/grpc/token_reader.go

Why this matters in real reviews and incidents

In a design review, this lesson helps you ask whether an external issuer is being trusted too broadly. In a production incident, it helps you distinguish “the user authenticated correctly” from “the repo translated that identity correctly.” Those are different failure classes, and mature auth debugging depends on separating them.

Check yourself (from memory)

Q1. The most senior description of token exchange here is…

Shamir is not relaying identity untouched; it is translating it into first-party claims.
What does Shamir really assert when it mints a Manabie token?
recall, then click to reveal
That the externally authenticated identity has been mapped onto a valid internal user, and that the repo now asserts the user’s first-party roles, group, and tenant context in a token it signs itself.
Want me to compare “external identity proof” vs “internal authority assignment” step by step? Ask me.

Sources. RFC 8693; Shamir exchange flow; repo auth map.