Skip to content

feat(api-keys): add API key authentication via FAB SecurityManager#37973

Merged
aminghadersohi merged 59 commits into
apache:masterfrom
aminghadersohi:amin/ch99414/api-key-auth
Mar 24, 2026
Merged

feat(api-keys): add API key authentication via FAB SecurityManager#37973
aminghadersohi merged 59 commits into
apache:masterfrom
aminghadersohi:amin/ch99414/api-key-auth

Conversation

@aminghadersohi
Copy link
Copy Markdown
Contributor

@aminghadersohi aminghadersohi commented Feb 14, 2026

User description

SUMMARY

Add API key authentication to Superset, enabling programmatic access to all API endpoints using long-lived API keys. No more JWT refresh headaches for CI/CD pipelines, MCP integrations, or automation scripts.

API key auth is implemented at the Flask-AppBuilder layer so the @protect() decorator handles it automatically — zero changes needed in individual API views.

Depends on: dpgaspar/Flask-AppBuilder#2431 (FAB feature branch — all CI green)
Related SIP: #37971

How Authentication Works

Superset supports three authentication methods. API keys slot in alongside the existing ones:

flowchart TD
    A["Incoming API Request
Authorization: Bearer <token>"] --> B{"@protect()
decorator"}
    B --> C{Is resource
public?}
    C -->|Yes| D["✅ Allow"]
    C -->|No| E{"Token starts with
configured prefix?
(e.g. sst_)"}
    E -->|"Yes — API Key path"| F["Validate API Key
1. Lookup by prefix
2. Verify hash
3. Check RBAC"]
    F -->|Valid + access| G["✅ Allow"]
    F -->|Invalid or no access| H["❌ 403"]
    E -->|"No — JWT/Session path"| I{JWT Token?}
    I -->|Yes| J["Verify JWT
+ Check RBAC"]
    J -->|Valid + access| K["✅ Allow"]
    J -->|Invalid| L["❌ 401"]
    I -->|No| M{Session
cookie?}
    M -->|Yes| N["Check RBAC"]
    N -->|Access| O["✅ Allow"]
    N -->|No access| P["❌ 403"]
    M -->|No| Q["❌ 401"]

    style D fill:#22c55e,color:#fff
    style G fill:#22c55e,color:#fff
    style K fill:#22c55e,color:#fff
    style O fill:#22c55e,color:#fff
    style H fill:#ef4444,color:#fff
    style L fill:#ef4444,color:#fff
    style P fill:#ef4444,color:#fff
    style Q fill:#ef4444,color:#fff
Loading

Key point: When an sst_ prefix is detected, it's a deterministic API key auth path — it never falls through to JWT. This avoids confusing error messages.

API Key Lifecycle

sequenceDiagram
    participant User
    participant Superset
    participant DB as Database

    Note over User,DB: 1. Create a key
    User->>Superset: POST /api/v1/security/api_keys/<br/>{ "name": "my-ci-key" }
    Superset->>Superset: Generate random key (secrets.token_urlsafe)
    Superset->>Superset: Hash key (werkzeug.generate_password_hash)
    Superset->>DB: Store hash, prefix, user_id, uuid
    Superset-->>User: { "key": "sst_abc123..." }<br/>⚠️ Shown only once!

    Note over User,DB: 2. Use the key
    User->>Superset: GET /api/v1/chart/<br/>Authorization: Bearer sst_abc123...
    Superset->>Superset: Detect "sst_" prefix
    Superset->>DB: Find keys by prefix
    Superset->>Superset: Verify hash (check_password_hash)
    Superset->>Superset: Check RBAC (has_access)
    Superset->>DB: Update last_used_on
    Superset-->>User: 200 OK + chart data

    Note over User,DB: 3. Revoke when done
    User->>Superset: DELETE /api/v1/security/api_keys/{uuid}
    Superset->>DB: Set revoked_on timestamp
    Superset-->>User: 200 OK

    Note over User,DB: 4. Revoked key rejected
    User->>Superset: GET /api/v1/chart/<br/>Authorization: Bearer sst_abc123...
    Superset->>DB: Find keys by prefix
    Superset->>Superset: Key is revoked → reject
    Superset-->>User: 403 Forbidden
Loading

What's in this PR

Backend:

  • MCP auth updated to use FAB's SecurityManager.validate_api_key()
  • FAB_API_KEY_ENABLED = True and FAB_API_KEY_PREFIXES = ["sst_"] in default config
  • FAB pinned to feature branch with API key support (FAB's create_db() creates the ab_api_key table automatically)

Frontend:

  • API Keys section added to User Info page (/user_info/)
  • ApiKeyList — table with name, prefix, status (Active/Revoked/Expired), last used, revoke button
  • ApiKeyCreateModal — create key with name, shows plaintext once with copy button

Security:

  • Keys hashed with werkzeug.generate_password_hash — no plaintext in DB
  • Prefix-based lookup avoids scanning all keys
  • Keys inherit user's RBAC permissions (Admin sees everything, Gamma sees limited)
  • last_used_on updated on each use for audit trail
  • g._api_key_user = True flag distinguishes API key auth from session/JWT

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Screenshot Description
API Keys section on User Info page
Screenshot 2026-02-17 at 6 18 48 PM

| | Create API Key modal |
Screenshot 2026-02-17 at 6 19 09 PM

| | Key created — shown once with copy button |
Screenshot 2026-02-17 at 6 19 33 PM

| | Active key in list with Revoke button |
Screenshot 2026-02-17 at 6 20 15 PM

| | Revoked key showing status badge |
Screenshot 2026-02-17 at 6 20 31 PM

TESTING INSTRUCTIONS

Prerequisites

# Install FAB feature branch
pip install git+https://github.com/aminghadersohi/Flask-AppBuilder@amin/ch99414/api-key-auth

# Ensure config (already set in this PR's superset/config.py)
# FAB_API_KEY_ENABLED = True
# FAB_API_KEY_PREFIXES = ["sst_"]

# Create table and register permissions
superset db upgrade
superset init

Test 1: Create an API Key

# Get a JWT token
JWT=$(curl -s -X POST http://localhost:8088/api/v1/security/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin","provider":"db","refresh":true}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# Create an API key
curl -s -X POST http://localhost:8088/api/v1/security/api_keys/ \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-test-key"}'

Expected: 200 with key (e.g. sst_abc123...), uuid, name. Save the key — shown only once.

Test 2: Use API Key on Protected Endpoints

curl -H "Authorization: Bearer sst_<YOUR_KEY>" http://localhost:8088/api/v1/chart/
curl -H "Authorization: Bearer sst_<YOUR_KEY>" http://localhost:8088/api/v1/dashboard/
curl -H "Authorization: Bearer sst_<YOUR_KEY>" http://localhost:8088/api/v1/dataset/

Expected: 200 with data on all endpoints.

Test 3: Auth Rejection Scenarios

Scenario Expected
No auth header 401
Authorization: Bearer sst_invalidkey 403 (prefix detected, validation fails)
Authorization: Bearer some_random_jwt 401 or 422 (not an API key, invalid JWT)
Revoked API key 403

Test 4: API Key CRUD

# List keys
curl -H "Authorization: Bearer $JWT" http://localhost:8088/api/v1/security/api_keys/

# Get key info
curl -H "Authorization: Bearer $JWT" http://localhost:8088/api/v1/security/api_keys/<UUID>

# Revoke key
curl -X DELETE -H "Authorization: Bearer $JWT" http://localhost:8088/api/v1/security/api_keys/<UUID>

Test 5: JWT Still Works

curl -H "Authorization: Bearer $JWT" http://localhost:8088/api/v1/chart/

Expected: 200 — JWT and API key auth coexist.

Test 6: RBAC Respected

  1. Create API key for a Gamma user → key inherits Gamma permissions
  2. Access allowed endpoint → 200
  3. Access restricted endpoint → 403

Test 7: UI

  1. Go to /user_info/ → see "API Keys" section
  2. Click "Create API Key" → enter name → key shown with copy button
  3. Copy key → verify it works via curl
  4. Click "Revoke" → confirm → key shows "Revoked" badge
  5. Verify revoked key returns 403

ADDITIONAL INFORMATION

  • Has associated issue: Related SIP: [SIP-202] Proposal for API Key Authentication #37971
  • Required feature flags:
  • Changes UI
  • Includes DB Migration — N/A (table managed by FAB's SecurityManager.create_db())
  • Introduces new feature or API
  • Removes existing feature or API

MCP Tool Testing Results

Tested against running Superset MCP service (localhost:5008) on 2026-03-24:

Tool Request Result
health_check {} {"status":"healthy","service":"Preset MCP Service"}
get_instance_info {} 13 dashboards, 91 charts, 20 datasets, current_user=Amin (Admin)
list_dashboards {"page":1,"page_size":3} Returned 3/13 dashboards
list_charts {"page":1,"page_size":3} Returned 3/91 charts
list_datasets {"page":1,"page_size":3} Returned 3/20 datasets
get_chart_info {"identifier":4} Returned pie chart "Work Location Preference"
execute_sql {"database_id":2,"sql":"SELECT 1 as test_col"} Returned 1 row in 0.13s
generate_explore_link {"dataset_id":19,"config":{...}} Generated explore URL

All tools executed successfully with proper auth context (Admin user).


CodeAnt-AI Description

Add API key management in user settings and let API keys sign in to MCP tools

What Changed

  • The User Info page now shows an API Keys section where users can create keys, copy the key once after creation, and revoke active keys.
  • API keys are listed with their status, creation date, last used date, and key prefix so users can track which keys are still valid.
  • MCP requests can now authenticate with an API key in place of a JWT or dev user, and the error message now tells users how to provide one.
  • API key access is only shown when the new feature flag is enabled.

Impact

✅ Shorter API access setup
✅ Fewer JWT refresh issues for automation
✅ Clearer API key management for users

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@github-actions github-actions Bot added the risk:db-migration PRs that require a DB migration label Feb 14, 2026
@dosubot dosubot Bot added api Related to the REST API authentication Related to authentication change:frontend Requires changing the frontend labels Feb 14, 2026
Comment thread superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx Outdated
Comment thread superset/mcp_service/auth.py Outdated
@github-actions github-actions Bot removed the api Related to the REST API label Feb 14, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 14, 2026

Codecov Report

❌ Patch coverage is 4.09836% with 117 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.39%. Comparing base (7222327) to head (8b6074b).
⚠️ Report is 13 commits behind head on master.

Files with missing lines Patch % Lines
...erset-frontend/src/features/apiKeys/ApiKeyList.tsx 0.00% 55 Missing ⚠️
...rontend/src/features/apiKeys/ApiKeyCreateModal.tsx 0.00% 41 Missing ⚠️
superset/mcp_service/auth.py 5.00% 19 Missing ⚠️
superset-frontend/src/pages/UserInfo/index.tsx 50.00% 2 Missing ⚠️

❌ Your project status has failed because the head coverage (99.85%) is below the target coverage (100.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #37973      +/-   ##
==========================================
- Coverage   65.54%   64.39%   -1.15%     
==========================================
  Files        1820     2535     +715     
  Lines       72868   130442   +57574     
  Branches    23339    30215    +6876     
==========================================
+ Hits        47758    84004   +36246     
- Misses      25110    44972   +19862     
- Partials        0     1466    +1466     
Flag Coverage Δ
hive 40.40% <13.63%> (?)
javascript 65.45% <2.00%> (-0.09%) ⬇️
mysql 61.34% <13.63%> (?)
postgres 61.43% <13.63%> (?)
presto 40.42% <13.63%> (?)
python 63.03% <13.63%> (?)
sqlite 61.05% <13.63%> (?)
unit 100.00% <ø> (?)

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

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review Bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #b5c2de

Actionable Suggestions - 1
  • requirements/base.txt - 1
Additional Suggestions - 5
  • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx - 2
    • Logic Error in Close Handler · Line 71-78
      The handleClose function sets createdKey to null before checking its value, which prevents onSuccess from being called after successful API key creation. This means the parent component won't refresh the API key list as intended.
      Code suggestion
       @@ -71,8 +71,8 @@
      -  const handleClose = () => {
      -    setCreatedKey(null);
      -    setCopied(false);
      -    onHide();
      -    if (createdKey) {
      -      onSuccess();
      -    }
      -  };
      +  const handleClose = () => {
      +    if (createdKey) {
      +      onSuccess();
      +    }
      +    setCreatedKey(null);
      +    setCopied(false);
      +    onHide();
      +  };
    • Missing Error Handling for Clipboard · Line 63-69
      The clipboard write operation lacks error handling. If the Clipboard API fails (e.g., due to permissions or browser limitations), users won't know the copy failed, leading to confusion.
  • superset-frontend/src/features/apiKeys/ApiKeyList.tsx - 3
    • Truncate API key prefix display · Line 142-152
      The key_prefix render appends '...' to the full string, potentially showing long values like 'sk-1234567890...'. Truncate to a fixed length (e.g., 10 chars) for better UX.
      Code suggestion
       diff --git a/superset-frontend/src/features/apiKeys/ApiKeyList.tsx b/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
       index 0000000..0000000 100644
      --- a/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
      +++ b/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
       @@ -142,7 +142,7 @@
              render: (prefix: string) => (
                <code
                  css={css`
                    background: ${theme.colorFillSecondary};
                    padding: 2px 6px;
                    border-radius: 3px;
                  `}
                >
      -          {prefix}...
      +          {prefix.length > 10 ? prefix.substring(0, 10) + '...' : prefix}
                </code>
              ),
            },
    • Specify locale in date formatting · Line 91-91
      Using undefined locale may lead to inconsistent date formatting across browsers; specify 'en-US' for consistency.
    • Replace custom spans with antd Tags · Line 98-130
      Use antd Tag components for status badges to avoid custom CSS and follow best practices from AGENTS.md.
      Code suggestion
       diff --git a/superset-frontend/src/features/apiKeys/ApiKeyList.tsx b/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
       index 0000000..0000000 100644
      --- a/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
      +++ b/superset-frontend/src/features/apiKeys/ApiKeyList.tsx
       @@ -1,7 +1,7 @@
        import { useCallback, useEffect, useState } from 'react';
        import { t, SupersetClient } from '@superset-ui/core';
        import { css, useTheme } from '@apache-superset/core/ui';
      -import { Button, Table, Modal, Tooltip } from '@superset-ui/core/components';
      +import { Button, Table, Modal, Tooltip, Tag } from '@superset-ui/core/components';
        import { useToasts } from 'src/components/MessageToasts/withToasts';
        import { ApiKeyCreateModal } from './ApiKeyCreateModal';
       
       @@ -99,29 +99,15 @@
          const getStatusBadge = (key: ApiKey) => {
            if (key.revoked_on) {
      -      return (
      -        <span
      -          css={css`
      -            color: ${theme.colorError};
      -          `}
      -        >
      -          {t('Revoked')}
      -        </span>
      -      );
      +      return <Tag color="error">{t('Revoked')}</Tag>;
            }
            if (key.expires_on && new Date(key.expires_on) < new Date()) {
      -      return (
      -        <span
      -          css={css`
      -            color: ${theme.colorWarning};
      -          `}
      -        >
      -          {t('Expired')}
      -        </span>
      -      );
      +      return <Tag color="warning">{t('Expired')}</Tag>;
            }
      -    return (
      -      <span
      -        css={css`
      -          color: ${theme.colorSuccess};
      -        `}
      -      >
      -        {t('Active')}
      -      </span>
      -    );
      +    return <Tag color="success">{t('Active')}</Tag>;
          };
       
          const columns = [
Review Details
  • Files reviewed - 6 · Commit Range: 100c366..100c366
    • requirements/base.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.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 requirements/base.txt Outdated
@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 14, 2026

Code Review Agent Run #bb1233

Actionable Suggestions - 0
Additional Suggestions - 1
  • requirements/development.txt - 1
    • Unofficial dependency fork · Line 265-265
      Switching to a personal fork of Flask-AppBuilder introduces supply chain risks, as the code isn't from an official or reviewed source. This could lead to security vulnerabilities or maintenance issues if the fork becomes unavailable. Consider using the official package or contributing the changes upstream.
Review Details
  • Files reviewed - 8 · Commit Range: 100c366..d653271
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.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

@aminghadersohi
Copy link
Copy Markdown
Contributor Author

Addressed all review feedback in d653271:

Fixed:

  • Clipboard error handling (CodeAnt): handleCopyKey is now async with try/catch — shows a danger toast on clipboard failure instead of silently showing "Copied!" on an unhandled promise rejection.
  • has_request_context() guard (CodeAnt): API key extraction now only runs when there's an actual HTTP request context, preventing RuntimeError in MCP internal operations (tool discovery, etc.) that run with only an application context.
  • handleClose ordering (Bito): Moved onSuccess() call before state clearing. While React closures mean the original code wasn't technically buggy (createdKey retains its value in the closure), the new ordering is clearer about intent.
  • antd Tag components (Bito): Replaced custom styled <span> elements with antd <Tag color="error|warning|success"> components for status badges, following Superset's convention of preferring antd components over custom CSS.

Acknowledged (no change needed):

  • Supply chain risk (Bito): The git URL dependency on FAB is temporary during development. Will revert to a standard PyPI version pin once FAB PR #2431 is merged and released.
  • Truncate key prefix (Bito): The key_prefix column is already limited to 16 chars in the database schema, so no truncation is needed in the UI.
  • Specify locale (Bito): Using undefined locale in toLocaleDateString() is intentional — it uses the user's browser locale, which is the correct behavior for an internationalized application.

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 14, 2026

Code Review Agent Run #a32c1b

Actionable Suggestions - 0
Review Details
  • Files reviewed - 8 · Commit Range: d653271..3f7711b
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@aminghadersohi aminghadersohi force-pushed the amin/ch99414/api-key-auth branch from 3f7711b to ede054c Compare February 17, 2026 22:54
Comment thread superset/mcp_service/auth.py Outdated
Comment thread tests/unit_tests/security/api_test.py Outdated
Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review Bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #d57b0d

Actionable Suggestions - 2
Additional Suggestions - 2
  • tests/unit_tests/security/api_test.py - 1
    • Incorrect test expectation · Line 32-32
      The test expects "ApiKeyApi" to be in the set of CSRF-exempt blueprints, but no code defines or exempts an "ApiKeyApi" blueprint. The WTF_CSRF_EXEMPT_LIST in config.py contains endpoint paths for individual views, not blueprint names. This will cause the test to fail. Additionally, the test name "test_csrf_not_exempt" and comment "Test that REST API is not exempt from CSRF" are misleading since the assertion checks the exempt set, which includes SecurityApi (a REST API).
  • superset-frontend/src/pages/UserInfo/index.tsx - 1
    • Missing translation for user-facing text · Line 211-211
      The new 'API Keys' header should use the translation function for consistency with other user-facing strings in the codebase, such as the button labels that already use t().
      Code suggestion
       @@ -211,1 +211,1 @@
      -            header={<DescriptionTitle>API Keys</DescriptionTitle>}
      +            header={<DescriptionTitle>{t('API Keys')}</DescriptionTitle>}
Review Details
  • Files reviewed - 9 · Commit Range: c789fbb..178bfac
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.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 requirements/development.txt Outdated
Comment thread requirements/development.txt Outdated
Copy link
Copy Markdown
Member

@msyavuz msyavuz left a comment

Choose a reason for hiding this comment

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

Looks good aside from small nits. Great feature to have!

Comment thread requirements/base.txt Outdated
Comment thread superset-frontend/src/features/apiKeys/ApiKeyList.tsx Outdated
@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 18, 2026

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 89859b8
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/69c25f7d2ab58a0008845299
😎 Deploy Preview https://deploy-preview-37973--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

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

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 18, 2026

Code Review Agent Run #9ebbfe

Actionable Suggestions - 0
Review Details
  • Files reviewed - 9 · Commit Range: 178bfac..3ca0b56
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@aminghadersohi
Copy link
Copy Markdown
Contributor Author

Note on CI failures: The 2 red checks (check-python-deps and docker-build (lean)) are expected and temporary. Both are caused by the git dependency on the FAB feature branch:

  • check-python-deps — CI re-compiles from pyproject.toml and resolves to flask-appbuilder==5.1.0 (PyPI), which doesn't match our git ref
  • docker-build (lean) — The lean Docker image doesn't have git installed, so it can't clone the git dependency

Both will resolve once the FAB PR is merged and released to PyPI. All other 68 checks pass.

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 19, 2026

Code Review Agent Run #3665ad

Actionable Suggestions - 1
  • requirements/base.txt - 1
    • API key hashing change may invalidate existing keys · Line 123-123
Review Details
  • Files reviewed - 9 · Commit Range: 3ca0b56..5702ce1
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 19, 2026

Code Review Agent Run #433ea6

Actionable Suggestions - 0
Review Details
  • Files reviewed - 9 · Commit Range: 5702ce1..c39dae3
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 19, 2026

Code Review Agent Run #6a6f44

Actionable Suggestions - 0
Review Details
  • Files reviewed - 9 · Commit Range: c39dae3..8ff1c66
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Feb 20, 2026

Code Review Agent Run #b35d42

Actionable Suggestions - 1
  • requirements/development.txt - 1
Review Details
  • Files reviewed - 9 · Commit Range: 8ff1c66..4874208
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-02-14_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ 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

aminghadersohi and others added 19 commits March 24, 2026 05:54
Remove parentheses from @pytest.fixture() decorators and apply
ruff format to fix pre-commit CI failure.
- Mock has_request_context in no-request-context test since CI's app
  fixture may implicitly provide a request context
- Clear MCP_DEV_USERNAME in _disable_api_keys fixture to prevent
  fallthrough to dev user path
- Fix ruff PT001 parentheses on pytest.fixture decorators
- Store copy-status timeout in useRef and clear on unmount to prevent
  state updates on unmounted component
- Clear existing timer before creating new one on repeated clicks
- Migration now creates indexes even when table already exists (e.g.,
  from FAB's create_all()) by checking existing indexes first
The API key secret modal could be dismissed by clicking outside or
pressing Escape, risking permanent loss of the key. Added maskClosable
and closable props to force users to click the Done button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Retrigger CI after playwright infra flake (server failed to start).
DatasetList.listview.test.tsx and FileHandler/index.test.tsx timed out -
unrelated to API key changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change ValueError to PermissionError for invalid/expired API key
  authentication failures so GlobalErrorHandlerMiddleware routes them
  through the "Permission denied" branch instead of "Invalid parameter"
- Fix migration downgrade to only drop indexes (not the table) since
  upgrade handles pre-existing tables created by FAB's create_all()
- Update tests to expect PermissionError
@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Mar 24, 2026

Code Review Agent Run #a5741d

Actionable Suggestions - 0
Additional Suggestions - 2
  • superset/mcp_service/auth.py - 2
    • Docstring order mismatch · Line 30-33
      The docstring lists authentication methods in an order that doesn't match the actual priority in `get_user_from_request()`. The code checks JWT (via `g.user`) first, then API key, then dev user, but the docstring puts API key first. This inconsistency could confuse developers reading the module.
      Code suggestion
       @@ -31,2 +31,2 @@
      -1. API Key authentication via FAB SecurityManager (configurable prefix)
      -2. JWT token authentication (via FastMCP BearerAuthProvider)
      +1. JWT token authentication (via FastMCP BearerAuthProvider)
      +2. API Key authentication via FAB SecurityManager (configurable prefix)
    • Error message order wrong · Line 283-284
      The ValueError message suggests trying API key first, then JWT, then dev user, but the code's priority is the reverse: JWT (via `g.user`) first, then API key, then dev. This mismatch could mislead users troubleshooting auth failures.
      Code suggestion
       @@ -283,2 +283,2 @@
      -            + f"\n\nEither pass a valid API key (Bearer {prefix_example}...), "
      -            "JWT token, or configure MCP_DEV_USERNAME for development."
      +            + f"\n\nEither pass a valid JWT token, API key (Bearer {prefix_example}...), "
      +            "or configure MCP_DEV_USERNAME for development."
Review Details
  • Files reviewed - 11 · Commit Range: a89eac2..0359dad
    • requirements/base.txt
    • requirements/development.txt
    • superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts
    • superset-frontend/src/features/apiKeys/ApiKeyCreateModal.tsx
    • superset-frontend/src/features/apiKeys/ApiKeyList.tsx
    • superset-frontend/src/pages/UserInfo/index.tsx
    • superset/config.py
    • superset/mcp_service/auth.py
    • superset/migrations/versions/2026-03-13_12-00_f1a2b3c4d5e6_add_fab_api_key_table.py
    • tests/unit_tests/mcp_service/test_auth_api_key.py
    • tests/unit_tests/security/api_test.py
  • Files skipped - 1
    • docs/static/feature-flags.json - Reason: Filter setting
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ 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

Add runtime/downtime estimates and downgrade rationale to the module
docstring per SIP-59 requirements.  Give the user_id foreign key an
explicit constraint name (fk_ab_api_key_user_id) for deterministic
naming across database backends.
@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Mar 24, 2026

Code Review Agent Run #a002d3

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 0359dad..b04a415
    • superset/migrations/versions/2026-03-13_12-00_f1a2b3c4d5e6_add_fab_api_key_table.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

aminghadersohi and others added 2 commits March 24, 2026 12:48
FAB's SecurityManager.create_db() already creates ab_api_key via
Model.metadata.create_all(engine) during app initialization — before
Alembic migrations run. No other ab_* table has an Alembic migration.
The migration's `if not table_exists` check would almost always skip.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bito-code-review
Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

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

Labels

authentication Related to authentication change:frontend Requires changing the frontend doc Namespace | Anything related to documentation packages size/XL size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants