medzuch/jwt-php

Standalone, RFC 7519 / 7797 / 8725-compliant JWT library for PHP 8.3 and 8.4. Framework-agnostic.

Maintainers

Package info

github.com/medzuch/jwt-php

pkg:composer/medzuch/jwt-php

Transparency log

Statistics

Installs: 198

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.2.0 2026-08-19 08:44 UTC

README

CI License: MIT PHP Version

A standalone, modern JWT library for PHP 8.3 and 8.4, built strictly to:

  • RFC 7519 — JSON Web Token
  • RFC 7515 / 7516 / 7517 / 7518 — JWS, JWE, JWK, JWA (underlying JOSE)
  • RFC 7797 — JWS Unencoded Payload Option (supported at the JWS layer; refused at the JWT layer per RFC 7519's update)
  • RFC 8725 — JWT Best Current Practices (BCP 225)

Framework-agnostic by design. Symfony integration lives in the separate medzuch/jwt-bundle package (in design; this library also drops into a custom Symfony authenticator directly — see the cookbook).

Status

Stable — the public API is frozen as of v1.0.0. From 1.0.0 the library follows Semantic Versioning strictly: no incompatible changes to the documented public surface within the 1.x line. What is and isn't covered is spelled out in docs/04 — Public API Surface › Stability promise — in short, everything that document lists (and everything reachable from it not marked @internal). Runs on PHP 8.3 and 8.4; both are covered by CI.

Why another JWT library?

Most PHP JWT libraries predate RFC 8725 and still encourage alg-driven verification — the root cause of the algorithm-confusion attacks the BCP exists to stop. This library:

  • Refuses alg:none and algorithm switching by construction (caller declares an allowlist).
  • Binds every key to its algorithm (one key, one purpose — BCP §3.1).
  • Treats b64:false as forbidden in JWTs (RFC 7519, updated by 7797).
  • Separates JWS, JWT, and Profile layers so that an application-level "access token" is a single type with a single validator, not a permissive bag of claims.
  • Ships with explicit typing (typ enforcement, application/<x>+jwt).
  • Refuses unsafe defaults: no jku/x5u fetching, no compression in JWE, no password-as-HMAC-key.

See docs/ for the full design, threat model, and per-RFC compliance notes.

Quickstart (Docker)

make build                    # build the PHP 8.3 dev image (one-time, ~30s)
make up                       # start the container
make install                  # composer install
make test                     # run the suite
make qa                       # CS + PHPStan level 9 + tests
make qa-84                    # the same gate on PHP 8.4 (second container)

The default dev image is the floor of the supported window (8.3), because that is the version a change breaks by accident; make qa-84 covers the ceiling.

Or without Docker, assuming PHP 8.3 or 8.4 with ext-sodium, ext-openssl, ext-mbstring:

composer install
composer qa

Documentation

Contributing

See CONTRIBUTING.md and docs/08-coding-standards.md.

Security

Security issues: do not open a public issue. See SECURITY.md.

License

MIT — see LICENSE.