rules:
  - id: auth.go.jwt.hardcoded-secret
    languages:
      - go
    severity: ERROR
    message: |
      A JWT HMAC signing/verification key is hardcoded as a string literal in a
      call to golang-jwt. Anyone who can read the source or git history can
      forge or tamper with tokens, which is a complete authentication bypass.

      Load the secret from the environment or a secret manager instead, e.g.
      `key := []byte(os.Getenv("JWT_SECRET"))` and `token.SignedString(key)`.
      Never commit signing keys to source control.
    # Two shapes are flagged, both requiring the key to be a `[]byte("...")`
    # built directly from a string literal (the `"..."` metavariadic only
    # matches a string-literal AST node): the signing side
    # `tok.SignedString([]byte("x"))`, and a golang-jwt Keyfunc that returns
    # `[]byte("x")` as the verification key. Because the literal must appear
    # in key position, `[]byte(os.Getenv("JWT_SECRET"))` and `[]byte(secret)`
    # (a variable) are NOT matched, only string literals.
    pattern-either:
      - pattern: $TOKEN.SignedString([]byte("..."))
      - patterns:
          - pattern: return []byte("..."), nil
          - pattern-inside: 'func(...) (interface{}, error) { ... }'
    metadata:
      oauthlint-rule-id: AUTH-GO-JWT-003
      oauthlint-doc-url: https://oauthlint.dev/rules/go-jwt-hardcoded-secret
      category: security
      cwe: CWE-798
      owasp: API2:2023
      llm-prevalence: HIGH
      technology:
        - golang-jwt
      references:
        - https://pkg.go.dev/github.com/golang-jwt/jwt/v5#Token.SignedString
        - https://cwe.mitre.org/data/definitions/798.html
