Bundle: an application service tagged with an alias the bundle already uses is replaced by the bundle's service
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
Start with HeaderCheckerCompilerPass, ClaimCheckerCompilerPass, and AlgorithmCompilerPass, then trace how their factories register aliases. Check how duplicate aliases from one service differ from aliases claimed by different services, and review the compatibility plan for the 4.3.x and 5.0.x branches. Done means duplicate claims are reported with both service names while repeated tags from the same service remain accepted, with the stated deprecation and exception behavior documented.
Written by the indexing model from the issue text.
Description
Version(s) affected
All released versions (3.4.x, 4.0.x, 4.1.x, 4.2.x) and the 4.3.x and 5.0.x branches; for header checkers since 3.0.6.
Description
HeaderCheckerCompilerPass, ClaimCheckerCompilerPass and AlgorithmCompilerPass emit one add($alias, $service) call per tag. The factory keeps the last service added under an alias, and the passes never check whether the alias is already taken. The application's services are defined before the bundle's, so an application service tagged with an alias that the bundle also uses (exp, iat, nbf, or an algorithm name such as RS256) is replaced by the bundle's own service, and the container compiles without any message. A service tagged by a bundle registered after JoseFrameworkBundle wins instead: the load order decides.
Example: the bundle has no option for the $protectedHeaderOnly argument of its time checkers, so the application declares its own checker:
services:
app.protected_exp_header_checker:
class: Jose\Component\Checker\ExpirationTimeChecker
arguments: { $clock: '@Psr\Clock\ClockInterface', $protectedHeaderOnly: true }
tags:
- { name: 'jose.checker.header', alias: 'exp' }
jose:
checkers:
headers:
api: { headers: ['exp'] }
jose.header_checker.api holds the bundle's ExpirationTimeChecker, whose protectedHeaderOnly() is false: a JWS in a JSON serialization that carries exp only in its unprotected header passes check($jws, 0, ['exp']). Under any other alias, the application's checker is used and that token is refused. Claim checkers behave the same way, and an algorithm service built with other constructor arguments and tagged with its standard name is replaced by the bundle's default instance in every loader, decrypter and builder.
Before 0.2.0 the factories refused an alias that was already registered (The alias "%s" already exists.).
How to reproduce
Boot a kernel with the configuration above and compare $container->get('jose.header_checker.api')->getCheckers()['exp']->protectedHeaderOnly() (false) with the same configuration where the tag alias is exp_protected and the list says ['exp_protected'] (true).
Possible Solution
- Workaround: use an alias of your own, as the documentation does for custom checkers and algorithms, or redefine the bundle's service under its own id (the class name, e.g.
Jose\Component\Checker\ExpirationTimeChecker). - In the three compiler passes, report an alias claimed by two different services, naming both; one service tagged twice with the same alias stays accepted.
- As for #756: a deprecation in 4.3.0 and an exception in 5.0.0, since containers that compile today with a duplicated alias, including deliberate overrides by a later bundle, would otherwise stop compiling.
- Document that aliases are unique, and how to replace a service of the bundle.
Additional Context
Found by the Anthropic OSS Scanner (ANT-2026-635NQ9DS). Companion to #756 (one checker per name in a manager). AlgorithmManager likewise keeps only the last algorithm of a given name, without notice.
- Dominant language
- PHP
- Stars
- 954
- Forks
- 119
- Avg merge
- 48m
- Merged PRs (30d)
- 17
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from web-token/jwt-framework
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
web-token/jwt-framework#757 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 68/100
web-token/jwt-framework#773 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 57/100
web-token/jwt-framework#772 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 55/100
web-token/jwt-framework#771 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
web-token/jwt-framework#770 ·
Maintainers usually reply within 1 day
All issues in web-token/jwt-framework
Similar issues
-
enhancement priority Sales
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
novalo-dev/Prestashop-MCP-Server#201 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Include flows spanning the full report time windowPossibly taken @somethingwithproof claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Cacti/plugin_flowview#306 ·
Maintainers usually reply within 1 day
-
bug origin: upstream priority: low
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
mattytap/Mattytap-Sermons#105 ·
-
priority:low type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
crazy-goat/workerman-bundle#1189 ·
Maintainers usually reply within 1 day