← All articles

Using claims without confusing them with permission

Authentication identifies a caller; authorisation decides whether that caller may perform an action. Reading claims should preserve that distinction.

t.Turgay
Using claims without confusing them with permission

Reading JWT fields is easy; establishing that they are trustworthy and sufficient for an operation is a separate task. Authentication answers who is calling, while authorization answers what that caller may do. The claim-based API patterns in my archive are best explained with those boundaries kept distinct.

The sample does not validate a JWT

This .NET 10 console example constructs a ClaimsIdentity in memory. Supplying the authentication type “demo” makes its IsAuthenticated property true. No token is issued, no signature is verified, and no issuer or audience is checked. A locally configured property is not evidence of a successful network authentication exchange.

using System.Security.Claims;
var identity=new ClaimsIdentity(new[]{
    new Claim(ClaimTypes.NameIdentifier,"7"),
    new Claim("permission","article:edit")
},"demo");
var user=new ClaimsPrincipal(identity);
Console.WriteLine(user.Identity?.IsAuthenticated==true);
Console.WriteLine(user.HasClaim("permission","article:edit"));
Console.WriteLine(user.HasClaim("permission","user:delete"));

The outputs are True, True and False. The principal has article:edit but not user:delete. That demonstrates a permission decision after a trustworthy principal has been established. Constructing the same object from arbitrary client-supplied JSON would not be a valid authentication process.

Decoding a token is not validating it

A JWT payload is readable without proving its signature. Acceptance requires signature verification against trusted keys, the expected issuer and audience, and the relevant time conditions. Allowed algorithms and key sources belong to the server's trust configuration, not to a role check in browser code.

A token with invalid exp or nbf values can still be decoded. Clock tolerance should be deliberate. Access tokens, refresh tokens and provider tokens may have different purposes; accepting one token type does not automatically make it a valid credential for another API. Signing keys and connection secrets must remain outside source code.

Make endpoint policy explicit

A real API can define article:edit as a policy requirement and apply it to its edit endpoint. That centralizes the contract instead of scattering ad hoc string comparisons through controllers. Claim names, role-claim type and value mapping must agree with the identity provider. Display names are not stable permission identifiers.

A permission may also be narrower than all records. Ownership, organizational or tenant scope must still restrict the query or mutation. A caller with article:edit should not gain access to another owner's record merely by submitting its ID. Hiding a button does not establish this server-side boundary.

Keep 401 and 403 distinct in the client

An absent or rejected identity normally leads to 401. An accepted identity lacking permission leads to 403. Sending the same user through login again for every 403 often returns them to the same rejection. If refresh is supported, it should be bounded and coordinated rather than launching independent retry loops for every failed request.

The article does not prescribe one browser credential-storage design. Cookie authentication needs appropriate HttpOnly and CSRF handling; bearer-token clients have their own exposure concerns. A localStorage permission or isAdmin value is never proof of server authorization.

Negative tests establish the real contract

After the permitted success path, exercise a missing token, a bad signature, the wrong audience, an expired token and a missing permission. Include a resource ID outside the caller's scope. Diagnose failures with narrow reasons and correlation identifiers rather than full token dumps. A True printed by this console example cannot replace those tests.

JWT bearer validation; Claims-based authorization.

✳ You have reached the end of this orbit.
Explore more articles →
turgay.A little code, a few pixels, a lot of curiosity.© 2026 · Made on Earth ✳