跳转至

XINFRA 安全·认证·数据报告

生成日期:2026-08-27 | 基于源码深度分析


一、认证架构总览

XINFRA 实现了多协议统一认证网关,支持本地登录、SAML 2.0 SSO、OAuth 2.0/OIDC 三种认证方式,并通过 JWT 实现会话管理。

graph TD
    subgraph "认证网关层"
        A["本地登录\nPOST /login"]
        B["SAML 2.0 SSO\nGET /login/internal-sso"]
        C["OAuth 2.0 / OIDC\n/auth/oauth/*"]
    end

    A --> JWT["JWT 签发/校验\nHS256/RS256"]
    B --> JWT
    C --> JWT

    JWT --> MW["AuthMiddleware\nBearer Token"]

    style JWT fill:#fff3e0
    style MW fill:#e8f5e9

💡 统一认证网关

三种认证方式最终都汇聚到 JWT 签发/校验,后端通过统一的 AuthMiddleware 处理所有请求的认证。SSO 启用时本地登录自动禁用,保证认证入口收敛。


二、本地登录

端点: POST /auth/api/v1/login

流程:

  1. 接收 username + password
  2. 查询数据库用户记录
  3. 验证密码哈希
  4. 签发 HS256 JWT(Claims: UserID, Username, Email, DisplayName, IsAdmin)
  5. 返回 token

限制: SSO 启用时(SSO_ENABLED=true)禁用本地登录


三、SAML 2.0 SSO

3.1 组件

组件 路径 职责
sso/login.go internal/sso/ SAML SP 核心实现
sso/metadata.go internal/sso/ SP 元数据 XML 生成
handler/saml.go internal/handler/ HTTP Handler

3.2 登录流程

sequenceDiagram
    participant U as 用户
    participant FE as 前端
    participant BE as 后端
    participant IDP as SAML IDP

    U->>FE: 点击 SSO 登录
    FE->>BE: GET /login/internal-sso
    BE->>BE: BuildLoginRedirect()
    BE->>BE: 构建 AuthnRequest (deflate+base64)
    BE-->>FE: 302 重定向到 IDP
    FE->>IDP: 用户在 IDP 认证
    IDP-->>BE: POST SAMLResponse 到 /saml/acs
    BE->>BE: DecodeSAMLResponse()
    BE->>BE: 解密断言 (RSA-OAEP + AES)
    BE->>BE: 创建/更新用户 + 签发 JWT
    BE-->>FE: 重定向回前端 (携带 sso_token)

💡 SAML 2.0 实现

完整实现 SAML 2.0 SP:AuthnRequest 构建(deflate + base64 编码)→ HTTP-Redirect 绑定 → IDP 认证 → SAMLResponse 解析。支持加密断言解密(RSA-OAEP 密钥传输 + AES-128/192/256-CBC/GCM 数据加密)。

3.3 加密算法支持

  • 密钥传输: RSA-OAEP
  • 数据加密:
  • AES-128-CBC / AES-192-CBC / AES-256-CBC
  • AES-128-GCM / AES-192-GCM / AES-256-GCM

3.4 SP 元数据

端点: GET /auth/api/v1/saml/metadata

生成标准 SAML SP 元数据 XML,包含: - EntityDescriptor - SPSSODescriptor - 签名/加密 KeyDescriptor - AssertionConsumerService (ACS) URL

3.5 登出

端点: GET/POST /auth/api/v1/logout

  • 清除本地 JWT(Redis token 吊销)
  • 可选重定向到 SAML IDP 登出 URL

四、OAuth 2.0 / OIDC Provider

4.1 端点

端点 路径 说明
Discovery /auth/.well-known/openid-configuration OIDC 发现文档
Authorize /auth/oauth/authorize 授权端点
Token /auth/oauth/token Token 端点
JWKS /auth/oauth/jwks 公钥端点
UserInfo /auth/oauth/userinfo 用户信息端点

4.2 支持的 Client

Client ID 用途 Token 类型
wayne Wayne K8s 管理平台 HS256 access_token
clouddm CloudDM 数据库管理 HS256 access_token
archery Archery SQL 审核 RS256 PlatformToken

