Free & open · no paywall, ever

IntegrAuth Academy

Identity, security and practical AI — free, from zero. Byte-sized lessons, real diagrams, hands-on labs, zero fluff. Two programs, each with its own exam and certificate.

20 tracks 241 lessons 242 hands-on labs 230+ diagrams 100% free

English is hard? Your browser can translate this page into Tamil, Telugu, Kannada, Malayalam or Hindi. Tech words stay in English so you learn the real names.

How?
  • Chrome on phone: ⋮ menu → Translate
  • Chrome on computer: right-click → Translate to …
  • Edge: the translate icon in the address bar
Identity & API Security Track 3 · Token Security
0/166 lessons read
TOKEN SECURITY · LESSON 7

Claims you can trust

Your app reads a token and personalizes the screen: the plan, the region, a verified phone. Your goal: tell which facts a user can change and which are locked.

Key points
  • Personalize only from signed claims, never from the browser.
  • Cosmetics belong to the user. Entitlements belong to the platform.
  • A typed fact is not proven. A verified fact is.
  • Clear a verified flag when the value changes.

Use only signed claims

A claim is one fact inside a signed token, such as your name, plan or region. The IdP signs the token. So your app can trust the claim without asking a database. Personalize only from signed claims. Never use a query parameter, a header or localStorage. Anything the browser can set, an attacker can set too. For the parts of a token, see the tokens lesson.

Two kinds of profile data

User-writable metadata holds cosmetic things such as theme and language. The user sets them through a self-service API. Platform-controlled metadata holds entitlements such as plan, region and roles. Only a login hook or an admin can write them. Put anything an attacker would like to change on the platform side.

🎨 Cosmetics: owned by the user

Theme, language, display choices. You set them through a self-service endpoint.

🔐 Entitlements: owned by the platform

Plan, region, roles. A login hook sets them from a trusted source such as billing. They decide what you may do.

Think of it like…

A name tag you scribble yourself versus a badge the front desk prints. The door should open only for the printed badge.

Maya's story

Maya sends the preferences API PATCH {tier: "gold"}. The backend answers 403 trust_boundary, because entitlements are platform-only. She can recolor her dashboard. She cannot give herself a paid plan.

AppBackendIdP1 · login → post-login hook3 · PATCH {theme, lang} — cosmetics5 · PATCH {tier: gold} — self-grant2 · token: signed claims (tier·region·theme·lang)4 · 200 saved6 · ✗ 403 trust_boundarypersonalize UI from signed claims only
Figure — The border holds. Cosmetics are saved. The self-given entitlement is refused. The token is the contract: the server decides from the claim, and the screen only shows it.

From "typed" to "proven"

A self-asserted attribute is a fact you simply typed, such as a phone number. Nobody has proven it, so it is not trusted. A verified attribute is one you proved you control. For a phone, you enter a one-time code (OTP) sent to that handset. Then the number moves to platform-controlled data. It appears in the token as the standard claim phone_number_verified. Send 2FA codes, recovery links and payment alerts only to a verified number.

BackendIdPHandset1 · send one-time code3 · save verified phone (platform-owned)4 · refresh token → re-run login hook2 · user enters 6-digit code5 · token: phone_number_verified = truesave self-asserted phone (untrusted)verify code ✓
Figure — From typed to proven. The code proves control of the handset. The number becomes a trusted claim that your APIs can read. Compare enrolling a verified MFA factor.
Watch out

A well-formed string is not proof of control. Clear the "verified" flag the moment the value is edited, and verify again. If you do not, a user swaps in a new number and inherits the old number's trust.

Why it matters

The API decides from the claim. The screen only shows it. Check entitlements on the server at every sensitive call.

Go deeper: naming your own claims

Give your own claims a clear prefix, for example https://claims.yourapp/tier. Then they never clash with standard names.

🧪 Interactive lab — enable JavaScript to play with this one.

🧪 Try it free

Decode and inspect the claims of your own token with ID Token Check.