rules:
  - id: auth.oauth.hardcoded-secret
    languages:
      - javascript
      - typescript
    severity: ERROR
    message: |
      An OAuth `client_secret` (or similarly sensitive credential) is being
      assigned a hard-coded string literal. 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.
    # Key matching is case-insensitive (client_secret / clientSecret /
    # CLIENT_SECRET). The value must be a quoted ≥8-char literal, so `process.env`
    # references never match. Env-var template strings, <placeholders>, and
    # obvious doc/test placeholders are excluded to avoid false positives.
    pattern-either:
      - patterns:
          - pattern-regex: |-
              (?i)client[_-]?secret\s*[:=]\s*['"][^'"\s]{8,}['"]
          - pattern-not-regex: |-
              (?i)client[_-]?secret\s*[:=]\s*['"]\$\{?[A-Za-z_]+\}?['"]
          - pattern-not-regex: |-
              (?i)client[_-]?secret\s*[:=]\s*['"]<[^'"]*>['"]
          - pattern-not-regex: |-
              (?i)client[_-]?secret\s*[:=]\s*['"](?:your[-_]|my[-_]|example|placeholder|xxx+|todo|fixme|test|dummy|fake|sample|changeme|redacted)
    metadata:
      oauthlint-rule-id: AUTH-OAUTH-003
      oauthlint-doc-url: https://oauthlint.dev/rules/oauth-hardcoded-secret
      category: security
      cwe: CWE-798
      owasp: API8:2023
      llm-prevalence: HIGH
      references:
        - https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
        - https://blog.gitguardian.com/the-state-of-secrets-sprawl-2026/
