Tufin MCP服务器-开源社区项目

引言
欢迎来到Tufin MCP(多控制器协议)服务器项目!这项开源计划旨在为Tufin用户提供一个强大的工具,以弥合Tufin强大的API(SecureTrack和SecureChange)与现代人工智能开发工作流程之间的差距。
通过使用基于角色的访问控制(RBAC)通过安全、标准化的REST API公开Tufin功能,该服务器允许您轻松地将Tufin数据和操作集成到自定义脚本、应用程序和AI代理中(如Cursor、ChatGPT actions、Ollama等中运行的那些)。
这是一个社区驱动的项目。 我们鼓励捐款!无论是增加新的端点覆盖率、提高安全性、增强客户端库还是修复错误,您的输入都是有价值的。请检查 贡献 有关更多详细信息,请参阅第节。
在GitHub上查找项目存储库:
为什么使用这个?
- 简化人工智能集成: 在Tufin现有的API之上提供了一个现代的REST API层,使其更容易与人工智能工具、聊天机器人和自动化脚本集成。
- 集中控制: 从一个地方管理Tufin访问和身份验证。
- 增强的安全性: 在Tufin的身份验证之上添加API密钥和基于角色的访问控制。
- 可扩展性: 旨在扩展以覆盖更多的Tufin API和潜在的其他安全平台。
- 未来潜力: 旨在支持较新的TufinAPI(如GraphQL)和批量操作(例如,从文件添加设备)等功能,这些功能可以通过直接的API调用变得复杂。
概述
该服务器充当Tufin API(目标为v25.1)的安全代理和抽象层。
主要特点:
- 标准REST/JSON API接口(通过OpenAPI记录)。
- 集中式Tufin身份验证(使用通过环境变量配置的基本身份验证)。
- MCP客户端的API密钥验证(使用bcrypt对密钥进行哈希)。
- 可配置的基于角色的访问控制(管理员、票务管理器、用户)。
- 关键SecureChange和SecureTrack操作(票务、设备、拓扑)的端点。
- 带请求ID的结构化JSON日志记录。
- 基于IP的速率限制。
- 基本Python客户端库。
- Docker支持。
入门指南
先决条件
- Python 3.8+
- 访问正在运行的Tufin SecureTrack和SecureChange实例(兼容v25.1)。
- Docker(如果通过容器运行)。
- Git。
安装
- 克隆存储库:
git clone https://github.com//tufin-mcp.git # ** Replace URL **
cd tufin-mcp- 创建并激活虚拟环境:
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`- 安装依赖项:
pip install -r requirements.txt配置
配置是通过环境变量或 .env 项目根目录中的文件。
- 创建
.env文件: 复制.env.example(如有提供)或创建.env手动。
- 设置所需变量:
# Server Settings
MCP_PORT=8000
LOG_LEVEL="INFO" # DEBUG, INFO, WARNING, ERROR
# Tufin Connection (REPLACE with your details)
TUFIN_SECURETRACK_URL="https://your-securetrack-host"
TUFIN_SECURECHANGE_URL="https://your-securechange-host"
TUFIN_USERNAME="your_tufin_username"
TUFIN_PASSWORD="your_tufin_password"
TUFIN_SSL_VERIFY="True" # Set to False only if absolutely necessary (insecure!)
TUFIN_API_TIMEOUT="30.0" # Timeout for Tufin API calls in seconds
# --- Development API Keys (Insecure - For Dev/Test Only!) ---
# For the default In-Memory secure store, provide initial RAW keys and roles via this JSON string.
# The server will HASH the keys on startup and store them in memory.
# DO NOT USE PRODUCTION KEYS HERE.
DEV_API_KEYS='[{"key":"admin_key_abc", "role":"admin"}, {"key":"manager_key_xyz", "role":"ticket_manager"}, {"key":"user_key_123", "role":"user"}]'SSL验证说明(TUFIN_SSL_VERIFY): 默认情况下,服务器会尝试验证Tufin实例的SSL证书(TUFIN_SSL_VERIFY="True").将其设置为 "False" 禁用验证,这对于使用自签名证书的环境可能是必要的,但它是 生产高度不安全 因为它将连接暴露于中间人攻击。如果使用内部CA,请考虑配置底层系统或提供自定义CA包路径(需要修改代码)。
生产安全说明: API密钥是 把……弄糟 使用bcrypt。默认值 InMemorySecureStore 从加载原始密钥 DEV_API_KEYS 只为发展.为了生产,你 必须:
1. 替换 InMemorySecureStore 在……里面 src/app/core/secure_store.py 使用安全数据库或秘密管理器(例如HashiCorp Vault)的实现。 1. 实现用于管理API密钥的安全进程/端点(生成、存储哈希+角色、撤销)。 1. 不要使用 DEV_API_KEYS 在生产中。
运行服务器
地方发展(乌维科恩)
# From the project root directory
uvicorn src.app.main:app --reload --port ${MCP_PORT:-8000}- 这
--reload标志允许在代码更改时自动重新加载。 - 使用中定义的端口
.env或默认为8000。
Docker容器
- 塑造形象:
# From the project root directory
docker build -t tufin-mcp-server:latest .- 运行容器:
docker run --rm -d \
--name tufin-mcp \
--env-file .env \
-p ${MCP_PORT:-8000}:${MCP_PORT:-8000} \
tufin-mcp-server:latest- 从本地加载环境变量 .env 文件。 - 将主机端口映射到容器端口(由定义 MCP_PORT 或默认值8000)。
- 访问:
http://localhost:${MCP_PORT:-8000}
- 日志:
docker logs tufin-mcp(-f跟随)
- 停止:
docker stop tufin-mcp
测试
此项目使用 pytest 用于测试。
- 安装测试依赖项:
pip install -r requirements-dev.txt- 运行测试:
# From the project root directory
pytest- 您可以运行特定文件: pytest tests/api/v1/test_endpoints.py - 使用 -v 对于详细输出: pytest -v - 使用 -k 按名称筛选测试: pytest -k list_devices
- 测试覆盖率(可选):
安装 pytest-cov (pip install pytest-cov)并运行:
pytest --cov=src/app --cov-report=term-missingAPI使用
认证
将生成的API密钥传递到 X-API-Key 除以下请求外的所有请求的HTTP标头 /health.
授权(RBAC)
在密钥创建过程中,访问由分配给API密钥的角色控制(使用安全生产流程或通过 DEV_API_KEYS 发展)。每个端点的允许角色在中配置 src/app/core/config.py 在...之下 ENDPOINT_PERMISSIONS.
- 角色:
admin,ticket_manager,user. - 在没有所需权限的情况下尝试操作会导致
403 Forbidden.
配置终结点权限:
这 ENDPOINT_PERMISSIONS 字典在 src/app/core/config.py 定义哪些角色可以访问哪些逻辑动作(权限ID)。例子:
# src/app/core/config.py
ENDPOINT_PERMISSIONS: Dict[str, List[UserRole]] = {
"list_devices": [UserRole.ADMIN, UserRole.TICKET_MANAGER, UserRole.USER],
"get_device": [UserRole.ADMIN, UserRole.TICKET_MANAGER, UserRole.USER],
"create_ticket": [UserRole.ADMIN, UserRole.TICKET_MANAGER],
# ... other permissions ...
}- 为什么采用这种方法? 这将访问控制策略集中在一个地方,使查看和修改权限变得容易,而无需更改端点代码本身。
- 它是如何工作的: 每个API端点路由都使用
require_permission("permission_id")附属国。此依赖关系检查与用户验证的API密钥关联的角色是否存在于为该特定密钥定义的列表中permission_id在ENDPOINT_PERMISSIONS字典。 - 定制: 您可以通过修改以下列表轻松自定义访问权限
UserRole任何给定权限ID的枚举直接位于config.py。添加新端点时添加新的权限ID。
速率限制
应用基于IP的速率限制(默认值:60/分钟)。超出限制会导致 429 Too Many Requests.
端点概述
API结构定义于 openapi.yaml。如果规范由应用程序提供,您可以直接浏览此文件或使用Swagger UI等工具(需要添加静态文件服务 main.py).
当前终结点摘要:
GET /health:健康检查。POST /api/v1/tickets:创建SecureChange票证。GET /api/v1/tickets:列出SecureChange票证(支持按以下方式过滤status).GET /api/v1/tickets/{ticket_id}:获取特定的SecureChange票证。PUT /api/v1/tickets/{ticket_id}:更新安全更改票证。GET /api/v1/devices:列出SecureTrack设备(支持按以下方式筛选status,name,vendor).GET /api/v1/devices/{device_id}:获取SecureTrack设备详细信息。POST /api/v1/devices/bulk:添加一个或多个设备(需要特定于供应商device_data在请求正文中)。POST /api/v1/devices/bulk/import:将受管设备(DG、ADOM、上下文等)导入现有管理设备。GET /api/v1/topology/map:获取SecureTrack拓扑图。POST /api/v1/topology/query:运行SecureTrack拓扑查询。GET /api/v1/topology/path:运行SecureTrack拓扑路径查询。返回a 概括 结果包括traffic_allowed,is_fully_routed,以及path_device_names(如果允许/路由)。GET /api/v1/topology/path/image:以图像形式获取拓扑路径(例如PNG)。POST /api/v1/graphql/rules:使用GraphQL和TQL过滤器查询SecureTrack规则。
注: 实现需要根据Tufin 25.1 REST API文档进行验证。过滤器实现需要根据特定的Tufin API语法进行检查。
基本示例(curl)
# Set environment variables for convenience
export MCP_URL="http://localhost:8000"
export MCP_API_KEY="your_api_key_here"
# Health Check
curl "$MCP_URL/health"
# List Devices
curl -H "X-API-Key: $MCP_API_KEY" "$MCP_URL/api/v1/devices?limit=5"
# Create Ticket (Requires appropriate role for the key)
curl -X POST -H "X-API-Key: $MCP_API_KEY" -H "Content-Type: application/json" \
-d '{"subject": "API: Allow Port 443", "description": "...details..."}' \
"$MCP_URL/api/v1/tickets"
# Example Topology Path Query
curl -G -H "X-API-Key: $MCP_API_KEY" "$MCP_URL/api/v1/topology/path" \
--data-urlencode "src=1.1.1.1" \
--data-urlencode "dst=8.8.8.8" \
--data-urlencode "service=tcp:443"
# Example Topology Path Image Request (save to file)
curl -H "X-API-Key: $MCP_API_KEY" "$MCP_URL/api/v1/topology/path/image?src=1.1.1.1&dst=8.8.8.8&service=tcp:443" -o topology_path.png
# Example Add Device (Cisco ASA - requires ADMIN role & correct device_data)
curl -X POST -H "X-API-Key: $MCP_API_KEY" -H "Content-Type: application/json" \
-d '{
"devices": [
{
"display_name": "MCP-ASA-Test",
"ip_address": "10.1.2.3",
"vendor": "Cisco",
"model": "ASA",
"securetrack_domain": "Default",
"enable_topology": true,
"device_data": {
"user_name": "tufin-api-user",
"password": "tufin-api-password",
"enable_password": "tufin-enable-password"
# Add other ASA specific fields from Tufin docs here
}
}
]
}' \
"$MCP_URL/api/v1/devices/bulk"
# Example Import Managed Devices (Panorama DG)
curl -X POST -H "X-API-Key: $MCP_API_KEY" -H "Content-Type: application/json" \
-d '{
"devices": [
{
"device_id": "1",
"device_data": {
"import_all": false,
"import_devices": [
{"name": "DG1", "import_all": false, "managed_devices": ["fw1"]}
]
}
}
]
}' \
"$MCP_URL/api/v1/devices/bulk/import"
# Example GraphQL Rule Query (using curl and jq for readability)
# Find firewall rules allowing any source to 8.8.8.8
export TQL_FILTER="destination.ip 8.8.8.8"
curl -X POST -H "X-API-Key: $MCP_API_KEY" -H "Content-Type: application/json" \
-d "{\"tql_filter\": \"$TQL_FILTER\"}" \
"$MCP_URL/api/v1/graphql/rules" | jqOpenAPI规范
OpenAPI 3.0规范文件(openapi.yaml)包含在根目录中。该文件正式描述了API,包括端点、参数、请求/响应模式和安全要求。它可以与各种工具一起使用:
- 代码生成: 生成不同语言的客户端库。
- API文件: 使用Swagger UI或Redoc等工具渲染交互式文档。
- AI集成: 导入到ChatGPT Actions等平台以启用交互。
- 测试工具: 使用Postman或Insomnia等工具。
(可选增强功能): 考虑将FastAPI配置为在以下位置自动满足此规范 /openapi.yaml 以及交互式文档(Swagger UI/Redoc)。
Python客户端库
Python客户端库的基本结构在 client_libs/python/.
安装(从本地来源)
# From the project root directory
cd client_libs/python
pip install .用法示例
from tufin_mcp_client import TufinMCPClient, TufinMCPClientError
SERVER_URL = "http://localhost:8000"
API_KEY = "your_api_key_here"
# Use as a context manager (recommended)
with TufinMCPClient(base_url=SERVER_URL, api_key=API_KEY) as client:
try:
health = client.get_health()
print(f"Health: {health}")
devices = client.list_devices()
print(f"Devices Found: {devices.total}")
# Example: Get first device if list is not empty
if devices.devices:
first_device_id = devices.devices[0].id
device_details = client.get_device(first_device_id)
print(f"Device {first_device_id}: {device_details.name} ({device_details.vendor})")
# Example: Create Ticket
ticket_data = {
"workflow_name": "Example Firewall Workflow", # Check configured workflows
"subject": "Client Lib Test",
"details": { # Workflow specific fields go here
"description": "Testing ticket creation via client",
"priority": "Medium"
# Add other fields required by the specific workflow
}
}
created_ticket = client.create_ticket(ticket_data)
print(f"Created Ticket ID: {created_ticket.id}, Status: {created_ticket.status}")
ticket_id = created_ticket.id
if ticket_id:
retrieved_ticket = client.get_ticket(ticket_id)
print(f"Retrieved Ticket {ticket_id}: Subject: {retrieved_ticket.subject}")
updated_data = {"status": "In Progress"} # Check actual updatable fields
updated_ticket = client.update_ticket(ticket_id, updated_data)
print(f"Updated Ticket {ticket_id}: Status: {updated_ticket.status}")
# Example Add Device
asa_device = {
"display_name": "MCP-ASA-Test-Client",
"ip_address": "10.1.2.4",
"vendor": "Cisco",
"model": "ASA",
"securetrack_domain": "Default",
"enable_topology": True,
"device_data": {
"user_name": "tufin-api-user",
"password": "tufin-api-password",
"enable_password": "tufin-enable-password"
}
}
client.add_devices([asa_device]) # Pass as a list
print("Device add request accepted.")
# Example Import Managed Device
import_details = {
"devices": [
{
"device_id": "1", # Panorama ID
"device_data": {
"import_all": False,
"import_devices": [
{"name": "DG_CLIENT", "import_all": True}
]
}
}
]
}
client.import_managed_devices(import_details)
print("Managed device import request accepted.")
# Example GraphQL Rule Query
rule_filter = "action accept and source.ip 192.168.1.0/24"
rules_response = client.query_rules_graphql(tql_filter=rule_filter)
print(f"\nFound {rules_response.rules.count} rules matching filter:")
for rule in rules_response.rules.values:
print(f" - ID: {rule.id}, Name: {rule.name}, Action: {rule.action}")
except TufinMCPClientError as e:
print(f"MCP Client Error: {e}")
if e.status_code:
print(f" Status Code: {e.status_code}")
if e.response_text:
print(f" Response: {e.response_text}")
except Exception as e:
print(f"An unexpected error occurred: {e}")注: 客户端库提供基本功能、错误处理(TufinMCPClientError),并返回响应的Pydantic模型。计划进一步改进(见路线图)。
JavaScript/TypeScript客户端库
一个基本的TypeScript客户端库结构 用于与MCP服务器API交互 提供于 client_libs/javascript/.
安装
# From your JS/TS project directory
npm install
# or link for local development
# cd client_libs/javascript && npm link && cd ../../ && npm link tufin-mcp-client-js
# Or if published to npm:
# npm install tufin-mcp-client-js 如果从源代码安装,请确保首先构建客户端: cd client_libs/javascript && npm run build && cd ../..
使用示例(TypeScript)
import { TufinMCPClient, TufinMCPClientError } from 'tufin-mcp-client-js'; // Adjust import path
const SERVER_URL = 'http://localhost:8000'; // Your MCP Server URL
const API_KEY = 'your_api_key_here';
const client = new TufinMCPClient(SERVER_URL, API_KEY);
async function runClient() {
try {
const health = await client.getHealth();
console.log('Health:', health);
const devices = await client.listDevices({ limit: 5 }); // Example param
console.log(`Devices Found: ${devices.total}`);
console.log('First device:', devices.devices[0]);
// Example: Create Ticket
const ticketData = {
workflow_name: 'Example Firewall Workflow', // Check configured workflows
subject: 'TS Client Test',
details: {
description: 'Testing ticket from TS client',
priority: 'Low'
// Add other workflow-specific fields
}
};
const createdTicket = await client.createTicket(ticketData);
console.log(`Created Ticket ID: ${createdTicket.id}, Status: ${createdTicket.status}`);
// Example Add Device
const asaDevice = {
display_name: "MCP-ASA-Test-JS",
ip_address: "10.1.2.5",
vendor: "Cisco",
model: "ASA",
securetrack_domain: "Default",
enable_topology: true,
device_data: {
user_name: "tufin-api-user",
password: "tufin-api-password",
enable_password: "tufin-enable-password"
}
};
await client.addDevices([asaDevice]); // Pass as an array
console.log("Device add request accepted.");
// Example Import Managed Device
const importDetails = {
devices: [
{
device_id: "1", // Panorama ID
device_data: {
import_all: false,
import_devices: [
{ name: "DG_JS_CLIENT", import_all: true }
]
}
}
]
};
await client.importManagedDevices(importDetails);
console.log("Managed device import request accepted.");
// Example GraphQL Rule Query
const ruleFilter = "disabled true";
const rulesResponse = await client.queryRulesGraphQL({tql_filter: ruleFilter});
console.log(`\nFound ${rulesResponse.rules.count} disabled rules:`);
rulesResponse.rules.values.forEach(rule => {
console.log(` - ID: ${rule.id}, Name: ${rule.name}`);
});
} catch (error) {
if (error instanceof TufinMCPClientError) {
console.error('MCP Client Error:', error.message);
if (error.status) {
console.error(' Status Code:', error.status);
}
if (error.data) {
console.error(' Response Data:', error.data);
}
} else {
console.error('An unexpected error occurred:', error);
}
}
}
runClient();注: 这个客户是基本的。它需要进一步发展,以实现全面的错误处理、潜在的模型解析(如果不依赖于 any),以及更坚固的类型安全性。
直接Tufin API客户(备选)
对于需要绕过MCP服务器并使用基本身份验证直接连接到Tufin API的场景,可以在 client_libs/javascript_direct/。有关详细信息,请参阅该目录中的README。
与AI工具集成
- 核心要求: MCP服务器URL,API密钥。
- 方法: Python客户端库或直接API调用。
- 工具指南: 游标、ChatGPT操作(使用
openapi.yaml)、Copilot(通过代码上下文)、Ollama/OpenRouter(通过中间脚本)。 - 安全注意事项: 密钥管理、HTTPS、最小权限、监控。
贡献
欢迎投稿!请查看 贡献指南 有关如何参与、报告错误、建议功能和提交pull请求的详细信息。
我们还坚持 行为准则.
路线图/未来增强功能
此列表反映了已知的TODO和未来的潜在改进:
- 验证和优化Tufin REST API逻辑:
- 双重检查中使用的所有Tufin REST API端点路径、方法、请求参数/主体(尤其是过滤语法/功能)和响应结构 src/app/clients/tufin.py 与Tufin 25.1 REST官方文档相比。 - 确保Pydantic模型 src/app/models/ 准确地解析经验证的Tufin REST API响应。
- GraphQL API集成:
- 探索并实现利用Tufin SecureTrack GraphQL API的端点(文档)用于潜在的更丰富的数据检索(例如,设备、规则、USP)。 (已添加规则查询) - 允许通过MCP API动态选择GraphQL查询中的字段。
- 批量操作:
- 实现批量操作的端点,例如从文件(例如CSV/Excel)添加/更新多个设备, 以及导入受管设备.
- 生产安全:
- 替换 InMemorySecureStore 使用生产就绪的解决方案(数据库、Vault),并实施安全的API密钥管理(生成、吊销)。 - 在中实施稳健的敏感数据屏蔽 src/app/core/logging_config.py. - 确保正确的SSL证书验证(TUFIN_SSL_VERIFY)已配置用于生产部署。
- 测试:
- 添加全面的单元和集成测试,包括客户端逻辑、API端点、安全性和错误处理。
- 客户库:
- 增强Python客户端库(错误处理、响应模型/解析)。 - 增强JS/TS客户端库(错误处理、构建过程)。
- Tufin客户精炼:
- 为添加可配置的超时和重试逻辑 httpx 客户在 src/app/clients/tufin.py.
- 部署DX(&DX):
- 添加进一步的部署指导(例如,Kubernetes清单、生产Gunicorn设置)。 - 配置FastAPI以提供服务 openapi.yaml 以及交互式文档(Swagger UI/Redoc)。
许可证
此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。
