TL;DR: JWT handling in Go is a low-level security problem, not just a coding task: the article walks through RS256, JWKS, claim validation, rotation, and common failure points, with examples from WorkOS. The core issue is that signed tokens are only trustworthy when signature enforcement, key management, and claim checks are treated as part of identity governance, not application plumbing.
At a glance
What this is: This guide shows how secure JWT handling in Go depends on verifying signatures, fetching keys from JWKS, and validating claims before trusting a token.
Why it matters: IAM teams need to treat JWT validation as an access-control boundary, because mistakes in token parsing, key selection, or claim enforcement can turn authentication into silent authorisation failure.
Context
JWTs are compact signed containers for identity and access data, but Go leaves more of the validation work to the developer than many higher-level stacks. That makes algorithm enforcement, key lookup, and claim validation part of the security design, not an implementation detail.
The governance problem is that a token can look structurally valid while still being unsafe to trust. For IAM and workload identity programmes, the article is really about making sure the verifier, the key source, and the application’s authorisation logic agree on who the token represents and what it may do.
Key questions
Q: What breaks when JWT claims are checked before signature validation?
A: If claims are checked before signature validation, an attacker can supply a token that looks correct but was never issued by a trusted source. That can produce false positives for roles, audience, or expiry and turn a forged object into accepted identity evidence. The failure is policy without proof, which is not a safe authorisation model.
Q: Why do iss, aud, exp, and nbf matter after a token is signed?
A: A valid signature only proves that someone with the right key created the token. Issuer, audience, and time claims prove that the token was meant for this service, is currently valid, and has not drifted outside its intended trust window. Without them, a legitimate token can still be misused.
A: Security teams should publish new public keys to the JWKS endpoint before retiring old ones, then let resource servers fetch updated keys on demand. This approach avoids manual client updates, reduces operational drift, and keeps JWT verification working during rotation. The core control is consistent key identification with kid values, plus a clear overlap window so signed tokens remain verifiable while systems refresh their key cache.
Q: Should organisations put roles and permissions inside JWT claims?
A: Only when those claims are tightly controlled and treated as part of the authorisation model. Embedding roles or feature flags can reduce lookups, but it also creates policy drift if the application does not re-check that the claim still matches current access rules.
Technical breakdown
How RS256 and JWKS work together in token verification
RS256 uses asymmetric cryptography: one private key signs the token and the public key verifies it. In practice, that means the verifier must either load the correct public key or retrieve it from a JWKS endpoint, then match the token’s kid header to the right key. JWKS matters because it supports rotation without manual redeployment, which is essential when many services verify the same issuer. The article correctly separates key distribution from token trust: a signature proves origin and integrity, but only if the verifier insists on the expected algorithm and key source.
Practical implication: Enforce algorithm allowlists and retrieve verification keys from JWKS instead of embedding or hardcoding public keys.
Why claim validation is part of authorisation, not decoration
JWT claims such as iss, aud, exp, nbf, and iat are not optional metadata in a security sense. They define who issued the token, who it is for, when it becomes valid, and when it expires. In Go, verifying the signature alone is insufficient because a validly signed token can still be replayed, misdirected, or used outside its intended time window. Custom claims then extend that decision into application authorisation, where roles, department, or feature flags determine what the caller may do after authentication succeeds.
Practical implication: Validate issuer, audience, and time-based claims on every request before any business logic runs.
Where JWT handling fails in real applications
The common failure modes are structural: decoding without verification, accepting the wrong signing method, keeping long-lived tokens, or storing sensitive data inside the token payload. JWTs are base64-encoded, not encrypted, so anything placed in the payload is readable wherever the token travels. The article also highlights bearer-token handling as a trust boundary: whoever presents the token is treated as the holder. That means transport protection, header parsing, and safe logging all belong to the identity control plane, not just the API layer.
Practical implication: Treat JWT payloads as visible data, keep access tokens short-lived, and refuse bearer tokens that are not fully verified.
Threat narrative
Attacker objective: The attacker’s objective is to impersonate a legitimate caller and reach protected API or application actions without possessing a valid issuer-approved token.
- Entry occurs when an application accepts a bearer token without enforcing signature verification or the expected signing method, allowing an attacker to supply a token that looks plausible to the parser.
- Credential abuse follows when the verifier trusts the token’s claims or key source without checking issuer, audience, and expiration, turning token acceptance into unauthorised access.
- Impact is reached when the application authorises requests on the strength of an untrusted JWT, exposing protected APIs and downstream resources to impersonation or privilege misuse.
Breaches seen in the wild
- Salesloft OAuth token breach: hackers stole OAuth tokens to access Salesforce data via Salesloft.
Read and download The State of NHI & AI Agent Breach Report 2026, covering 150+ breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
JWT verification is identity governance, not middleware plumbing: The article shows that token parsing only becomes security-relevant when signature enforcement, key provenance, and claim validation are treated as one control. That is the practical boundary between a readable blob and an identity assertion. For practitioners, the governance question is not whether a token exists, but whether it is trustworthy enough to drive access decisions.
Bearer-token trust is a standing-access assumption: The model assumes that whoever presents the token may act until expiry or revocation. That assumption is acceptable only when token lifetime, transport protection, and issuer controls are tightly bounded. The implication is that JWT design has to be evaluated as a privilege window problem, not as a format problem.
JWKS shifts trust from static distribution to managed verification: Centralised key discovery helps reduce manual key handling, but it also makes key selection and rotation part of runtime trust. When kid-based lookup is weakly enforced, the verifier can be pointed at the wrong key or the wrong issuer context. Practitioners should treat JWKS governance as an access control dependency, not just a convenience layer.
Custom claims create authorisation debt if they outgrow their decision model: Roles, department, and feature flags can help avoid repeated database lookups, but they also move business logic into the token. That only works if the application keeps claim semantics tightly aligned with current policy. The broader identity lesson is that authorisation embedded in tokens must be governed with the same discipline as any other access decision.
JWT validation exposes a familiar control gap in a new form: Algorithm enforcement, public-key trust, and claim checks are the three places where teams most often assume the library will do the right thing on its own. It will not. Practitioners should recognise this as a policy enforcement problem inside the application trust boundary, not a library selection problem.
What this signals
JWT validation is a policy enforcement point: Teams that treat token handling as library plumbing usually miss the governance boundary that matters most. The practical shift is to decide which claims are authoritative, which keys are trusted, and what should happen when any of those checks fail.
The same discipline that governs NHI trust windows also applies here: token lifetime, issuer trust, and key rotation determine whether a bearer token is a controlled access artefact or a reusable credential. For IAM and workload identity teams, this makes verifier design a first-class control.
Claim-driven authorisation debt: When applications move roles and permissions into JWTs, they also move decision freshness into the token itself. That means access reviews, revocation, and policy changes can lag behind reality unless the surrounding identity process is designed to absorb that delay.
For practitioners
- Enforce algorithm allowlists Reject any token that does not use the expected signing method, and fail closed if the verifier cannot confirm RS256 or another approved algorithm before decoding claims.
- Validate issuer and audience on every request Check iss, aud, exp, nbf, and iat as part of the request path, not as a separate debug step, so a signed token still has to match the intended application and time window.
- Fetch verification keys from JWKS Use a JWKS endpoint for public-key lookup, and verify that kid selection maps to the current issuer keys instead of accepting a hardcoded or stale PEM file.
- Keep access tokens short-lived Set short exp values for access tokens, and use a separate refresh flow rather than stretching bearer-token lifetime to cover long user sessions.
- Treat token payloads as visible data Never place passwords, secrets, or sensitive personal data in a JWT, because the payload is only base64-encoded and can be read wherever the token is exposed.
Key takeaways
- JWTs only remain trustworthy when verification, issuer trust, audience checks, and expiry checks are enforced together at the application boundary.
- The article shows that key rotation and JWKS-based verification are operational controls, not optional implementation details.
- JWT design choices can turn a signed token into either a tightly governed access artefact or a reusable bearer credential with excessive trust.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 and MITRE ATT&CK address the attack and risk surface, while NIST SP 800-53 Rev 5 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-02 — Secret Leakage | JWT payload and key-handling mistakes can expose bearer credentials and sensitive token data. |
| NHI-04 — Insecure Authentication | The article centres on verifying token authenticity before granting access. | |
| Recommendation — Scan token-handling paths for exposed secrets and prevent JWT payloads from carrying sensitive data. Enforce signed-token verification and reject any JWT that fails issuer, audience, or algorithm checks. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | JWT signing keys, rotation, and verifier trust are authenticator lifecycle concerns. |
| Recommendation — Manage JWT signing material with explicit rotation, distribution, and revocation controls under IA-5. | ||
| MITRE ATT&CK | TA0006 — Credential Access | Stolen or forged tokens are credential-access mechanisms that enable impersonation. |
| Recommendation — Hunt for token theft and forged JWT use as credential-access activity in your detection pipeline. | ||
| NIST CSF 2.0 | PR.AA-05 — Access Permissions, Entitlements and Authorizations | JWT claims directly feed application authorisation decisions. |
| Recommendation — Tie JWT claim validation to PR.AA-05 so access decisions are enforced before any resource is served. | ||
Key terms
- Json Web Token: A JSON Web Token is a compact, signed token that carries claims between systems so they can verify identity or authorization without consulting a central session store. In practice, its safety depends on strict validation of the signature, issuer, audience, expiry, and algorithm before any trust decision is made.
- JWKS: A JWKS, or JSON Web Key Set, is a machine-readable publishing format for public keys used by clients to verify signatures or encrypt tokens. It lets consumers fetch current key material automatically instead of relying on manual distribution, which is critical when keys rotate on a schedule.
- Bearer Token: A bearer token is a credential that grants access to whoever possesses it, without requiring strong proof that the holder is the intended client. In NHI environments, that makes theft and replay the main risk, especially when tokens are long-lived, broadly scoped, or stored in local files.
- Custom Claim: A custom claim is an additional data field inserted into a token beyond the standard registered claims. It lets a security team or application encode business-specific attributes, such as department or office status, that are needed for downstream decisions. The claim must be governed carefully because it can influence access control.
Deepen your knowledge
NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are building or maturing an IAM programme, it is worth exploring.
Published by the NHIMG editorial team on June 7, 2026.
Updated on October 7, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org