4.3 授权码流程

sequenceDiagram
    participant FE as 前端
    participant BE as 后端
    participant Redis as Redis

    FE->>BE: GET /oauth/authorize?client_id=...
    BE->>BE: 用户认证 + 生成 OAuth Code
    BE->>Redis: SetNX + TTL 存储 Code
    BE-->>FE: 302 redirect_uri?code=...
    FE->>BE: POST /oauth/token (code)
    BE->>Redis: 校验 + 消费 Code(一次性)
    BE-->>FE: access_token + id_token

💡 OAuth2 授权码流程

OAuth Code 使用 Redis SetNX + TTL 存储,保证一次性消费。Token 端点按 client 差异化签发:Wayen/CloudDM 使用 HS256 access_token,Archery 使用 RS256 PlatformToken。

4.4 Token 签发

  • access_token: HS256,包含 UserID, Username, Email, IsAdmin
  • id_token: RS256,符合 OIDC 规范,包含 UserID, Username, Email, EmailVerified, Name, IsAdmin, Nonce
  • Archery 特殊处理: 签发 RS256 PlatformToken 替代 HS256 access_token

4.5 Token 吊销

  • 通过 Redis key 检查实现
  • 登出时将 token 加入吊销列表
  • AuthMiddleware 校验时可选检查 Redis 吊销状态

五、JWT 机制

5.1 Claims 结构

类型 算法 用途 包含字段
Claims HS256 访问令牌 UserID, Username, Email, DisplayName, IsAdmin
OAuthCodeClaims HS256 OAuth 授权码 UserID, ClientID, RedirectURI, Scope, Nonce
IDTokenClaims RS256 OIDC ID Token UserID, Username, Email, EmailVerified, Name, IsAdmin, Nonce
PlatformTokenClaims RS256 子系统平台令牌 UserID, Username, Email, DisplayName, IsAdmin

5.2 密钥管理

  • HS256: 通过 JWT_SECRET 环境变量配置
  • RS256: RSA 私钥从文件加载(支持 PKCS1/PKCS8 格式)
  • JWK 构建:从 RSA 公钥导出
  • KeyID 生成:SHA256 前 8 字节 Base64
  • 通过 JWKS 端点暴露公钥

5.3 配置

配置项 说明
JWT_SECRET HS256 密钥
JWT_ISSUER 签发者(默认 authserver)
JWT_TTL_MINUTES Token 有效期(默认 120 分钟)

六、权限模型

6.1 RBAC 架构

graph TD
    subgraph "平台级权限"
        P1["PlatformRoleBinding\nUserID → Role (platform_admin)"]
    end

    subgraph "业务线级权限"
        B1["BusinessLineUser\nUserID → Role (owner/member)"]
        B2["BusinessLinePermission\nUserID → Permission"]
    end

    subgraph "子系统级权限"
        S1["Wayne\nNamespace Role Binding"]
        S2["Archery\nResource Group / Permission Group"]
    end

    P1 --> B1
    B1 --> S1
    B1 --> S2

    style P1 fill:#e1f5fe
    style B1 fill:#fff3e0
    style B2 fill:#fff3e0

💡 三级 RBAC

权限模型分为三级:平台级(platform_admin 管理员)→ 业务线级(owner/member + 细粒度权限)→ 子系统级(Wayne 命名空间角色 + Archery 资源组/权限组)。前端通过四级路由守卫实现权限控制。

6.2 平台级角色

  • platform_admin — 平台管理员,存储在 PlatformRoleBinding 表
  • 系统用户 xinfra-platform 在初始化时自动创建并授予此角色

6.3 业务线级角色

  • owner — 业务线管理员,拥有所有业务线权限
  • member — 业务线成员,按 BusinessLinePermission 授予权限

6.4 权限清单

平台级权限(platformPermission):

  • business_line.manage — 业务线管理

业务线级权限(capability):

