Repository navigation
Conversation
wak327
requested review from
Lang-Akshay,
brian-hussey,
crivetimihai,
ja8zyjits and
msureshkumar88
as code owners
October 3, 2026 18:19
Author
|
@Lang-Akshay @jonpspri @crivetimihai This PR adds the The recipe does not use the |
wak327
force-pushed
the
chore/6100-make-token-target
branch
3 times, most recently
from
October 8, 2026 08:17
0839697 to
84c353c
Compare
wak327
force-pushed
the
chore/6100-make-token-target
branch
2 times, most recently
from
October 15, 2026 19:43
933cad9 to
04b9a89
Compare
Add a `make token` target. It prints an admin JWT for admin@example.com. The recipe calls `python -m mcpgateway.utils.create_jwt_token --admin` without `--secret` or `--algo`. Settings loads JWT_SECRET_KEY and JWT_ALGORITHM from the environment, then from .env. The token matches the gateway JWT settings, and the secret stays out of argv. USERNAME applies only from the make command line. Windows and many Linux desktop sessions export USERNAME as the OS login name. The target must not use that name as the token subject. EXP applies from the command line or from the environment. The recipe sets LOG_LEVEL to WARNING when the caller does not export LOG_LEVEL. The mcpgateway.config INFO lines then stay off stderr. The target fails with a `make setup` hint when .env is missing. It fails with a `make install-dev` hint when the venv interpreter is missing. Both hints go to stderr. stdout carries only the token, so `export MCPGATEWAY_BEARER_TOKEN=$(make -s token)` works. The `inspector-up` hint and the mcp_inspector comment in docker-compose.yml now point to `make token`. The `inspector-up` hint no longer prints a JWT secret from WEAK_VALUES. The .secrets.baseline change moves the Makefile and docker-compose.yml line numbers. The detect-secrets hook fails on stale line numbers. Closes IBM#6100 Signed-off-by: Waleed Khalid <wak327@gmail.com>
wak327
force-pushed
the
chore/6100-make-token-target
branch
from
October 20, 2026 14:52
04b9a89 to
250edd6
Compare
Signed-off-by: Waleed Khalid <wak327@gmail.com> # Conflicts: # .secrets.baseline
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
🔗 Related Issue
Closes #6100
📝 Summary
Problem
python -m mcpgateway.utils.create_jwt_tokencommand, its flags, and the value ofJWT_SECRET_KEY.inspector-uphint prints--secret my-test-key-but-now-longer-than-32-bytes --algo HS256. That value is inWEAK_VALUES(mcpgateway/_security_constants.py:36). A gateway with a valid configuration does not use that key, so a token from the hint does not authenticate.Root cause
The
inspector-uprecipe hardcodes a sample secret. It does not use the signing settings of the gateway. No wrapper target reads those settings for the developer.Fix
Makefile:422-443adds thetokentarget. The recipe runscreate_jwt_token --username <user> --admin --exp <minutes>with no--secretand no--algo. Settings loadsJWT_SECRET_KEYandJWT_ALGORITHMfrom the environment, then from.env. The token therefore uses the same signing settings as a gateway started from the same shell. The secret stays out of argv.admin@example.com. The default lifetime is 10080 minutes.USERNAMEapplies only from the make command line. Windows and many Linux desktop sessions exportUSERNAMEas the OS login name. That name must not become the token subject.EXPapplies from the make command line or from the environment.LOG_LEVELtoWARNINGwhen the caller does not exportLOG_LEVEL. Themcpgateway.configINFO lines then stay off stderr. The elevated-claims warning from the CLI still prints..envfails with amake setuphint. A missing venv interpreter fails with amake install-devhint. Both hints go to stderr. stdout holds only the token, soexport MCPGATEWAY_BEARER_TOKEN=$(make -s token)works.Makefile:1930changes theinspector-uphint tomake token.docker-compose.yml:2546-2547changes themcp_inspectorheader comment tomake token. The two hints for the inspector flow now match..secrets.baselinemoves the line numbers of the existing allowlisted entries inMakefileanddocker-compose.yml. Without this change the detect-secrets pre-commit hook rewrites the baseline and exits with code 3.tests/unit/test_makefile_token_target.pyadds 10 tests. They cover the help line, theinspector-uphint, the defaults, theUSERNAMEandEXPsources, both failure hints, and an end-to-end run. The end-to-end run patches a copy of.env.examplewithinit_secrets, runsmake -s token, and decodes the token with the.envkey, audience and issuer.Deviations from the recipe in the issue
grepreadsJWT_SECRET_KEYfrom.envand passes--secret--secret; Settings loads the key--algo HS256--algo; Settings loadsJWT_ALGORITHMJWT_ALGORITHMgets a matching token.USERNAME=x EXP=60 make tokenmake token USERNAME=x EXP=60;EXPalso works from the environmentUSERNAMEis the OS login name on many desktops.EXPhas no such collision.JWT_SECRET_KEYis empty.envis missing or the venv interpreter is missingSecurityConfigurationErrorand a remediation hint.$(make -s token).📏 Reviewability
triage🏷️ Type of Change
🧪 Verification
All commands run from the repository root with the project venv interpreter as
python.The branch is rebased onto
mainata211ab7d. After the rebase,.secrets.baselinetakes themainversion, and the pinned detect-secrets pre-commit hook refreshes its line numbers. The diff of.secrets.baselineagainstmainchanges onlyline_numbervalues andgenerated_at.python -m pytest tests/unit/test_makefile_token_target.py -v -p no:cacheproviderpython -m pytest tests/unit/test_makefile_token_target.py tests/unit/test_makefile_rust_targets.py tests/unit/test_issue_6083_compose_cleanup.py tests/unit/test_tls_compose.py tests/unit/test_secret_baseline_ci_decision_workflow.py -p no:cacheprovidermake ruff RUFF_MODE=check TARGET=tests/unit/test_makefile_token_target.pyuv tool run ruff==0.15.20 format --check tests/unit/test_makefile_token_target.pymake black CHECK=1 TARGET=tests/unit/test_makefile_token_target.pymake isort CHECK=1 TARGET=tests/unit/test_makefile_token_target.pymake pylint TARGET=tests/unit/test_makefile_token_target.pyuv tool run interrogate==1.7.0 -vv tests/unit/test_makefile_token_target.pyuv tool run yamllint==1.38.0 -c .yamllint docker-compose.ymlpre-commit run --config .pre-commit-config.yaml --files Makefile docker-compose.yml .secrets.baseline tests/unit/test_makefile_token_target.pydetect-secrets-hook --baseline <copy of .secrets.baseline> --use-all-plugins --fail-on-unaudited -- <every file from git ls-files>with the pinned rev076672a9make -s token EXP=60in a scratch directory with.env.examplepatched bypython -m mcpgateway.scripts.init_secrets --patch-env .env, thenverify_jwt_token()frommcpgateway.utils.verify_credentialswith that.envsub=admin@example.com,is_admin=True,teams=None, lifetime 60 minutesJWT_SECRET_KEYexported with a different value.envkey givesInvalidSignatureError.envmake -s tokenin a scratch directory with an unpatched copy of.env.example, then with an empty.envSecurityConfigurationError: jwt_secret_key: unset placeholder (__REPLACE_ME__) rejectedmake -n inspector-upmake token; no--secreta211ab7dpython -m pytest tests/unit/test_makefile_token_target.py tests/unit/test_makefile_rust_targets.py tests/unit/mcpgateway/utils/test_create_jwt_token.py -p no:cacheproviderpre-commit run detect-secrets --files Makefile docker-compose.yml tests/unit/test_makefile_token_target.pyChecks not run:
make test: the change touches nomcpgateway/source. The table lists the affected test modules.make coverage diff-cover: the changed lines are inMakefile,docker-compose.yml,.secrets.baselineand a test module. diff-cover measures no source lines here.make docker-nuke docker-prod-rust testing-upandmake test-e2e: the change adds a developer Makefile target and changes no gateway runtime path. The gateway token check usesverify_jwt_token()in place of a live gateway.make detect-secrets-scan: the full-tree hook run above uses the same pinned detect-secrets revision.✅ Checklist
make helpline,inspector-uphint,mcp_inspectorcomment📓 Notes (optional)
admin@example.com, as the issue specifies. It does not followPLATFORM_ADMIN_EMAIL. When noadmin@example.comuser exists in the database, the gateway rejects the default token with 401 (mcpgateway/auth.py:2125-2150). Usemake token USERNAME=<platform admin email>in that case. No issue tracks aPLATFORM_ADMIN_EMAILdefault yet, so the "tracked in separate issues" box stays unchecked.-C <other directory>printscd: tests/migration: No such file or directoryon stderr. That message comes from existing Makefile code, not from this change. No issue tracks it yet.