Files
mcp-auth/sql/init.sql
T
2026-09-02 17:31:52 +08:00

78 lines
4.2 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================
-- MCP Auth — Bearer Token 动态鉴权管理库
-- 数据库:mcp_auth(独立于业务库 smart_quotation_auto)
-- 幂等可重跑:CREATE DATABASE 需手动执行(连接超库权限),下方表结构均 IF NOT EXISTS
-- ============================================================
-- 0. 库(手动执行,或由 DBA 预建)
-- CREATE DATABASE mcp_auth;
-- 1. mcp_token:token 主表
CREATE TABLE IF NOT EXISTS mcp_token (
token_id BIGSERIAL PRIMARY KEY,
token_hash VARCHAR(64) UNIQUE NOT NULL, -- sha256(明文),verify 校验用
token_plain VARCHAR(128), -- 明文 Token(管理后台二次复制用)
token_prefix VARCHAR(16) NOT NULL, -- 明文前 12 字符 + '…',前端识别用
client_id VARCHAR(64) NOT NULL, -- 调用方标识(如 trae / partner-a)
service_scope VARCHAR(32) NOT NULL, -- 'erp' | 'crm'(服务标识)
service_url VARCHAR(255), -- MCP 服务地址(如 http://10.100.154.100:8001/mcp)
status VARCHAR(16) NOT NULL DEFAULT 'active', -- active/revoked/expired
expires_at TIMESTAMPTZ, -- null = 永不过期
description VARCHAR(200), -- 用途说明
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_by VARCHAR(64) NOT NULL,
revoked_at TIMESTAMPTZ,
revoke_reason VARCHAR(200),
last_used_at TIMESTAMPTZ,
last_used_ip VARCHAR(64),
last_used_svc VARCHAR(32) -- 最近被哪个 MCP 服务命中(erp/crm)
);
CREATE INDEX IF NOT EXISTS idx_mcp_token_status ON mcp_token(status) WHERE status = 'active';
CREATE INDEX IF NOT EXISTS idx_mcp_token_client ON mcp_token(client_id);
-- 2. mcp_token_log:审计日志(可选,MCP 服务 verify_token 命中后异步写入)
CREATE TABLE IF NOT EXISTS mcp_token_log (
log_id BIGSERIAL PRIMARY KEY,
token_id BIGINT NOT NULL REFERENCES mcp_token(token_id) ON DELETE CASCADE,
event VARCHAR(32) NOT NULL, -- issued/verified/revoked/rejected/expired
service VARCHAR(32), -- erp/crm
client_ip VARCHAR(64),
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
detail JSONB
);
CREATE INDEX IF NOT EXISTS idx_mcp_token_log_token ON mcp_token_log(token_id, occurred_at DESC);
CREATE INDEX IF NOT EXISTS idx_mcp_token_log_event ON mcp_token_log(event, occurred_at DESC);
-- 3. admin_user:管理员账号(bcrypt 密码哈希)
CREATE TABLE IF NOT EXISTS admin_user (
user_id BIGSERIAL PRIMARY KEY,
username VARCHAR(64) UNIQUE NOT NULL,
password_hash VARCHAR(128) NOT NULL, -- bcrypt
display_name VARCHAR(64),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_login_at TIMESTAMPTZ
);
-- 4. mcp_service:MCP 服务注册表(per-service API Key)
CREATE TABLE IF NOT EXISTS mcp_service (
service_id BIGSERIAL PRIMARY KEY,
service_name VARCHAR(64) UNIQUE NOT NULL, -- erp / crm / ...
service_url VARCHAR(255) UNIQUE NOT NULL, -- MCP 服务地址(如 http://10.100.154.100:8001/mcp),唯一
api_key VARCHAR(128) NOT NULL, -- 明文 API Key(管理后台展示用,MCP 服务用此值)
api_key_hash VARCHAR(64) UNIQUE NOT NULL, -- sha256(明文 API Key),verify-token 校验用
description VARCHAR(200),
status VARCHAR(16) NOT NULL DEFAULT 'active', -- active/revoked
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_by VARCHAR(64) NOT NULL,
revoked_at TIMESTAMPTZ,
last_used_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_mcp_service_status ON mcp_service(status) WHERE status = 'active';
-- 5. 默认管理员(密码: admin123,bcrypt $2b$12$... 由后端首次启动时注入,此处仅占位)
-- 实际部署:python -m backend.scripts.seed_admin 或由后端首次启动自动建
-- 这里给出手工生成 bcrypt 的 SQL 模板(替换 $BCRYPT_HASH 为实际值):
-- INSERT INTO admin_user (username, password_hash, display_name)
-- VALUES ('admin', '$BCRYPT_HASH', '默认管理员')
-- ON CONFLICT (username) DO NOTHING;