v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
LOW AI PREVALENCE: LOW auth.jwt.no-issuer

JWT is being verified without checking the iss (issuer) claim.

Why AI tools produce this: AI coding tools rarely emit this on their own, but it still slips into assisted edits.

Why this matters

If your verification key is shared across multiple authorization servers (or even tenants on a single IdP), this lets a token signed by one issuer be accepted by code that was meant to trust another.

Pass { issuer: 'https://your-idp.example.com' } to jwt.verify so that the trust chain is explicit. RFC 7519 §4.1.1 defines the iss claim for exactly this purpose.

VULNERABLE
vulnerable.ts
import jwt from 'jsonwebtoken';

// ruleid: auth.jwt.no-issuer
export function verifyBad(token: string) {
  return jwt.verify(token, process.env.JWT_PUBLIC_KEY!, {
    algorithms: ['RS256'],
    audience: 'example-api',
  });
}

// ruleid: auth.jwt.no-issuer -- 2-arg verify has no options, so no issuer check
export function verifyBad2(token: string) {
  return jwt.verify(token, process.env.JWT_SECRET!);
}
SAFE
safe.ts
import jwt from 'jsonwebtoken';

// ok: auth.jwt.no-issuer
export function verifyGood(token: string) {
  return jwt.verify(token, process.env.JWT_PUBLIC_KEY!, {
    algorithms: ['RS256'],
    audience: 'example-api',
    issuer: 'https://idp.oauthlint.dev',
  });
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.jwt.no-issuer -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 ↗