Token X-Ray
What it inspectsToken X-Ray runs a registry of pure analyzers over every open document. Findings surface as diagnostics in the Problems panel, as code lenses above the matching lines (
Issuer recognitionWhen a JWT or OIDC config exposes an
Secret scanning90+ vendor-specific secret rules ship out of the box. Hits report exact byte ranges so VS Code renders them as diagnostics on the precise characters.
Most rules mark a PrivacyEvery decoder, parser, and rule runs locally in the extension host. No tokens, secrets, or document contents are transmitted off the machine. Signature verification uses keys you configure locally — there is no JWKS network fetch. FeaturesInspect any token — claimset viewerThe claimset viewer renders each claim with its registered meaning (RFC 7519 + common public claims), IdP-specific annotations, and a findings banner (red / yellow / blue) at the top. Open it from the
Findings activity-bar viewA dedicated Token X-Ray view container in the activity bar lists every detected token across open documents as an outline — analyzer kind, file:line, decoded sections, and findings. Click any node to reveal the source location.
Diagnostics in the Problems panelAll findings stream into the Problems panel under the
Other surfaces
Commands
The two preview commands are also available as title-bar buttons when the editor language is Suppressing findingsThree layers, in order of precedence (most-specific first): 1. Inline comments
2.
|
| Setting | Default | Purpose |
|---|---|---|
tokenXray.jwt.verifySignature |
false |
Run signature verification in the claimset viewer |
tokenXray.jwt.expectedIssuer |
"" |
If set, also assert iss equals this value |
tokenXray.jwt.expectedAudience |
"" |
If set, also assert aud equals this value |
tokenXray.jwt.keys |
[] |
Verification keys — JWK objects, { pem, alg, kid? }, or { secret, alg, kid? } for HMAC |
tokenXray.secrets.enabled |
true |
Master switch for secret-rule findings |
tokenXray.secrets.exclude |
[] |
Glob patterns to skip secret scanning for (independent of .tokenxrayignore) |
tokenXray.secrets.maxFileSizeBytes |
1048576 |
Skip secret scanning on documents larger than this (1 MiB default) |
tokenXray.secrets.codeActions.enabled |
true |
Enable the Redact / Move-to-.env quick fixes |
tokenXray.respectGitignore |
true |
Merge workspace .gitignore (root + nested) into the ignore set so gitignored files are skipped |
tokenXray.scan.debounceMs |
250 |
Trailing-edge debounce (0–2000 ms) applied to text-change events before re-scanning |
tokenXray.inlayHints.enabled |
true |
Show inline expiry / severity hints next to tokens |
tokenXray.ruleSeverity |
{} |
Per-rule severity overrides (error / warning / info / off) |
tokenXray.debug |
false |
Log scan counts and suppressions to the Token X-Ray output channel |
Example settings.json
A typical setup that verifies JWTs against a known JWKS, dials down the noise on AWS ARN findings, and disables the OpenAI rule entirely:
{
"tokenXray.jwt.verifySignature": true,
"tokenXray.jwt.expectedIssuer": "https://login.microsoftonline.com/<tenant-id>/v2.0",
"tokenXray.jwt.expectedAudience": "api://your-app-id",
"tokenXray.jwt.keys": [
{
"kty": "RSA",
"kid": "your-key-id",
"use": "sig",
"alg": "RS256",
"n": "...base64url-modulus...",
"e": "AQAB"
},
{ "pem": "-----BEGIN PUBLIC KEY-----\nMIIB...\n-----END PUBLIC KEY-----", "alg": "RS256", "kid": "rotated-key" },
{ "secret": "shared-hmac-secret", "alg": "HS256", "kid": "hs-key" }
],
"tokenXray.ruleSeverity": {
"secret.aws.arn": "info",
"jwt.alg.none": "error",
"secret.openai.*": "off"
},
"tokenXray.respectGitignore": true,
"tokenXray.scan.debounceMs": 150,
"tokenXray.secrets.exclude": ["**/fixtures/**", "**/__snapshots__/**"],
"tokenXray.inlayHints.enabled": true,
"tokenXray.debug": false
}
Malformed entries in tokenXray.jwt.keys are surfaced with a one-shot warning toast (with an Open Settings button) and a line in the Token X-Ray output channel; valid entries are loaded silently.
Architecture
The codebase is layered so the analysis core stays pure and testable:
src/
analyzers/ # pure detectors — no vscode imports
jwt/ saml/ samlMetadata/ x509/ csr/ jwk/ sshKey/ pgp/
oauth/ paseto/ basicAuth/ awsSigv4/ httpSignature/
oidcDiscovery/ cookie/ secrets/
core/ # AnalyzerRegistry + pure helpers (scanText, globMatch,
# ignoreFile, severityOverrides, disableComments,
# hover/inlayHints/documentLinks/documentSymbols/findingsTree)
providers/ # vscode glue: diagnostics, code lenses, hovers, semantic tokens,
# inlay hints, document links, document symbols, status bar,
# findings tree, secret code actions, debug output channel
panels/ # webview-based claimset viewer
contexts/ # command registrations
webview/ # React app for the claimset viewer (own workspace)
src/analyzers/** and src/core/** must remain free of vscode imports — Vitest runs them with no mocks, and coverage thresholds are enforced (90% lines, 90% functions, 85% branches).
Build
npm install
npm run build # builds extension + webview workspaces
npm run typecheck # tsc --noEmit
npm run test # vitest run
npm run test:coverage # enforce coverage thresholds
npm run esbuild # bundle the extension (sourcemaps)
npm run deploy # vsce publish
The CI workflow (.github/workflows/vsix-package.yaml) runs typecheck + test before packaging.
Sample fixtures live in /sample (JWTs, certificates, SAML responses, JWKs, cookie headers, secret-bearing text) and double as the test corpus for the analyzers.
How can I help?
If you find Token X-Ray useful, a rating on the Visual Studio Marketplace makes a real difference. Bugs and feature requests are very welcome on the GitHub issue tracker, and pull requests even more so.
This is a personal passion project — sponsoring on GitHub helps keep time carved out for it.


