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 →
MEDIUM AI PREVALENCE: MEDIUM auth.oauth.long-token-lifetime

An OAuth token-lifetime field is set to a literal value longer than 24 hours.

Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.

Why this matters

The value of expires_in (or a comparable field) exceeds 86_400 seconds. Long-lived access tokens make every token theft catastrophic because they remain valid for days or weeks; the industry standard is 15-60 minutes for access tokens, paired with a refresh-token rotation flow for longer sessions.

Don't issue access tokens longer than a day. Use refresh tokens with proper rotation (RFC 6749 §6, RFC 9700 §4.14) for "stay logged in" semantics.

VULNERABLE
vulnerable.ts
// ruleid: auth.oauth.long-token-lifetime
export const oauthBad = {
  access_token: 'redacted',
  expires_in: 604800,
};

// ruleid: auth.oauth.long-token-lifetime
export const oauthBad2 = {
  client_id: 'app',
  expiresIn: 2592000,
};

// ruleid: auth.oauth.long-token-lifetime
export const oauthBad3 = {
  tokenLifetime: 86401,
};

declare const config: { expires_in: number };
// ruleid: auth.oauth.long-token-lifetime -- member assignment
config.expires_in = 604800;

// ruleid: auth.oauth.long-token-lifetime -- jsonwebtoken string duration (30 days)
export const jwtOpts = { expiresIn: '30d' };

// ruleid: auth.oauth.long-token-lifetime -- 2 weeks
export const jwtOpts2 = { expiresIn: '2w' };
SAFE
safe.ts
// ok: auth.oauth.long-token-lifetime
export const oauthGood = {
  access_token: 'redacted',
  expires_in: 900,
};

// ok: auth.oauth.long-token-lifetime -- exactly at the threshold (≤ 1 day)
export const oauthBoundary = {
  expiresIn: 86400,
};

// ok: auth.oauth.long-token-lifetime -- short string durations are fine
export const shortJwt = { expiresIn: '15m' };
export const oneDayJwt = { expiresIn: '1d' };
export const hoursJwt = { expiresIn: '12h' };

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.oauth.long-token-lifetime -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc9700#section-4.14 ↗https://datatracker.ietf.org/doc/html/rfc6749#section-6 ↗