Skip to content

sign-kms · 模块详解 ​

本仓库 submodule:sign-kms/。本章引用的所有路径均为相对于该 submodule 根。

cmd/kms/ ​

文件关键符号行号
main.gomain():flag→config→signet→wireApp→app.Run35, 76-126
wire.gowireApp() providers24-32

main() 详细顺序见 核心流程 · Server 启动。

internal/conf/ ​

文件关键 message
conf.protoBootstrap(8-13)、Server(55-66:network/addr/timeout/http_addr/web_dist_path/tls/https)、TLS(68-78)、Data(80-86)、HSM(51-53)、HSMProvider(39-49)、Observability(15-24,含 Metrics/Tracing/Logging 子 message 26-37)

make config 生成 conf.pb.go。

internal/server/ ​

文件关键符号行号
grpc.goNewGRPCServer、中间件链 recovery → signet → GrpcAuthMiddleware → audit、RegisterKmsServiceServer23-56, 26-28, 54
grpc.gomTLS 配置(条件 Tls.Enable=true && CaFile 非空)44-51, 82
http.goNewHTTPServer、中间件 recovery → signet → logging、HttpAuthMiddleware、RegisterKmsManageServiceHTTPServer、obs.RegisterRoutes45-98, 49-51, 56, 70, 73
http.go静态文件(嵌入式 + SPA fallback)22-43, 76-95

internal/service/ ​

文件RPC 方法行号
kms_service.goGenerateKeypair、GetPublicKey、Sign、Verify、HealthCheck20-29 / 31-40 / 42-60 / 62-78 / 80
kms_manage_service.goSignin、Signout、Current、CreateNs、GetAccessToken(共 14 个 RPC)26-47 / 49-59 / 61-67 / 69-86 / 88-102

完整 HTTP RPC 列表见 06-api · HTTP 端点。

internal/biz/ ​

kms_biz.go ​

来源:internal/biz/kms_biz.go。

方法行号
NewKmsBiz42
partitionMu(per-partition mutex)51
resolveNamespace(缓存 + DB 查询)58
invalidateNamespace73
getSession(从分区 pool 借会话)79
getProviderContext105
CloseAllSessions118
PoolStatus123
GenerateKeyPair143
GenerateKeyPairForPartition161
Sign268
Verify320
GetPublicKey373

GenerateKeyPairForPartition 核心步骤(:161-264):

  • per-partition mutex 锁(:170-172)
  • 重试最多 3 次,失败丢弃坏会话(:192-213)
  • 公钥字节提取(:218)→ raw EC 点 → sha256 → finalId hex(:226-232)
  • 设置 CKA_LABEL = CKA_ID = finalId(:234-244)
  • DB 落盘:algorithm=EC、curve=P-256、可选 tag(:246-261)

kms_manage_biz.go ​

来源:internal/biz/kms_manage_biz.go。

方法行号
NewKmsManageBiz45
CreateNs(路由到 soft / hardware)54
createSoftNs69
createHardwareNs110
ListProviders206
GetAccessToken212
GetNamespaceInfo295
ListNamespaces323
CreateKey377
SyncKeys404
ListAccessTokens495
DisableAccessToken509
EnableAccessToken516
UpdateAccessTokenKeys541
ListKeys565
ValidateCredentials582

Token 签发关键步骤(GetAccessToken,:251-279):

  • tokenID = "at_" + 12 位随机字母数字(:254)
  • 先写 AccessToken DB(DB 是权威),再签 JWT(:258-266)
  • JWT claims 含 ID (JTI)、Subject、IssuedAt、ExpiresAt、PartitionID = ns.TokenLabel、Role、Keys(:270-279)

其它 ​

文件用途
biz.goProviderSet:NewKmsBiz、NewObservableKmsBiz、NewKmsManageBiz
kms_observable.goObservableKmsBiz 包装 KmsBiz,叠加 OTEL 指标;KmsService 依赖此对象(NewObservableKmsBiz:30)

SKI 推导(extractRawECPoint / getPublicKeyBytes)在 kms_biz.go 内,单测见 ski_test.go。

internal/data/ ​

Repository 模式包装 Ent client。

Ent schema(internal/data/ent/schema/) ​

文件实体行号
namespace.goNamespace(id / name / token_label / user_pin / so_pin / provider_id / description / 时间戳)18-51
keypair.goKeypair(id / tag / algorithm / curve / public_key / public_key_pem / key_type / status / namespace_id / metadata / 时间戳)30-75
user.goUser(username / password_hash / is_active / 时间戳)15-25
access_token.goAccessToken(id=JTI / subject / role / keys / status / namespace_id / expires_at / 时间戳)25-57

关键设计点:

  • Keypair.id 由服务器从公钥点 sha256 推导(keypair.go:18-23),既是主键也是 HSM CKA_LABEL/CKA_ID。
  • AccessToken.keys 第 37-39 行注释明确:DB 是权威源,JWT 中的 keys 仅供参考;DB 修改可立即在下次请求生效(由 pkg/auth/grpc_auth.go:62-74 覆盖)。

