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 →
HIGH AI PREVALENCE: HIGH auth.oauth.hardcoded-secret

An OAuth client_secret (or similarly sensitive credential) is being assigned a hard-coded string literal.

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

The moment this lands in git, it is one search away from compromise.

Replace the literal with process.env.OAUTH_CLIENT_SECRET (or your secret manager equivalent) and add the variable to .env.example with a placeholder so contributors know it is required.

GitGuardian 2026 found 28.6M public secrets on GitHub, with Claude Code commits leaking at 2x baseline. This is the most common AI-coding leak.

VULNERABLE
vulnerable.ts
// ruleid: auth.oauth.hardcoded-secret
export const oauthBad = {
  client_id: 'app-prod',
  client_secret: 'sk_live_abc123XYZ789verylong',
};

// ruleid: auth.oauth.hardcoded-secret
export const oauthBad2 = {
  clientId: 'app-prod',
  clientSecret: 'super-secret-value-here-abcdef',
};

// ruleid: auth.oauth.hardcoded-secret
export const config = {
  CLIENT_SECRET: 'GOCSPX-aaaaaaaaaaaaaaaaaaaaaaa',
};
SAFE
safe.ts
// ok: auth.oauth.hardcoded-secret
export const oauthGood = {
  client_id: process.env.OAUTH_CLIENT_ID!,
  client_secret: process.env.OAUTH_CLIENT_SECRET!,
};

// ok: auth.oauth.hardcoded-secret -- placeholder values for docs are fine
export const sample = {
  client_secret: '<your-client-secret>',
};

// ok: auth.oauth.hardcoded-secret -- example placeholder
export const docsExample = {
  clientSecret: 'your-secret-here',
};

// ok: auth.oauth.hardcoded-secret -- obvious test stubs, not a real leak
export const testStub = {
  clientSecret: 'test1234secret',
  client_secret: 'dummy-secret-for-tests',
};

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.hardcoded-secret -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 ↗https://blog.gitguardian.com/the-state-of-secrets-sprawl-2026/ ↗