Commit Graph

7 Commits

Author SHA1 Message Date
Amin Ghadersohi
6dc0dc02b8 fix(mcp): fix stale patch target in auth tests and update stale docstring
- Use superset.mcp_service.auth.has_request_context as patch target in
  test_mcp_auth_hook_clears_stale_g_user tests; patching flask.has_request_context
  has no effect on the module-level import already bound in auth.py
- Update test_jwt_access_token_skips_api_key_auth docstring to reference
  API_KEY_PASSTHROUGH_CLAIM instead of the legacy _api_key_passthrough name
- Add noqa: BLE001 to broad exception catch in mcp_config.py to document
  that the wide catch is intentional (JWT libs raise many types, secrets guard)
2026-05-14 23:37:33 +00:00
Amin Ghadersohi
9458c25c95 fix(mcp): validate API keys via FastMCP AccessToken and lock down ApiKey perms
Three independent bugs let MCP requests presenting Bearer tokens with the
sst_ prefix authenticate as MCP_DEV_USERNAME without any validation under
streamable-http:

1. _resolve_user_from_api_key read the token from flask.request.headers,
   but the streamable-http transport never pushes a Flask request context
   — has_request_context() was always False, so the function returned
   None before validating, falling through to the dev-user fallback.
   Now reads the token from FastMCP's per-request AccessToken (which the
   CompositeTokenVerifier already populated) and fails closed when the
   key is invalid.

2. CompositeTokenVerifier was only installed when MCP_AUTH_ENABLED=True.
   With FAB_API_KEY_ENABLED=True alone, no transport-level verifier
   existed at all. The factory now builds an API-key-only verifier in
   that case (jwt_verifier=None) that rejects non-API-key Bearer tokens
   at the transport instead of silently accepting them.

3. The pass-through AccessToken was minted with scopes=[], which would
   make FastMCP's RequireAuthMiddleware 403 every API-key request when
   MCP_REQUIRED_SCOPES is non-empty. Pass-through now propagates
   self.required_scopes.

Also addresses Daniel's review comment on superset/security/manager.py:
adds "ApiKey" to ADMIN_ONLY_VIEW_MENUS so the FAB ApiKeyApi PVMs are
gated to Admin instead of leaking to Alpha and Gamma.

Renames the pass-through claim from _api_key_passthrough to the
namespaced _superset_mcp_api_key_passthrough (exported as
API_KEY_PASSTHROUGH_CLAIM) so a custom claim from an external IdP can't
accidentally divert a JWT into the API-key validation path.

Tests updated to mock get_access_token instead of app.test_request_context
(the simulated Flask context was the reason the prior tests passed while
production failed). New tests cover API-key-only verifier mode, scope
propagation on pass-through, and the namespaced-claim isolation.
2026-05-14 23:37:33 +00:00
Amin Ghadersohi
d0b77211fc fix(mcp): add type annotations to test fixtures and parameters
Address code review feedback: add explicit type annotations
to all new test function parameters and fixture return types.
2026-05-14 23:37:33 +00:00
Amin Ghadersohi
11e44ac5bf fix(mcp): wire composite verifier and add ApiKey permission sync
Wire CompositeTokenVerifier into create_default_mcp_auth_factory,
add _api_key_passthrough detection in _resolve_user_from_jwt_context,
create ApiKey permissions in create_custom_permissions, and update
test_auth_api_key with pass-through and non-matching prefix tests.
2026-05-14 23:37:33 +00:00
Amin Ghadersohi
7c4f87615b fix(mcp): correct method name in API key auth (extract_api_key_from_request) (#39437) 2026-04-23 23:33:23 -04:00
Amin Ghadersohi
38fdfb4ca2 fix(mcp): prevent stale g.user from causing user impersonation across tool calls (#38747) 2026-03-30 14:23:46 -04:00
Amin Ghadersohi
811dcb3715 feat(api-keys): add API key authentication via FAB SecurityManager (#37973)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Kamil Gabryjelski <kamil.gabryjelski@gmail.com>
2026-03-24 13:37:26 -04:00