Lesson 17 · Senior auth & authz

Service-to-service auth and the confused deputy problem

Why “internal” is not a magic trust label, how fake JWT contexts work here, and what risk they are trying to control.

Your win: explain why service-to-service auth still needs identity, how FakeJwtContext works, and why the confused-deputy problem is the right mental model for its risk.

In plain English Plain English: an internal call without a human still needs a security identity, or downstream authorization logic has nothing trustworthy to reason about.

Why “internal” is a dangerous word

Teams often say “it’s an internal API” as if that ends the conversation. In practice, it usually begins the real one.

An internal service may still act on behalf of a tenant, still touch restricted data, and still widen scope accidentally. That is why this lesson belongs in the senior part of the course. The risk is not only who called. The risk is what authority the call is allowed to carry forward.

The risk framing The question is not “is this internal?” The question is “what authority is this internal caller allowed to exercise on whose behalf?”

What the repo is trying to preserve

FakeJwtContext synthesizes claims for a small allow-list of internal methods using the request’s organization ID, rather than pretending no identity is needed. That preserves tenant scope while still making internal paths possible.

That detail matters because “no auth” and “synthesized scoped identity” are not the same security posture at all. One erases identity. The other reconstructs enough identity for downstream gates to keep working.

Why the confused deputy lens fits

The confused-deputy problem is the right mental model because an internal service can accidentally exercise authority on behalf of the wrong party or with broader scope than intended. Once you see that, service-to-service auth stops looking like infrastructure trivia and starts looking like delegated authority design.

Backend use case When reviewing an internal endpoint, this is the distinction that tells you whether the design preserved scope or quietly erased it.
Common mistake Treating service-to-service auth as a convenience-only problem instead of a trust-boundary problem where scope can be widened accidentally.
Read this next

The confused deputy lens

Use the classic security concept, then map it onto why the repo synthesizes scoped claims instead of simply dropping identity.

RFC 8693 — Token Exchange
internal/golibs/interceptors/internal_api.go

The practical interview answer

A good answer here sounds like this: “internal traffic still needs a scoped identity, because downstream authorization logic cannot reason safely with no caller model at all.”

That answer lands because it names the risk, the mechanism, and the design intent in one sentence.

Check yourself (from memory)

Q1. The key difference between ignoreAuthEndpoint and FakeJwtContext is…

“No identity” and “synthesized identity” are very different security postures.
Why is the confused-deputy problem the right lens for service-to-service auth?
recall, then click to reveal
Because an internal service can accidentally exercise authority for the wrong tenant or caller unless the delegated identity and scope are pinned explicitly, not assumed implicitly.
Want me to compare safe internal identity synthesis vs unsafe internal trust shortcuts? Ask me.

Sources. RFC 8693; internal API fake-JWT interceptor; repo auth map.