A JWT is configured with an unsecured / none signer, e.g. Configuration::forUnsecuredSigner() or new Signer\None() (lcobucci/jwt), or the 'none' algorithm passed to JWT::encode() / new Key(...) (firebase/php-jwt).
Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.
Why this matters
Unsecured tokens carry no signature, so anyone can mint a token with any claims and it will be accepted (CWE-347). This appears in AI-generated "quick token" and debugging code that then ships.
Use a real signer with a key from configuration: use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; $config = Configuration::forSymmetricSigner( new Sha256(), InMemory::base64Encoded(getenv('JWT_KEY')) );
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.php.jwt.unsecured-signer -- <reason>