Apache Superset 二次开发实践:接入 AI Agent,并确保数据权限不被绕过
本文记录澈析 BI(Chexi BI)的开发实践。项目基于 Apache Superset 深度开发,增加了 AI Agent、MCP 工具服务、用户权限隔离和独立部署能力。澈析 BI 是独立产品,并非 Apache Software Foundation 官方发行版本。
一、为什么选择 Superset 做 AI BI
传统 BI 的主要操作包括连接数据源、编写 SQL、创建数据集、制作图表和搭建仪表盘。Apache Superset 已经提供了比较完整的数据可视化、SQL Lab、RBAC 和行级权限能力,适合作为智能 BI 的基础平台。
但接入大模型后,问题不只是“让 AI 生成 SQL”。真正需要解决的是:
- AI 能看到哪些数据库和数据集?
- AI 创建的图表属于哪个用户?
- 不同角色能否通过 Agent 绕过页面权限?
- 自然语言查询是否遵守行级安全规则?
- AI 生成错误 SQL 时,如何限制影响范围?
因此,我们没有让 Agent 直接连接业务数据库,而是让它通过 Superset 的业务层和权限体系访问资源。
二、整体架构
浏览器 │ ├── www.chexi.tech:公开产品官网 │ └── app.chexi.tech:登录后的 Superset 应用 │ Nginx / HTTPS │ Gunicorn + Superset │ ┌──────────────┴──────────────┐ │ │ PostgreSQL 元数据库 Redis 缓存 │ └──────── MCP Service ─────── AI AgentMCP 服务作为独立进程运行,使用 FastMCP 提供标准化工具,但复用 Superset 的配置、元数据库、SQLAlchemy 模型和安全管理器。
目前工具覆盖数据集、数据库、图表、仪表盘等资源,例如:
list_datasets 查询用户可见的数据集 query_dataset 查询已授权数据集 generate_chart 创建图表 get_chart_data 获取图表数据 generate_dashboard 创建仪表盘 list_dashboards 查询可见仪表盘三、最重要的原则:AI 不能拥有额外权限
Agent 发起请求后,服务首先验证 JWT 或其他受支持的令牌,再将对应 Superset 用户写入当前请求上下文。
简化后的流程如下:
def handle_agent_request(token: str): user = verify_token_and_resolve_user(token) if not user or not user.is_active: raise AuthenticationError() g.user = user return execute_tool_as_current_user()之后继续使用 Superset 原有的安全能力:
- Flask-AppBuilder RBAC 控制功能权限
DashboardAccessFilter过滤看板ChartAccessFilter过滤图表DatasourceFilter过滤数据集security_manager.raise_for_access()校验具体数据资源- 数据集查询路径继续应用 Row Level Security
这意味着 Agent 只是用户的新操作入口,不是一个拥有管理员权限的超级账号。
需要特别注意:数据集 RLS 与任意 SQL 执行不是同一层安全边界。拥有 SQL Lab 或数据库访问权限的用户,可能具备比数据集查询更大的访问范围。因此,生产环境应限制任意 SQL 工具,并优先让 Agent 使用数据集查询接口。
四、开发认证与生产认证必须分开
开发阶段可以配置固定用户,方便调试:
MCP_DEV_USERNAME = "admin"但这种模式下,所有 MCP 请求都会以同一个用户执行,绝对不能直接用于多用户生产环境。
生产环境应启用 JWT,并校验签名、签发者、受众和过期时间:
MCP_AUTH_ENABLED = True MCP_JWT_ISSUER = "https://auth.example.com" MCP_JWT_AUDIENCE = "superset-mcp" MCP_JWT_ALGORITHM = "RS256" MCP_JWKS_URI = "https://auth.example.com/.well-known/jwks.json" MCP_DEV_USERNAME = None令牌应使用短有效期,并将用户身份映射到真实的 Superset 用户。自动化任务则使用独立服务账号,授予最小权限,而不是复用 Admin。
五、Redis 缓存配置中的真实问题
图表查询会访问DATA_CACHE_CONFIG。即使业务数据库测试连接成功,只要 Redis 认证失败,图表接口仍会返回 500。
我们曾遇到过这个错误:
redis.exceptions.AuthenticationError: invalid username-password pair or user is disabled最终发现部署环境中的 Redis 密码包含了额外引号。推荐统一使用环境变量,并正确编码连接信息:
import os from urllib.parse import quote REDIS_HOST = os.getenv("REDIS_HOST", "127.0.0.1") REDIS_PORT = int(os.getenv("REDIS_PORT", "6379")) REDIS_USER = os.getenv("REDIS_USERNAME", "default") REDIS_PASSWORD = os.environ["REDIS_PASSWORD"] password = quote(REDIS_PASSWORD, safe="") redis_url = ( f"redis://{REDIS_USER}:{password}" f"@{REDIS_HOST}:{REDIS_PORT}/2" ) DATA_CACHE_CONFIG = { "CACHE_TYPE": "RedisCache", "CACHE_KEY_PREFIX": "superset_data_", "CACHE_REDIS_URL": redis_url, }密钥、数据库密码和 Redis 密码都不应写进superset/config.py,更不能提交到 Git。Superset 官方的生产安全文档也明确建议使用环境变量或密钥管理服务,而不是在配置文件中硬编码。Superset 生产安全文档
六、FastMCP 的模块遮蔽问题
另一个比较隐蔽的问题发生在以下启动方式:
cd /home/ubuntu/prod/ai_superset python superset/app.pyPython 会把脚本所在的superset/目录放到模块搜索路径最前面。Superset 自己存在superset/key_value/,它可能遮蔽 FastMCP 依赖的第三方key_value.aio,最终出现:
ModuleNotFoundError: No module named 'key_value.aio' FastMCP server support is not installed依赖实际上已经安装,问题出在模块搜索顺序。正确方式是从项目根目录按模块或 WSGI 应用启动:
python -m superset.app生产环境则使用:
gunicorn \ --bind 127.0.0.1:9000 \ --workers 2 \ --worker-class gthread \ --threads 8 \ --timeout 300 \ "superset.app:create_app()"Superset 官方同样不建议在生产环境使用superset run或 Flask 开发服务器,而应使用 Gunicorn 等 WSGI 服务。Superset 配置文档
七、Nginx 与登录保护
Gunicorn 只监听本机地址:
location / { proxy_pass http://127.0.0.1:9000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }公开官网和数据应用使用不同域名。官网允许搜索引擎抓取,Superset 应用则保持登录保护,并增加:
add_header X-Robots-Tag "noindex, nofollow, noarchive" always;robots.txt和noindex只能控制搜索展示,不能代替鉴权。真正的保护仍然是登录状态、RBAC、资源权限、RLS 和接口层的401/403响应。
八、AI BI 的能力边界
AI Agent 可以降低查询、筛选和可视化配置的操作成本,但不能自动理解企业所有业务口径。
例如,“销售额”可能代表含税金额、实收金额、订单金额或退款后的净额。即使 SQL 语法完全正确,指标定义仍可能错误。
因此,我们把 AI 的定位设计为:
- 帮助用户表达分析需求
- 查找用户有权限的数据集
- 生成候选分析和可视化
- 保留查询与图表配置供用户检查
- 让重要结论经过人工核验
权限控制决定“能不能访问”,业务语义决定“分析得对不对”,两者缺一不可。
九、总结
将 Superset 改造成 AI BI,最难的部分不是调用大模型,而是让 AI 完整继承现有的数据权限、资源权限和审计边界。
这次实践中最关键的经验是:
- Agent 不应直接连接业务数据库。
- 每次工具调用都必须绑定真实用户身份。
- 数据集、图表和仪表盘必须执行对象级权限检查。
- 开发固定用户不能带到生产环境。
- Redis、JWT、数据库凭据必须使用环境变量或密钥服务。
- AI 输出必须保留可验证的 SQL、数据口径和图表配置。
- 公开官网与登录后的数据应用必须分离。
澈析 BI 目前提供智能数据分析、图表与仪表盘、AI Agent 和权限隔离能力。产品介绍与免费试用地址:
澈析 BI - 免费试用的智能 BI 与 AI 数据分析工具
推荐标签:
Apache Superset、BI、AI Agent、MCP、数据可视化、 数据权限、Row Level Security、Python、Flask、Gunicorn