Skip to content

fix(mcp): serialize dashboard role permissions#41404

Open
hoon-e wants to merge 5 commits into
apache:masterfrom
hoon-e:fix-mcp-dashboard-role-serialization
Open

fix(mcp): serialize dashboard role permissions#41404
hoon-e wants to merge 5 commits into
apache:masterfrom
hoon-e:fix-mcp-dashboard-role-serialization

Conversation

@hoon-e

@hoon-e hoon-e commented Jun 25, 2026

Copy link
Copy Markdown

SUMMARY

Fix MCP dashboard role permission serialization to handle Flask-AppBuilder PermissionView objects safely.

Previously, dashboard role serialization assumed permissions were simple objects with a direct name attribute. FAB role permissions are
often represented as PermissionView objects, where the effective permission name is composed from permission.name and view_menu.name
such as can_read on Dashboard. This could cause MCP dashboard serialization to fail when role permission data was accessed.

This change makes role permission serialization defensive by:

  • supporting direct permission names
  • supporting FAB PermissionView objects
  • handling detached or non-iterable permission relationships safely
  • preserving existing MCP dashboard privacy behavior

Related to #41001

AS-IS

  • MCP dashboard role serialization expected role permissions to expose a simple name.
  • FAB PermissionView objects were not serialized into the expected permission string format.
  • Accessing detached or unavailable permission relationships could raise serialization errors.
  • In the latest dashboard MCP response path, sensitive access-list fields such as roles remain stripped from dashboard output.

TO-BE

  • Role permission objects are serialized defensively.
  • FAB permission/view-menu pairs are represented as strings like can_read on Dashboard.
  • Detached or unavailable permission relationships no longer break serialization.
  • Dashboard MCP privacy behavior is preserved: requesting roles does not expose role data in dashboard list responses.

TESTING INSTRUCTIONS

Verified locally with Docker using the current branch build.

  1. Built and started Superset light Docker stack:
docker compose -f docker-compose-light.yml up --build -d superset-light

2. Started the MCP server from the built image on port 5008.
3. Called the actual MCP HTTP endpoint with FastMCP client and requested dashboard fields including roles:

await client.call_tool(
    "list_dashboards",
    {
        "request": {
            "page": 1,
            "page_size": 3,
            "select_columns": ["id", "dashboard_title", "roles"],
        }
    },
)

Result:

  • MCP call succeeded.
  • No DetachedInstanceError.
  • No role serialization traceback.
  • No Error calling tool.
  • Response returned dashboards successfully.
  • roles was stripped from columns_requested and columns_loaded, matching current MCP dashboard privacy behavior.

Observed response summary:

{
  "count": 3,
  "columns_requested": ["id", "dashboard_title"],
  "columns_loaded": ["id", "dashboard_title"],
  "columns_available_has_roles": false,
  "first_dashboard_keys": ["dashboard_title", "id"]
}

Also verified the tool-search proxy path:

  • search_tools found list_dashboards
  • call_tool successfully invoked list_dashboards

Static validation:

python3 -m compileall -q superset/mcp_service/dashboard/schemas.py tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
git show --check --stat HEAD

ADDITIONAL INFORMATION

This PR does not re-expose dashboard owners or roles in MCP dashboard list responses. Those fields are intentionally stripped by the current MCP privacy policy.

@dosubot dosubot Bot added authentication:RBAC Related to RBAC dashboard:security:access Related to the security access of the Dashboard labels Jun 25, 2026
@bito-code-review

bito-code-review Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #378ac8

Actionable Suggestions - 0
Additional Suggestions - 2
  • tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py - 1
    • Incomplete edge case coverage · Line 139-139
      The test only covers the happy path where both `permission.name` and `view_menu.name` exist. The implementation `_serialize_permission_name` has branching logic that should be validated. Per project guidelines, comprehensive tests should cover success paths, error scenarios, validation failures, and edge cases (rule 11730).
  • superset/mcp_service/dashboard/schemas.py - 1
    • Unusual Exception Pattern · Line 157-158
      The `try/except` around `getattr(role, "permissions", None)` catches `DetachedInstanceError`, but `getattr` typically raises `AttributeError` for missing attributes. This pattern is unusual unless there's a specific SQLAlchemy behavior being handled. Verify this is the correct exception type or consider documenting the edge case.
Review Details
  • Files reviewed - 2 · Commit Range: 0bd7ea3..0bd7ea3
    • superset/mcp_service/dashboard/schemas.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread superset/mcp_service/dashboard/schemas.py
Comment thread tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py Outdated
@netlify

netlify Bot commented Jun 25, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit aee35e9
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a3cb06dba1eb900089d5b4d
😎 Deploy Preview https://deploy-preview-41404--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread superset/mcp_service/dashboard/schemas.py Outdated
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 6.06061% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.42%. Comparing base (e0f3f93) to head (84bbc70).

Files with missing lines Patch % Lines
superset/mcp_service/dashboard/schemas.py 6.06% 31 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41404      +/-   ##
==========================================
- Coverage   64.44%   64.42%   -0.02%     
==========================================
  Files        2655     2655              
  Lines      145491   145524      +33     
  Branches    33585    33589       +4     
==========================================
- Hits        93762    93759       -3     
- Misses      50028    50062      +34     
- Partials     1701     1703       +2     
Flag Coverage Δ
hive 39.23% <6.06%> (-0.02%) ⬇️
mysql 57.97% <6.06%> (-0.03%) ⬇️
postgres 58.04% <6.06%> (-0.03%) ⬇️
presto 40.80% <6.06%> (-0.02%) ⬇️
python 59.47% <6.06%> (-0.04%) ⬇️
sqlite 57.69% <6.06%> (-0.03%) ⬇️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bito-code-review

bito-code-review Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #7d4856

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: 0bd7ea3..aee35e9
    • superset/mcp_service/dashboard/schemas.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@pull-request-size pull-request-size Bot added size/L and removed size/M labels Jun 25, 2026
assert "slug" in data["columns_loaded"]


def test_dashboard_role_serializer_serializes_permission_view_names() -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a short docstring to this new test function describing the serializer behavior it validates. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This is a newly added Python test function and it has no docstring. The custom rule requires new functions to be documented inline, so the suggestion identifies a real violation.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 140:140
**Comment:**
	*Custom Rule: Add a short docstring to this new test function describing the serializer behavior it validates.

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
👍 | 👎

}


def test_dashboard_role_serializer_skips_bad_permission_items() -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a docstring to this new test function so its edge-case intent is explicitly documented. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This is a newly added Python test function and there is no docstring immediately under it. That violates the rule requiring new functions to include docstrings.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 157:157
**Comment:**
	*Custom Rule: Add a docstring to this new test function so its edge-case intent is explicitly documented.

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
👍 | 👎



def test_dashboard_role_serializer_skips_bad_permission_items() -> None:
class DetachedPermission:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a brief class docstring explaining the purpose of this helper class used in the test. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This newly introduced helper class does not have a docstring. The custom rule explicitly requires new classes to be documented inline.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 158:158
**Comment:**
	*Custom Rule: Add a brief class docstring explaining the purpose of this helper class used in the test.

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
👍 | 👎



def test_dashboard_role_serializer_handles_detached_permissions() -> None:
class DetachedRole:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a class docstring to describe why this detached-role test double exists. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This is a newly added helper class inside a test function and it lacks a docstring. That matches the custom rule for new classes needing inline documentation.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 184:184
**Comment:**
	*Custom Rule: Add a class docstring to describe why this detached-role test double exists.

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
👍 | 👎



def test_dashboard_role_serializer_stops_on_detached_permission_iterator() -> None:
class DetachedPermissionIterator:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a short docstring to this iterator helper class to clarify the failure scenario it simulates. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This new helper class also lacks a docstring. Since the rule requires newly added classes to be documented, the suggestion is valid.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
**Line:** 208:208
**Comment:**
	*Custom Rule: Add a short docstring to this iterator helper class to clarify the failure scenario it simulates.

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
👍 | 👎

@bito-code-review

bito-code-review Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #214208

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: aee35e9..84bbc70
    • tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authentication:RBAC Related to RBAC dashboard:security:access Related to the security access of the Dashboard size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants