Files
momentry_core/docs/API_KEY_MANAGEMENT.md

21 KiB
Raw Blame History

Momentry API Key 管理系統設計

項目 內容
建立者 Warren
建立時間 2026-03-21
文件版本 V1.2

版本歷史

版本 日期 目的 操作人 工具/模型
V1.0 2026-03-18 創建文件 Warren OpenCode / MiniMax M2.5
V1.1 2026-03-20 新增 Key 類型與管理流程 Warren OpenCode
V1.2 2026-03-21 更新 API Key 格式與驗證流程 Warren OpenCode

狀態: 開發中


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/