权限 说明
subsystem.wayne.manage Wayne 子系统管理(含 role.grant + role.revoke)
subsystem.wayne.read Wayne 子系统只读
subsystem.archery.manage Archery 子系统管理
subsystem.archery.read Archery 子系统只读
machine.view / machine.manage 机器资源查看/管理
delivery.view / delivery.deploy / delivery.credentials 交付系统查看/部署/凭证
execution_profile.manage 执行配置管理
audit.login.view / audit.operation.view 审计日志查看

6.5 前端权限检查

四级检查(路由守卫):

  1. platformPermission — authStore.hasPlatformPermission()
  2. businessLineMember — businessLineStore.current?.id 存在性
  3. businessLineOwner — businessLineStore.isCurrentAdmin
  4. capability / capabilities — authStore.hasAnyBusinessLinePermission()

权限别名映射(前端硬编码):

  • subsystem.wayne.manage → subsystem.wayne.role.grant, subsystem.wayne.role.revoke
  • machine.view → machine.read, machine.credential.read
  • machine.manage → machine.create/update/delete/credential.manage/sync
  • delivery.view → delivery.target.read, delivery.read
  • delivery.deploy → delivery.create
  • delivery.credentials → delivery.credential.reveal
  • execution_profile.manage → execution_profile.publish

七、审计日志

7.1 数据模型

AuditLog 表:

字段 类型 说明
ActorUserID uint 操作者 ID
ActorUsername string 操作者用户名
ClientIP string 客户端 IP
Action string 操作类型
ResourceType string 资源类型
ResourceID string 资源 ID
ScopeType string 作用域类型
ScopeID string 作用域 ID
BusinessLineID uint 业务线 ID
Decision string 决策结果
Reason string 原因
Metadata JSON 元数据

7.2 审计分类

分类 端点 内容
登录审计 GET /auth/api/v1/audit/login 登录/登出事件
业务线权限审计 GET /auth/api/v1/audit/operations?category=business_line_permission 权限授予/撤销
子系统授权审计 GET /auth/api/v1/audit/operations?category=subsystem_authorization 子系统角色绑定
服务交付审计 GET /auth/api/v1/audit/operations?category=service_delivery 交付任务操作

7.3 写入机制

  • AuditService 异步写入(不阻塞业务请求)
  • 支持分页查询

八、数据库设计

8.1 连接与迁移

  • 数据库: MySQL 8.0
  • ORM: GORM(gorm.io/driver/mysql)
  • 迁移: AUTO_MIGRATE=true 时自动迁移 40+ 张表
  • 初始化: SeedDefaults 创建系统平台用户 xinfra-platform

8.2 核心数据模型分组

用户与权限(7 张表)

  • User — 用户主表(软删除)
  • WayenCredential — Wayne 平台凭据(软删除)
  • BusinessLine — 业务线
  • BusinessLineUser — 业务线成员关系
  • PlatformRoleBinding — 平台角色绑定
  • BusinessLinePermission — 业务线权限
  • BusinessLineWayneNamespace / BusinessLineSinaOrganization — 业务线映射

交付系统(12+ 张表)

  • DeliveryTask — 交付任务(16 种状态)
  • ResourceQuota / ResourceReservation — 配额与预留
  • MySQLPrecheckLease — 预检租约(唯一约束)
  • DeploymentResult / DeploymentCredential — 部署结果与凭证
  • VaultDatabaseAccount — Vault 数据库账号
  • ServiceConfig — 服务配置台账
  • MySQLDynamicVariable — MySQL 动态变量(12 个种子数据)
  • ExecutionJob / RollbackJob — 执行与回滚
  • TaskEvent — 任务事件
  • AWXRuntimeInventory — AWX 运行时 Inventory

MySQL HA(5 张表)

  • MySQLCluster — 集群(HAMode: none/mha)
  • MySQLInstance — 实例(Role: primary/replica)
  • MySQLReplicationChannel — 复制通道
  • MySQLInternalCredential — 内部凭据(Vault 注册后清除)
  • ServerIDAllocation — Server ID 分配

PostgreSQL HA(8 张表)

  • PostgreSQLCluster — 集群
  • PostgreSQLInstance — 实例
  • PostgreSQLResourceUsage — 资源使用
  • PostgreSQLCloudDMReservation — CloudDM 预留
  • PostgreSQLHAOperation — HA 操作(14 种状态)
  • PostgreSQLHAHostPlan — 主机计划
  • PostgreSQLHAAudit — HA 审计
  • PostgreSQLHAControlOperation / PostgreSQLHAJobLog

机器与 Receptor(6 张表)

  • MachineResource — 机器资源
  • MachineCredential — 机器凭据
  • MachineSyncState — 同步状态
  • ReceptorNode — Receptor 节点
  • ReceptorProvisioningTask / ReceptorProvisioningEvent — 供应任务
  • SSHCredential — SSH 凭据(PGP 加密)

执行配置(3 张表)

  • ExecutionProfileRelease — 配置发布
  • ExecutionBindingRelease — 绑定发布
  • TaskExecutionSnapshot — 执行快照

Archery 集成(5 张表)

  • BusinessLineArcheryResourceGroup / BusinessLineArcheryPermissionGroup
  • ArcheryAccessSyncTask — 同步任务
  • ArcheryInstanceBinding / ArcheryUserBinding

审计(1 张表)

  • AuditLog — 统一审计日志

8.3 迁移逻辑

AutoMigrate 包含复杂的索引迁移逻辑: - RBAC 迁移:从 users.is_admin 导入 platform_role_bindings - 业务线角色迁移:permission=0 映射为 owner - PostgreSQL HA UUID 准备:将空字符串转为 NULL 以支持唯一索引 - MySQL/PostgreSQL 台账索引重建:活跃集群/实例的唯一约束 - SSH 凭据 schema 迁移 - MySQL 动态变量种子数据


九、缓存策略

9.1 Redis 使用

用途 Key 模式 TTL
OAuth Code 存储 oauth:code:{code} 可配置(OAuthCodeTTL)
Token 吊销 token:revoked:{token} JWT 剩余有效期
Wayne 容器数据缓存 业务相关 可配置(CacheTTL)

9.2 配置

配置项 说明
REDIS_ENABLED 是否启用 Redis
REDIS_ADDR Redis 地址
REDIS_PASSWORD Redis 密码
REDIS_DB 数据库编号
REDIS_CONNECT_TIMEOUT / REDIS_READ_TIMEOUT / REDIS_WRITE_TIMEOUT 超时配置

十、Vault 密钥管理

10.1 架构

graph TD
    subgraph VaultServer["Vault Server"]
        KV["KV v2\n通用密钥"]
        DB["Database Secrets Engine\n数据库凭据自动化"]
    end

    AppRole["AppRole Auth"] --> KV
    StaticRole["Static Role"] --> DB

    AppRole -->|"role_id + secret_id"| VaultServer
    DB -->|"MySQL/PostgreSQL 连接"| DB

    style VaultServer fill:#e1f5fe
    style AppRole fill:#e8f5e9

💡 Vault 集成

Vault 通过 AppRole 认证获取 token,支持自动续期(TTL 前 1 分钟刷新)和 401/403 请求重试。Database Secrets Engine 实现数据库凭据全生命周期自动化:连接注册 → Static Role 登记 → 凭据读取 → 清理。

10.2 认证方式

  • AppRole 认证: 通过 role_id + secret_id 获取 token
  • 自动续期: TTL 前 1 分钟自动刷新
  • 请求重试: 401/403 自动重新认证后重试一次

10.3 KV v2 操作

方法 说明
ReadKVV2(path, key) 读取密钥
WriteKVV2(path, data) 写入密钥
DeleteKVV2(path, key) 删除密钥

10.4 Database Secrets Engine

MySQL 连接注册

RegisterMySQLDatabaseConnection(vault, connectionName, dsn)
- plugin_name: mysql-database-plugin - 校验 skip_static_role_import_rotation 是否生效

Static Role 注册

RegisterDatabaseStaticRole(vault, roleName, connectionName, username, rotationPeriod)
- 读取 database/static-creds/<role> 验证凭据可用性 - 支持 skip_import_rotation 避免立即轮换密码

凭据读取

ReadDatabaseStaticCredentials(vault, roleName)
- 读取 Static Role 当前凭据(只用于运行时,不持久化)

清理

