主题
sign-kms · 架构
组件分层
关键文件
| 组件 | 文件 | 行号 |
|---|---|---|
| Server 入口 | cmd/kms/main.go | 76-126 |
| Wire DI | cmd/kms/wire.go | 24-32 |
| gRPC 注册 | internal/server/grpc.go | 23-56 |
| HTTP 注册 | internal/server/http.go | 45-98 |
| KmsService | internal/service/kms_service.go | 20-80 |
| KmsManageService | internal/service/kms_manage_service.go | 26-100 |
| KmsBiz | internal/biz/kms_biz.go | 42-373 |
| KmsManageBiz | internal/biz/kms_manage_biz.go | 45-582 |
| ProviderRegistry | pkg/pkcs11/registry.go | 14-102 |
| SessionPool | pkg/pkcs11/session_pool.go | 18-95 |
| Auth Claims | pkg/auth/claims.go | 11-49 |
| gRPC Auth Middleware | pkg/auth/grpc_auth.go | 30-80 |
| HTTP Auth Middleware | pkg/auth/http_auth.go | 27-56 |
启动序列
来源:cmd/kms/main.go:76-126。
wireApp 的 providers(cmd/kms/wire.go:24-32):
server.ProviderSetbiz.ProviderSetservice.ProviderSetdata.ProviderSetpkcs11.NewProviderRegistrynewApp
gRPC 中间件链
来源:internal/server/grpc.go:26-28。
recovery → signet (tracing/metrics) → GrpcAuthMiddleware → audit服务注册:RegisterKmsServiceServer(srv, kmsSvr)(grpc.go:54)。
mTLS:当 Tls.Enable=true 且 CaFile 非空时启用客户端证书验证(grpc.go:44-51, 82)。
HTTP 中间件链
来源:internal/server/http.go:49-56。
recovery → signet (tracing/metrics) → logging
FilterFunc: HttpAuthMiddleware()注册:
RegisterKmsManageServiceHTTPServer(srv, svc)(http.go:70)- 静态文件:嵌入式
web/dist或文件系统,SPA fallback(http.go:22-43, 76-95) - 可观测路由:
obs.RegisterRoutes(srv)注册/healthz、/readyz(http.go:73)
ProviderRegistry
来源:pkg/pkcs11/registry.go。
| 项 | 行号 |
|---|---|
ProviderInstance struct(ID、Name、Type、LibPath、Enabled、Ready、PoolSize、ctx、pools、mu) | 14-26 |
GetContext() | 29 |
GetPools() | 36 |
GetPoolSize()(取配置 pool_size 或 DefaultPoolSize=5) | 43-47 |
ProviderRegistry struct(mu、providers map、order []string) | 60-64 |
NewProviderRegistry(conf.HSM) | 68 |
| 至少 1 个 provider 可用才能继续 | 89-92 |
register 单个 provider 注册 | 102 |
SessionPool
来源:pkg/pkcs11/session_pool.go。
| 项 | 行号 / 值 |
|---|---|
SessionPool struct(tokenLabel、slotID、userPin、p11、pool chan、size、mu、closed、stopOnce、stopCh、OTEL 指标字段) | 24-41 |
PoolStatus struct(TokenLabel、SlotID、Reachable、AvailableSessions、TotalSessions) | 44-50 |
NewSessionPool —— 大小受限、预创建、启动 healthCheckLoop | 54-95 |
DefaultPoolSize | 5(line 18) |
MaxPoolSize | 30(line 19) |
HealthCheckInterval | 30 秒(line 20) |
其它方法(Borrow / Return / Discard / WarmupHandleCache) | 实现位置已部分定位,细节 [未核] |
JWT 与权限
来源:pkg/auth/claims.go:11-49。
go
type KMSClaims struct {
jwt.RegisteredClaims
PartitionID string
Role string
Keys []string
}角色映射(pkg/auth/claims.go:42-46,RoleAllows() 在 :49):
| Role | 允许的 operation |
|---|---|
readonly | get_public_key、verify |
readwrite | sign、verify、get_public_key |
admin | sign、verify、get_public_key、gen_keypair、sign_cert、sign_crl |
Auth 中间件细节
来源:pkg/auth/grpc_auth.go、pkg/auth/http_auth.go、pkg/auth/config.go。
gRPC(grpc_auth.go:48-80)
- 工厂签名:
GrpcAuthMiddleware(store)(:48),store可为nil。 - 流程:解析 Bearer → 验证 JWT 签名 / 过期 → 查
TokenStore.GetByJTI→ 若Disabled返回 Forbidden;否则用 DB 中的Keys覆盖 JWTclaims.Keys(:62-74)→ 注入到 context。
HTTP(http_auth.go:27-56)
- 仅检查
/api/*,白名单:/api/v1/signin(pkg/auth/config.go:11的NoAuthPaths)。 - 从 cookie 读 token →
ParseToken→jwt.NewContext。
密钥与 cookie
来源:pkg/auth/config.go。
| 项 | 默认 / 行号 |
|---|---|
| Cookie 名 | KMS_AUTH_COOKIE 或 access_token(line 15) |
SecureCookie | 由服务器设置(line 19) |
authSecretVal | 懒加载 KMS_AUTH_SECRET(line 22-44;未设置时 panic 在 :44) |
CookiePath | /(line 52) |
DefaultExpiry | 24 小时(管理后台 cookie)(line 55) |
DefaultTokenExpiry | 365 天(KMS access token)(line 58) |
MaxTokenExpiry | 730 天 hard cap(line 60) |
DB schema 一览
来源:internal/data/ent/schema/。
| Entity | 文件 | 关键字段 |
|---|---|---|
Namespace | namespace.go:18-51 | id (Unique, Immutable)、name (Unique)、token_label (Unique)、user_pin (Sensitive)、so_pin (Sensitive)、provider_id、description、时间戳 |
Keypair | keypair.go:30-75 | id (Unique, Immutable, SKI hex)、tag (MaxLen 128)、algorithm、curve、public_key、public_key_pem、key_type、status、namespace_id、metadata、时间戳;索引 tag+namespace_id |
User | user.go:15-25 | username (Unique)、password_hash、is_active、时间戳 |
AccessToken | access_token.go:25-57 | id (Unique, Immutable, JTI)、subject、role、keys (JSON array; 第 37-39 行注明 DB 为权威源)、status enum (active/disabled)、namespace_id FK、expires_at、时间戳 |
Keypair.id 设计(keypair.go:18-23)
id = hex(sha256(0x04||X||Y)),其中 X||Y 是 EC P-256 公钥原始点;同时作为 HSM CKA_LABEL / CKA_ID,不接受用户提供,由服务器计算。
性能数字
仅来自 README.md:119-129 的明文:
| 项 | 值 | 出处 |
|---|---|---|
| 单次签名 | ~100us、内存 328 B/op | README.md:119-129 |
| SoftHSM 天花板 | ~11,000 tps(pool=5 可达) | 同 |
| Luna S790 标称 | 22,000 tps(ECC P-256) | 同 |
这些为 README 自述数字,未独立基准。