## v0.9.20260325_144654 ### Features - API Key Authentication System - Job Worker System - V2 Backup Versioning ### Bug Fixes - get_processor_results_by_job column mapping Co-authored-by: OpenCode
21 KiB
21 KiB
Momentry API Key 管理系統設計
| 項目 | 內容 |
|---|---|
| 版本 | V1.2 |
| 日期 | 2026-03-21 |
| 狀態 | 開發中 |
1. 概述
1.1 目標
建立安全的 API Key 管理機制,支援:
- 多類型 API Key(系統、用戶、服務)
- 自動過期與輪換
- 異常使用偵測
- 強制更新機制
- 完整審計日誌
- Gitea Token 整合
- n8n API Key 整合
1.2 設計原則
| 原則 | 說明 |
|---|---|
| 最小權限 | 每個 Key 僅授予必要權限 |
| 定期輪換 | 自動過期強制更新 |
| 追蹤可審 | 所有操作都有日誌 |
| 分離儲存 | Key 與使用者資料分離 |
2. API Key 類型
2.1 Key 類型矩陣
| 類型 | 前綴 | 用途 | 預設有效期 | 輪換方式 |
|---|---|---|---|---|
system |
msys_ |
系統內部服務 | 365 天 | 手動 |
user |
muser_ |
個人用戶 | 90 天 | 自動 |
service |
msvc_ |
服務間通訊 | 180 天 | 自動 |
integration |
mint_ |
第三方整合 | 30 天 | 強制更新 |
emergency |
memg_ |
緊急存取 | 24 小時 | 一次性 |
2.2 Key 格式
{prefix}{uuid_v4}_{timestamp}_{checksum}
範例:
msys_a1b2c3d4-e5f6-7890-abcd-ef1234567890_1710998400_sha256
3. 資料庫 Schema
3.1 api_keys 表
CREATE TABLE api_keys (
id BIGSERIAL PRIMARY KEY,
key_id VARCHAR(64) UNIQUE NOT NULL, -- 公開 Key ID
key_hash VARCHAR(128) NOT NULL, -- SHA256 哈希
key_prefix VARCHAR(8) NOT NULL, -- Key 前綴
name VARCHAR(128) NOT NULL, -- Key 名稱
key_type VARCHAR(32) NOT NULL, -- system/user/service/integration/emergency
user_id BIGINT, -- 關聯用戶 (nullable for system)
service_name VARCHAR(64), -- 服務名稱 (for service keys)
permissions JSONB NOT NULL DEFAULT '[]', -- 權限列表
expires_at TIMESTAMP, -- 過期時間
last_used_at TIMESTAMP, -- 最後使用時間
last_used_ip VARCHAR(45), -- 最後使用 IP
usage_count BIGINT DEFAULT 0, -- 使用次數
status VARCHAR(16) DEFAULT 'active', -- active/suspended/expired/revoked
rotation_required BOOLEAN DEFAULT FALSE, -- 強制輪換標記
rotation_reason VARCHAR(256), -- 輪換原因
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_api_keys_key_id ON api_keys(key_id);
CREATE INDEX idx_api_keys_user_id ON api_keys(user_id);
CREATE INDEX idx_api_keys_type ON api_keys(key_type);
CREATE INDEX idx_api_keys_status ON api_keys(status);
CREATE INDEX idx_api_keys_expires ON api_keys(expires_at);
3.2 api_key_audit_log 表
CREATE TABLE api_key_audit_log (
id BIGSERIAL PRIMARY KEY,
key_id VARCHAR(64) NOT NULL,
action VARCHAR(32) NOT NULL, -- created/used/rotated/revoked/expired/suspended
actor VARCHAR(64), -- 操作者 (user_id or 'system')
ip_address VARCHAR(45),
user_agent VARCHAR(512),
request_path VARCHAR(256),
response_code INTEGER,
details JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_audit_key_id ON api_key_audit_log(key_id);
CREATE INDEX idx_audit_action ON api_key_audit_log(action);
CREATE INDEX idx_audit_created ON api_key_audit_log(created_at);
3.3 api_key_rotation_log 表
CREATE TABLE api_key_rotation_log (
id BIGSERIAL PRIMARY KEY,
key_id VARCHAR(64) NOT NULL,
old_key_id VARCHAR(64),
new_key_id VARCHAR(64),
rotation_type VARCHAR(32) NOT NULL, -- scheduled/manual/forced/emergency
reason VARCHAR(256),
triggered_by VARCHAR(64), -- system/user/scheduler
grace_period_end TIMESTAMP, -- 寬限期結束時間
created_at TIMESTAMP DEFAULT NOW()
);
4. API Key 狀態機
┌──────────────┐
│ created │
└──────┬───────┘
│
▼
┌────────────────────┐
│ active │◄─────────────┐
└─────────┬──────────┘ │
│ │
┌─────────────┼─────────────┐ │
│ │ │ │
▼ ▼ ▼ │
┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ suspended │ │ expired │ │ revoked │─────┘
└──────────┘ └──────────┘ └──────────┘
狀態轉換規則
| 從 | 到 | 觸發條件 |
|---|---|---|
| created | active | 啟用 Key |
| active | suspended | 異常使用偵測 |
| active | expired | 達到過期時間 |
| active | revoked | 手動撤銷 |
| suspended | active | 解除鎖定 |
| suspended | revoked | 確認異常 |
| expired | active | 重新啟用 |
5. 異常偵測機制
5.1 異常指標
| 指標 | 閾值 | 處置 |
|---|---|---|
| 每分鐘請求數 | > 1000 | 警告 |
| 每小時請求數 | > 10000 | 鎖定 |
| 錯誤率 | > 50% | 警告 |
| 不同 IP 數 | > 5/小時 | 警告 |
| 非工作時間使用 | 深夜請求 | 警告 |
| 異常模式 | 暴力破解 | 鎖定 |
5.2 異常處理流程
異常偵測
│
▼
┌─────────┐
│ 分析 │──→ 排除正常流量
└────┬────┘
│
▼
┌─────────┐
│ 評估 │──→ 輕微 → 警告
└────┬────┘
│
▼
┌─────────┐
│ 處置 │──→ 嚴重 → 鎖定 + 輪換
└─────────┘
6. 強制更新機制
6.1 觸發條件
| 條件 | 嚴重性 | 動作 |
|---|---|---|
| 疑似洩露 | 高 | 立即停用 + 強制輪換 |
| 異常使用 | 中 | 警告 + 建議輪換 |
| 計劃性維護 | 低 | 通知 + 排程輪換 |
| 政策要求 | 高 | 強制輪換 |
| 過期 | 低 | 停用 + 通知 |
6.2 強制輪換流程
1. 系統偵測到需要強制更新
│
▼
2. 建立新 Key(保留舊 Key 在寬限期內)
│
▼
3. 發送通知(Email/Slack/Redis PubSub)
│
▼
4. 寬限期開始(預設 24 小時)
│
├── 在寬限期內更新 → 完成輪換
│
└── 寬限期結束 → 舊 Key 停用
6.3 寬限期配置
| Key 類型 | 寬限期 |
|---|---|
| system | 72 小時 |
| user | 24 小時 |
| service | 48 小時 |
| integration | 24 小時 |
| emergency | 0 小時 |
7. CLI 管理命令
7.1 命令列表
# Key 管理
momentry api-key create --name "My Key" --type user --permissions read,write
momentry api-key list --type user
momentry api-key info <key_id>
momentry api-key revoke <key_id> --reason "安全原因"
# 輪換管理
momentry api-key rotate <key_id> # 正常輪換
momentry api-key force-rotate <key_id> # 強制輪換
momentry api-key rotation-status <key_id> # 查看輪換狀態
# 異常管理
momentry api-key suspend <key_id> --reason "異常使用"
momentry api-key unsuspend <key_id>
momentry api-key blacklist <key_id> # 列入黑名單
# 審計
momentry api-key audit <key_id> --since 7d
momentry api-key stats --type service --period 30d
7.2 輸出範例
$ momentry api-key list --type service
┌────────────────────────────────────┬─────────┬──────────────┬────────────────┐
│ Key ID │ Name │ Status │ Expires │
├────────────────────────────────────┼─────────┼──────────────┼────────────────┤
│ msvc_a1b2c3d4_1710998400_sha256 │ N8N │ active │ 2026-09-21 │
│ msvc_e5f6g7h8_1713600000_sha256 │ OpenCode│ rotation_req │ 2026-09-21 │
└────────────────────────────────────┴─────────┴──────────────┴────────────────┘
⚠️ 1 個 Key 需要輪換
8. 實現計畫
Phase 1: 核心功能
- 資料庫 Schema
- Key 生成與哈希
- 基本 CRUD API
- 過期檢查
Phase 2: 安全機制
- 異常偵測
- 自動鎖定
- 強制輪換
- 寬限期管理
Phase 3: 管理工具
- CLI 命令
- 審計日誌
- 統計報表
- 通知系統
Phase 4: 自動化
- 定時輪換排程
- Prometheus 指標
- Alertmanager 整合
- 自動化回應
9. 安全考量
9.1 Key 儲存
- 明文 Key 只顯示一次(創建時)
- 儲存時使用 SHA256 哈希
- 使用 Fernet 對稱加密敏感配置
9.2 傳輸安全
- 所有 API 必須使用 HTTPS
- Key 在 Header 中傳輸(X-API-Key)
- 避免 Key 在 URL 中
9.3 存取控制
- 只有管理員可創建/撤銷 Key
- 用戶只能管理自己的 Key
- 系統 Key 需要特殊權限
10. 環境變數配置
# API Key 管理
MOMENTRY_API_KEY_GRACE_PERIOD=86400 # 寬限期(秒)
MOMENTRY_API_KEY_MAX_PER_USER=5 # 每用戶最大 Key 數
MOMENTRY_API_KEY_ROTATION_DAYS=90 # 自動輪換天數
# 異常偵測
MOMENTRY_API_KEY_RATE_LIMIT=1000 # 每分鐘限制
MOMENTRY_API_KEY_ERROR_THRESHOLD=0.5 # 錯誤率閾值
MOMENTRY_API_KEY_IP_LIMIT=5 # 每小時 IP 限制
# 通知
MOMENTRY_API_KEY_ALERT_WEBHOOK= # 異常通知 webhook
11. Gitea API Token 整合
11.1 概述
支援透過 API Key 管理系統建立和管理 Gitea Personal Access Tokens,採用「建立時納管」模式。
11.2 納管模式
使用者提供帳號密碼 → 呼叫 Gitea API 建立 Token → 明文只顯示一次 → 同步儲存至管理系統
特點:
- Token 明文僅在建立時取得
- 管理系統記錄 Token 元數據(不含明文)
- 支援本地查詢和刪除
11.3 資料庫結構
CREATE TABLE gitea_tokens (
id SERIAL PRIMARY KEY,
gitea_token_id BIGINT NOT NULL, -- Gitea 內部 Token ID
gitea_user VARCHAR(128) NOT NULL, -- Gitea 用戶名
token_name VARCHAR(128) NOT NULL, -- Token 名稱
token_last_eight VARCHAR(8) NOT NULL, -- SHA1 最後 8 碼(顯示用)
scopes JSONB DEFAULT '[]', -- 權限範圍
api_key_id VARCHAR(48), -- 關聯的 API Key ID(可選)
last_verified TIMESTAMP, -- 最後驗證時間
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(gitea_user, token_name)
);
11.4 Token 權限範圍
| 範圍 | 說明 |
|---|---|
read:repository |
讀取倉庫 |
write:repository |
寫入倉庫 |
read:issue |
讀取議題 |
write:issue |
寫入議題 |
read:user |
讀取用戶資訊 |
write:write |
修改用戶資訊 |
read:organization |
讀取組織 |
write:organization |
修改組織 |
read:package |
讀取套件 |
write:package |
發布套件 |
read:notification |
讀取通知 |
write:notification |
修改通知 |
read:admin |
管理員讀取 |
write:admin |
管理員寫入 |
11.5 CLI 命令
建立 Token
# 基本用法
momentry gitea create \
--username <gitea_user> \
--password <gitea_password> \
--token-name <token_name> \
--scopes "read:repository,write:repository"
# 範例:建立整合用 Token
momentry gitea create \
--username admin \
--password "MyPassword123" \
--token-name "ci-pipeline" \
--scopes "read:repository,write:repository,read:issue,write:issue"
輸出範例:
✅ Gitea Token created successfully!
┌─────────────────────────────────────────────────────────────────────────────┐
│ ⚠️ IMPORTANT: Save this token now - it will not be shown again! │
└─────────────────────────────────────────────────────────────────────────────┘
Token ID: 9
Token Name: ci-pipeline
SHA1: 9a4f282e9ba817b430082e6bff2c18e2ae38e480
Last 8: ae38e480
Authorization Header:
Authorization: token 9a4f282e9ba817b430082e6bff2c18e2ae38e480
列出 Token
# 列出用戶的所有 Token
momentry gitea list \
--username <gitea_user> \
--password <gitea_password>
輸出範例:
📋 Gitea Tokens for user: admin
┌────────────────────────────────────────────────────────────────────────────┐
│ ID │ Name │ Last 8 │ Registered │
├────────────────────────────────────────────────────────────────────────────┤
│ 9 │ ci-pipeline │ ae38e480 │ ✓ │
│ 8 │ dev-token │ 1234abcd │ - │
└────────────────────────────────────────────────────────────────────────────┘
Total: 2 token(s)
刪除 Token
# 刪除指定 Token
momentry gitea delete \
--username <gitea_user> \
--password <gitea_password> \
--token-name <token_name>
查詢本地記錄
# 查詢已納管的 Token 記錄
momentry gitea verify --token-name <token_name>
輸出範例:
📋 Gitea Token: ci-pipeline
User: admin
Token ID: 9
Last 8: ae38e480
Scopes: ["read:repository","write:repository"]
Created: 2026-03-21 06:44:55.577586 UTC
Last Verified: never
11.6 使用範圍
適用場景
| 場景 | 說明 |
|---|---|
| CI/CD 整合 | 建立專用 Token 用於自動化流程 |
| 服務間通訊 | 建立 Token 供其他服務存取 Gitea API |
| 開發環境 | 為開發者建立短期 Token |
| 監控整合 | 建立只讀 Token 用於監控和報告 |
限制
| 限制 | 說明 |
|---|---|
| 明文 Token | 僅在建立時取得,無法再次查詢 |
| 管理 API | 需要帳號密碼(BasicAuth) |
| Token 驗證 | 只能透過 API 呼叫驗證有效性 |
| 同步刪除 | 本地刪除不會自動同步到 Gitea |
11.7 環境變數
# Gitea 連線設定
GITEA_URL=http://localhost:3000 # Gitea API URL
11.8 安全考量
| 項目 | 措施 |
|---|---|
| 密碼傳輸 | 僅在 CLI 命令中使用,不儲存 |
| Token 儲存 | 本地僅存元數據,不含明文 |
| 權限最小化 | 建議僅授予必要權限 |
| 定期輪換 | 建議定期更新 Token |
12. n8n API Key 整合
12.1 概述
支援透過 API Key 管理系統建立和管理 n8n API Keys,採用「建立時納管」模式。
12.2 納管模式
使用者提供現有 n8n API Key → 呼叫 n8n API 建立新 Key → 明文只顯示一次 → 同步儲存至管理系統
特點:
- 需要一個現有的 n8n API Key 作為管理憑證
- API Key 明文僅在建立時取得
- 管理系統記錄 Key 元數據(不含明文)
- 支援本地查詢和刪除
12.3 資料庫結構
CREATE TABLE n8n_api_keys (
id SERIAL PRIMARY KEY,
n8n_key_id VARCHAR(64) UNIQUE NOT NULL, -- n8n 內部 Key ID
label VARCHAR(100) NOT NULL, -- Key 標籤
api_key_last_eight VARCHAR(8) NOT NULL, -- API Key 最後 8 碼(顯示用)
momentry_api_key_id VARCHAR(48), -- 關聯的 API Key ID(可選)
expires_at TIMESTAMP WITH TIME ZONE, -- 過期時間
last_verified TIMESTAMP WITH TIME ZONE, -- 最後驗證時間
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
12.4 認證方式
n8n 使用 JWT-based API Key,透過 X-N8N-API-KEY Header 認證:
curl -H "X-N8N-API-KEY: <your-api-key>" https://n8n.example.com/api/v1/workflows
12.5 CLI 命令
建立 API Key
# 基本用法
momentry n8n create \
--api-key <existing_n8n_api_key> \
--label <key_label> \
--expires-in-days <days>
# 範例:建立 CI/CD 用 Key
momentry n8n create \
--api_key "n8n_api_xxxxxxxxxxxx" \
--label "ci-pipeline" \
--expires-in-days 90
輸出範例:
✅ n8n API Key created successfully!
┌─────────────────────────────────────────────────────────────────────────────┐
│ ⚠️ IMPORTANT: Save this API key now - it will not be shown again! │
└─────────────────────────────────────────────────────────────────────────────┘
Key ID: abc123-def456
Label: ci-pipeline
API Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Usage:
curl -H 'X-N8N-API-KEY: eyJhbGciOiJIUz...' https://n8n.momentry.ddns.net/api/v1/workflows
列出 API Keys
# 列出所有 API Keys
momentry n8n list --api-key <existing_n8n_api_key>
輸出範例:
📋 n8n API Keys
┌────────────────────────────────────────────────────────────────────────────┐
│ Label │ ID │
├────────────────────────────────────────────────────────────────────────────┤
│ ci-pipeline │ abc123-def456-789 │
│ monitoring │ xyz789-abc123-456 │
└────────────────────────────────────────────────────────────────────────────┘
Total: 2 key(s)
刪除 API Key
# 刪除指定 API Key
momentry n8n delete \
--api-key <existing_n8n_api_key> \
--label <key_label>
查詢本地記錄
# 查詢已納管的 API Key 記錄
momentry n8n verify --label <key_label>
輸出範例:
📋 n8n API Key: ci-pipeline
Key ID: abc123-def456
Last 8: ...JVCJ9
Created: 2026-03-21 06:44:55.577586 UTC
Expires: 2026-06-19 06:44:55.577586 UTC
Last Verified: never
12.6 使用範圍
適用場景
| 場景 | 說明 |
|---|---|
| CI/CD 整合 | 建立專用 Key 用於自動化流程 |
| 監控整合 | 建立只讀 Key 用於監控工作流狀態 |
| 服務間通訊 | 建立 Key 供其他服務呼叫 n8n API |
| 開發環境 | 為開發者建立短期 Key |
限制
| 限制 | 說明 |
|---|---|
| 明文 API Key | 僅在建立時取得,無法再次查詢 |
| 管理憑證 | 需要一個現有的 n8n API Key |
| 本地刪除 | 不會自動同步到 n8n |
| 權限範圍 | 非 Enterprise 版無細粒度權限 |
12.7 環境變數
# n8n 連線設定
N8N_URL=https://n8n.momentry.ddns.net # n8n API URL
12.8 安全考量
| 項目 | 措施 |
|---|---|
| 管理 Key | 需妥善保管,作為管理其他 Key 的憑證 |
| API Key 儲存 | 本地僅存元數據,不含明文 |
| 過期機制 | 建議設定過期時間 |
| 定期輪換 | 建議定期更新 Key |
13. 參考文檔
- PostgreSQL Schema
- Redis Key 設計( MOMENTRY_CORE_REDIS_KEYS.md)
- 監控系統(MOMENTRY_CORE_MONITORING.md)
- Gitea 安裝指南(INSTALL_GITEA.md)
- n8n API 文件(https://docs.n8n.io/api/authentication/)