codeant-ai-for-open-source[bot] commented on code in PR #42297:
URL: https://github.com/apache/superset/pull/42297#discussion_r3717165856


##########
superset/mcp_service/auth.py:
##########
@@ -398,7 +467,9 @@ def check_tool_permission(  # noqa: C901
         # advertises scopes. Tokens/deployments that don't use scopes (API 
keys,
         # scope-less JWTs, dev-mode) fall through to RBAC-only behavior — see
         # ``_token_scope_allows``.
-        if has_permission and not _token_scope_allows(method_permission_name):
+        if has_permission and not _token_scope_allows(
+            method_permission_name, class_permission_name
+        ):
             _log_scope_denial(

Review Comment:
   **Suggestion:** The new scope check is only applied through 
`check_tool_permission`, but `get_schema` performs its own dynamic RBAC check 
and does not call `_token_scope_allows`. Consequently, a scoped token carrying 
an unrelated resource scope can still retrieve schema metadata for any resource 
for which its user has RBAC access, bypassing the intended per-resource 
token/RBAC intersection. Apply the same scope check to dynamic permission paths 
such as `get_schema` before allowing the operation. [incomplete implementation]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Scoped tokens can bypass intended schema scope restrictions.
   - ⚠️ `get_schema` exposes chart, dataset, dashboard, database, or report 
metadata.
   - ⚠️ Token/RBAC intersection is inconsistent across MCP tools.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=12428ba0c2d4497f8990e1ed21d55459&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=12428ba0c2d4497f8990e1ed21d55459&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/auth.py
   **Line:** 470:473
   **Comment:**
        *Incomplete Implementation: The new scope check is only applied through 
`check_tool_permission`, but `get_schema` performs its own dynamic RBAC check 
and does not call `_token_scope_allows`. Consequently, a scoped token carrying 
an unrelated resource scope can still retrieve schema metadata for any resource 
for which its user has RBAC access, bypassing the intended per-resource 
token/RBAC intersection. Apply the same scope check to dynamic permission paths 
such as `get_schema` before allowing the operation.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42297&comment_hash=86b952a954782b6e07599c92dea0cc784c41a73d2c9c950daceff34cdb373426&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42297&comment_hash=86b952a954782b6e07599c92dea0cc784c41a73d2c9c950daceff34cdb373426&reaction=dislike'>👎</a>



##########
superset/mcp_service/composite_token_verifier.py:
##########
@@ -168,32 +181,38 @@ async def verify_token(self, token: str) -> AccessToken | 
None:
         if any(token.startswith(prefix) for prefix in self._api_key_prefixes):
             if self._app is not None:
                 loop = asyncio.get_running_loop()
-                username = await loop.run_in_executor(
+                result = await loop.run_in_executor(
                     None, self._validate_api_key_sync, token
                 )
-                if username is None:
+                if result is None:
                     logger.debug(
                         "API key rejected at transport layer (invalid or 
expired)"
                     )
                     return None
+                username, key_scopes = result
                 logger.debug(
                     "API key validated at transport layer for user=%s", 
username
                 )
                 return AccessToken(
                     token=token,
                     client_id="api_key",
-                    scopes=list(self.required_scopes or []),
+                    # Prefer the key's own scopes over verifier-global
+                    # required_scopes. Empty list = no scopes set = "no scopes
+                    # advertised" back-compat per auth.py's
+                    # _get_token_scopes()/_token_scope_allows().
+                    scopes=key_scopes or list(self.required_scopes or []),

Review Comment:
   **Suggestion:** The empty-key-scope fallback re-advertises 
`self.required_scopes`, so a key with no `ApiKey.scopes` is treated as a scoped 
token whenever global required scopes are configured. That contradicts the 
documented no-scopes behavior in `auth.py`, where an empty scope set means 
RBAC-only authorization, and can unexpectedly deny otherwise RBAC-authorized 
API-key requests. Preserve the empty scope list for unscoped keys rather than 
converting it into global JWT scopes. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ Unscoped API keys can lose RBAC-authorized MCP operations.
   - ⚠️ Behavior changes when `MCP_REQUIRED_SCOPES` is configured.
   - ⚠️ API-key scope semantics contradict documented back-compat behavior.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=d85215dfa34b4bd5beaca7972359a18c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=d85215dfa34b4bd5beaca7972359a18c&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/composite_token_verifier.py
   **Line:** 203:203
   **Comment:**
        *Logic Error: The empty-key-scope fallback re-advertises 
`self.required_scopes`, so a key with no `ApiKey.scopes` is treated as a scoped 
token whenever global required scopes are configured. That contradicts the 
documented no-scopes behavior in `auth.py`, where an empty scope set means 
RBAC-only authorization, and can unexpectedly deny otherwise RBAC-authorized 
API-key requests. Preserve the empty scope list for unscoped keys rather than 
converting it into global JWT scopes.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42297&comment_hash=875c033e7cbc198e7006cb4daf6f1e071cde7298825798a25f85394fff0ebae6&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42297&comment_hash=875c033e7cbc198e7006cb4daf6f1e071cde7298825798a25f85394fff0ebae6&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to