初始化 ​

文件用途
init_user.go首次启动管理员账号(读 DEFAULT_ADMIN_PWD env)

pkg/pkcs11/ ​

文件关键符号行号
registry.goProviderInstance、ProviderRegistry、NewProviderRegistry、register14-26 / 60-64 / 68-92 / 102
session_pool.goSessionPool、PoolStatus、NewSessionPool、DefaultPoolSize=5、MaxPoolSize=30、HealthCheckInterval=30s24-41 / 44-50 / 54-95 / 18-20

Borrow / Return / Discard / WarmupHandleCache 具体行号 [未核]。

pkg/auth/ ​

文件关键符号行号
claims.goKMSClaims、RoleReadonly、RoleReadWrite、RoleAdmin、roleOps、RoleAllows11-22 / 26-28 / 42-46 / 49
grpc_auth.goGrpcAuthMiddleware、token 解析、TokenStore.GetByJTI 覆盖 keys48 / 49-80 / 62-74
http_auth.goHttpAuthMiddleware、白名单 /api/v1/signin27 / 28-56
config.goCookieName、GetAuthSecret(未设置 panic)、DefaultExpiry=24h、DefaultTokenExpiry=365d、MaxTokenExpiry=730d15 / 38, 44 / 55 / 58 / 60

api/v1/ ​

文件serviceRPC
kms.protoKmsService(行 7-13)GenerateKeypair、GetPublicKey、Sign、Verify、HealthCheck(行 8-12)
manage.protoKmsManageService(行 11-81)14 个 RPC(含 google.api.http 注解)

完整 HTTP 路径与请求类型见 06-api · HTTP 端点。

p11client/ ​

来源:p11client/。

文件用途
kms_so.cPKCS#11 代理实现,定义 68 项标准函数表;另有自定义辅助函数 C_GetPublicKey
grpc_client_helper.c / .hgRPC 客户端辅助
proto/kms.pb-c.c / .hprotobuf-c 生成
include/pkcs11.h / pkcs11t.h / pkcs11f.hPKCS#11 标准头
test_pkcs11.c / simulation_test.c / known_key_test.c测试

kms_so.c 的 CK_FUNCTION_LIST 暴露 68 个标准 PKCS#11 C_* 函数。其中与 KMS 操作相关的为实质实现,按源码顺序:C_Initialize / C_Finalize / C_GetInfo / C_GetFunctionList / C_GetSlotList / C_GetSlotInfo / C_GetTokenInfo / C_GetMechanismList / C_GetMechanismInfo / C_InitToken / C_InitPIN / C_SetPIN / C_OpenSession / C_CloseSession / C_CloseAllSessions / C_GetSessionInfo / C_Login / C_Logout / C_GenerateKeyPair / C_SignInit / C_Sign / C_GetAttributeValue / C_SetAttributeValue / C_FindObjectsInit / C_FindObjects / C_FindObjectsFinal / C_VerifyInit / C_Verify。其余函数(加解密、摘要、Wrap/Unwrap、随机数等)为桩实现,返回 CKR_FUNCTION_NOT_SUPPORTED;源码还定义了不在标准函数表中的自定义辅助函数 C_GetPublicKey。

环境变量(kms_so.c):

  • KMS_SO_DEBUG(:39)
  • SIGN_KMS_ENDPOINT(:202)

web/ ​

项值
框架React 19.2.0、React Router 7.10.1
样式Tailwind CSS 4.1.18(via @tailwindcss/vite)
UIshadcn/ui(Radix + Tailwind)
构建rolldown-vite 7.2.5
Scripts(package.json)dev、build、lint、preview、ui

scripts/ ​

脚本用途
init-softhsm.sh创建 7 个测试 partition + EC P-256 密钥(见 03-quickstart)

docs/ ​

来源:docs/ 目录。

  • design-multi-hsm-provider.md — HSM Provider 层多后端支持设计
  • design-p11client-v2.md — PKCS#11 代理库设计
  • grafana/sign-kms-overview.json — Grafana 仪表板定义

具体设计文档内容 [未核]。

看代码推荐路径 ​

  1. cmd/kms/main.go → wire.go 了解依赖链。
  2. internal/server/grpc.go + http.go → 看中间件链与服务注册。
  3. 任选一个端到端:internal/service/kms_service.go:Sign → internal/biz/kms_biz.go:Sign(268) → getSession(79) → pkg/pkcs11/session_pool.go:Borrow。
  4. 管理面:internal/service/kms_manage_service.go:GetAccessToken → internal/biz/kms_manage_biz.go:GetAccessToken(212)。
  5. pkg/auth/grpc_auth.go:48-80 → 看 JWT 解析与 DB 覆盖。
  6. internal/data/ent/schema/*.go → DB 实体定义。
  7. p11client/kms_so.c → 想懂客户端 .so 时再读。