DeleteMySQLDatabaseConnection(vault, connectionName)
DeleteDatabaseStaticRole(vault, roleName)

10.5 配置

配置项 说明
VAULT_ENABLED 是否启用 Vault
VAULT_ADDR Vault 地址
VAULT_NAMESPACE Vault Namespace
VAULT_TOKEN Vault Token(备用)
VAULT_KVV2_MOUNT_PATH KV v2 挂载路径
VAULT_APPROLE_ROLE_ID / VAULT_APPROLE_SECRET_ID AppRole 凭据
VAULT_DATABASE_MYSQL_CONNECTION_NAME MySQL 连接名
VAULT_DATABASE_STATIC_ROLE_PREFIX Static Role 前缀
VAULT_DATABASE_ROTATION_PERIOD 密码轮换周期(默认 87600h = 10 年)

十一、凭据安全

11.1 SSH 凭据加密

SSHCredential 模型:

  • PrivateKeyCiphertext — PGP 加密的私钥
  • EncryptedDataKey — 加密的 DataKey
  • KnownHosts — 已知主机
  • HostKeyPolicy — 主机密钥策略

加密方案:

  • 生成随机 DataKey
  • 使用 DataKey 的 AES 密钥加密私钥
  • 使用 PGP 公钥加密 DataKey
  • 存储加密后的私钥和加密后的 DataKey

11.2 交付凭据

DeploymentCredential 模型:

  • Ciphertext — 加密的凭据
  • Nonce — 加密 nonce
  • Status — 状态(pending/revealed/expired)
  • ViewedBy — 查看者

凭证揭示:

  • POST /delivery/tasks/:id/credentials/reveal
  • 支持 JSON 和 XLSX 下载两种格式
  • 一次性揭示,标记为 revealed

11.3 临时文件安全

Ansible playbook 中的凭据处理:

# 创建临时文件
- tempfile:
    state: file
    suffix: .cred
  register: cred_file

# 写入凭据
- copy:
    content: "{{ password }}"
    dest: "{{ cred_file.path }}"
    mode: '0600'

# 使用后清理
- file:
    path: "{{ cred_file.path }}"
    state: absent

使用 mktemp + chmod 600 + trap 模式,避免命令行泄露。


十二、Wayne 服务间签名

12.1 签名方案

算法: HMAC-SHA256

签名 Payload:

METHOD\nURI\nTIMESTAMP\nNONCE\nBODY_SHA256

Headers:

  • X-Wayne-Service — 服务名
  • X-Wayne-Timestamp — 时间戳
  • X-Wayne-Nonce — 随机 nonce
  • X-Wayne-Signature — HMAC-SHA256 签名

12.2 验签

  • 常量时间比较(hmac.Equal),防止时序攻击
  • 校验时间戳有效期

十三、安全配置汇总

13.1 传输安全

  • K8s 内部通信使用 HTTP(Service DNS)
  • 外部访问通过 NodePort 暴露
  • SAML SP 证书路径可配置

13.2 认证安全

  • JWT Token 有效期可配置(默认 120 分钟)
  • Token 吊销通过 Redis 实现
  • SAML 加密断言支持 RSA-OAEP + AES-CBC/GCM
  • OAuth Code 一次性使用(Redis SetNX + 消费)

13.3 数据安全

  • SSH 凭据 PGP + AES 加密
  • 交付凭据 AES 加密 + 一次性揭示
  • Vault 集成实现密钥自动化管理
  • 数据库密码定期轮换(默认 10 年)

13.4 访问控制

  • 三级 RBAC:平台级 → 业务线级 → 子系统级
  • 路由级权限控制(路由守卫四级检查)
  • API 级权限控制(AuthMiddleware + 业务逻辑校验)
  • 全链路审计日志

💡 安全设计原则

  • 纵深防御: 传输层(NodePort)→ 认证层(JWT/SAML/OAuth)→ 授权层(三级 RBAC)→ 审计层(全链路日志)
  • 最小权限: SSH 凭据 PGP 加密、交付凭据一次性揭示、Vault 自动轮换
  • 零信任: OAuth Code 一次性消费、Token 吊销、常量时间签名验证防时序攻击