Skip to main content
Skip to main content
DevelopmentJuly 10, 2026 4 min read

Decode JWT in CI: Debug Tokens Locally

When an integration test fails, the token usually sits in the log. Decoding it locally shows whether the problem is expiry, issuer, or algorithm — before you touch the code.

Decode JWT tokens locally with our JWT Decoder. Your token never leaves your browser.

Why JWTs keep showing up in CI

Integration tests, end-to-end suites, and deployment scripts often need an access token. When a test fails, the token lands in the log output, and the natural next step is to look inside it.

Decoding a JWT is safe: the header and payload are only base64url-encoded, not encrypted. The risk is not decoding — it is pasting the token, or worse, the signing key, into a server-side tool that may log it.

Most token failures in CI trace back to a small set of causes. The token expired while the job sat in the queue, the runner's clock disagrees with the issuer's, or the token was minted for a different environment. Decoding takes under a minute and tells you which one you are looking at.

JWT anatomy in 60 seconds

The three parts are separated by dots, and each one is base64url without padding. That is why a JWT reads as a jumble of letters, digits, and hyphens rather than readable JSON.

PartWhat it containsExample
HeaderAlgorithm and token type"alg": "RS256"
PayloadClaims such as sub, exp, iat, iss"exp": 1780000000
SignatureKeyed digest that verifies integritybase64url-encoded bytes

Note: Only the signature requires the key. Header and payload can always be decoded without any secret.

Decode a CI token without exposing secrets

  1. Copy the token from the CI log, excluding any surrounding secrets or environment lines.
  2. Open the JWT Decoder in your browser.
  3. Paste the token and inspect the header: check alg and kid values.
  4. Inspect the payload: verify exp, iat, iss, and sub against the environment you are debugging.
  5. Compare exp with the current time using the Timestamp Converter if the values look ambiguous.

Warning: Never paste the signing key, client secret, or refresh token into any tool. Decoding the token itself is enough to debug 90% of auth failures.

Common JWT issues you will find in CI

  • Expired token: exp is in the past, often because the test ran longer than the token lifetime
  • Clock skew: the issuing server and the test runner disagree on time
  • Wrong issuer: token minted for a different environment (staging vs production)
  • Algorithm confusion: header alg changed or mismatched with the key type
  • Malformed input: extra whitespace or URL-encoded characters break base64url parsing
  • Audience mismatch: aud does not match what the API expects, so the request is rejected despite a valid signature
  • nbf in the future: the token is not usable yet because its not-before time has not arrived

FAQ

Q.Is decoding a JWT safe?

A.Yes. The header and payload of a JWT are base64url-encoded, not encrypted, so decoding reveals only what was already inside the token. Anyone who holds the token can decode it, which is by design. The real dangers are sharing the token or leaving it in a public log.

Q.Can a decoder verify the JWT signature?

A.No — a decoder has no key, and signature verification requires the signing key or the public key that matches it. What a decoder can do is parse the header and payload so you can check alg, kid, and the claims. For real verification, use your identity provider's validation endpoint or a JWT library configured with the public key.

Q.What should I never paste into a debugging tool?

A.Never paste private keys, client secrets, refresh tokens, or tokens that can access production data. If the payload contains claims you would rather not repeat elsewhere, redact them before pasting, and prefer a client-side decoder whose input never leaves your machine.

Q.Why does exp show up as a plain number?

A.Because exp is a NumericDate: seconds since 1970-01-01 UTC. A value like 1780000000 means nothing at a glance, which is why the JWT Decoder also renders it as a readable date. To compare it with the current time, use the Timestamp Converter or let the tool do the math for you.

References

  • RFC 7519 – JSON Web Token (JWT): https://www.rfc-editor.org/rfc/rfc7519
  • RFC 7515 – JSON Web Signature (JWS): https://www.rfc-editor.org/rfc/rfc7515
  • RFC 8725 – JSON Web Token Best Current Practices: https://www.rfc-editor.org/rfc/rfc8725
  • OWASP – JSON Web Token Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html

Decode a CI token

Header and payload in your browser, read-only, zero upload.

Read the token before blaming the test

Inspect alg, exp, and iss with the JWT Decoder, convert timestamps with the Timestamp Converter, and compare against the environment the test runs in.

Keep signing keys and production tokens out of logs and paste tools entirely.

When I had to chase a token failure that kept breaking a nightly pipeline, decoding the token was the step that ended the guessing. The payload showed an exp that had already passed by the time the queue picked up the job: the token was minted at build time, not at run time, so it died before it was ever used.

decode jwt in cijwt debug ci pipelinejwt decoder onlineinspect jwt token locallyjwt payload viewerjwt exp checkclient-side jwt decodersafe jwt debuggingjwt header payload signaturedecode jwt without secrets