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: HIGH auth.oauth.broad-scope

OAuth scope request includes an over-broad scope such as admin, full_access, *, or repo (entire GitHub access).

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

LLMs default to the widest scope that "works", but every extra scope expands the blast radius if the access token is leaked or replayed.

Request the narrowest scope that satisfies your feature. Examples: use repo:status instead of repo, gmail.send instead of https://mail.google.com/, and scope down to read:user when you only need a profile.

VULNERABLE
vulnerable.ts
// ruleid: auth.oauth.broad-scope
export const badConfig = {
  scope: 'admin',
};

// ruleid: auth.oauth.broad-scope
export const badConfig2 = {
  scopes: ['admin', 'read:profile'],
};

// ruleid: auth.oauth.broad-scope
export const badConfig3 = {
  scope: 'full_access',
};

// ruleid: auth.oauth.broad-scope
export const badConfig4 = {
  scope: 'openid email *',
};

// ruleid: auth.oauth.broad-scope -- standalone "admin" among space-delimited scopes
export const badConfig5 = {
  scope: 'read admin write',
};

// ruleid: auth.oauth.broad-scope -- entire GitHub repo access
export const badConfig6 = {
  scopes: ['repo', 'read:user'],
};

// ruleid: auth.oauth.broad-scope -- full Gmail mailbox
export const badConfig7 = {
  scope: 'https://mail.google.com/',
};
SAFE
safe.ts
// ok: auth.oauth.broad-scope
export const goodConfig = {
  scope: 'openid email profile',
};

// ok: auth.oauth.broad-scope
export const goodConfig2 = {
  scopes: ['read:user', 'repo:status'],
};

// Narrow structured sub-scopes that merely contain a broad word as a segment —
// must not be flagged (regression guards for the substring false positive).
// ok: auth.oauth.broad-scope -- read-only admin sub-scope
export const narrow1 = { scope: 'admin:read' };
// ok: auth.oauth.broad-scope -- Slack channel admin, narrow
export const narrow2 = { scope: 'channels:admin' };
// ok: auth.oauth.broad-scope -- Google calendar narrow scope
export const narrow3 = { scope: 'calendar.all' };
// ok: auth.oauth.broad-scope -- public repos only, narrower than "repo"
export const narrow4 = { scope: 'public_repo' };

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.broad-scope -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc6749#section-3.3 ↗