9 · 配置与凭据

业务配置一律走配置中心的台账(ctx.infraConfig),读取顺序是 台账 > 插件代码内缺省;真实环境变量不参与业务配置。 本章讲清台账模型、消费方写法、读取顺序、引导配置与凭据红线。

一句话

运行期可调的项进台账,装配级的项进 patch,敏感的项放本地覆盖层或环境变量。 明文口令/密钥不得进 git 历史。

1. 台账模型:应用名 + key#

配置中心 kth-infra-configmanagement 是两级模型,落在一张表上:

  • 应用名(app):业务系统 / 插件的逻辑名,规则 [a-z][a-zA-Z0-9_-]*;它不是实体,随第一个配置项出现、随最后一个消失。
  • 配置项名(key):扁平键,规则 [a-zA-Z][a-zA-Z0-9._-]*,点号只是键名的一部分(不做层级)。
  • 值:标量字符串(类比 properties 文件),类型解析归消费方;单值上限 4096 字符。
应用名 ≠ 包名

台账应用名是消费方自定的逻辑名,未必等于插件包名。例如图像检测插件的包名是 kth-bus-image-detection,而台账应用名是 bus-image-detection。 消费方代码里的应用名常量必须与台账里登记的一致,否则读不到。

2. 消费方怎么写#

插件在 inject 里声明 infraConfig,然后在 apply 里取配置。 同步方法,不用 await;返回的是明文(加密项已由配置中心在加载时解密)。

jssrc/index.js · 读取业务配置
export const inject = ['infraConfig']

/** 台账应用名:与配置中心里登记的应用一致 */
const CONFIG_APP = 'bus-image-detection'

export function apply(ctx) {
  // get(app):整应用一次性拿 —— Record<string,string>;未登记 → {}
  const all = ctx.infraConfig.get(CONFIG_APP)

  // get(app, key):单个值 —— string | undefined
  const pdfUrl = ctx.infraConfig.get(CONFIG_APP, 'engine.pdf.url')

  // get(app, keys):只含命中的键 —— Record<string,string>
  const picked = ctx.infraConfig.get(CONFIG_APP, ['threshold', 'upload.maxBytes'])

  // 取值链:台账有则用台账,缺省值兜在插件代码里
  const endpoint = pdfUrl ?? 'http://127.0.0.1:8101'
}

3. 读取顺序(重点)#

配置中心在启动时把整张台账读成内存快照,此后同步只读;重启宿主即生效,运行期不刷新、不监听。三种取法的回退规则不同:

调用返回未命中时
get(app)该应用全部配置 Record<string,string>应用未登记 → {};不回退环境变量
get(app, key)string | undefined回退 process.env[key];仍无 → undefined
get(app, keys)只含命中键的 Record<string,string>逐个按上一条回退,未命中不出现在结果里
  • 台账优先于代码缺省:台账登记了就用台账;没登记才用插件代码里的默认值。
  • 整应用不回退:get(app) 无从知道应用有哪些键,台账是唯一真源。
  • 单键可回退:get(app, key) 未命中会查同名环境变量 —— 这是现场应急的旁路,不是常规配置通道。
  • 环境变量不参与业务配置:真实环境变量只放底座凭据与启动必需项(如 DSH_HOME)。业务配置不要靠环境变量分发,改用台账。

4. 引导配置:永不进台账#

配置中心自己那个库的连接参数与 SM4 密钥,属于引导配置:写在本插件 patch 的 config: 段(随包走,装进 profile 即生效),永不进台账;缺项回退 KTH_CONFIGMANAGEMENT_* 环境变量。

为什么不能进台账

读台账要先连库,连库参数又存在台账里,会形成自举死锁。因此 store 层硬拒绝 把引导配置登记为台账条目 —— 应用名不得取本插件自身标识(configManagement)。

yaml配置中心的 patch 行(引导配置随行携带)
- insert:
    - id: kth-infra-configmanagement
      name: ../../Infrastructure/infra-configmanagement/content/lib/index.js
      config:
        host: 10.0.0.10
        port: 5432
        database: tianqing
        user: kunlun
        password: <DB_PASSWORD>          # 支持占位符,真值只在本机
        secretKey: <32 位十六进制>       # SM4 密钥,128 位

引导配置是整条链上唯一还写在 patch 文件里的凭据;示例一律用占位符,真值只存在本机(见下一节)。

5. 首次在本机导入台账#

宿主起来后,若某个应用的台账还没登记,消费方读到的就是空 —— 需要先把连接参数等配置项导入一次。 导入接口收 .env 风格的 KEY=VALUE 文本,只增改不删。

text导入接口
POST http://127.0.0.1:3080/kth-infra-configmanagement/api/apps/basePermission/import
Content-Type: application/json

{ "text": "kind=postgres\nhost=<DB_HOST>\nport=5432\ndatabase=tianqing\nuser=kunlun\npassword=***" }

响应告知处理结果,逐行错误带行号与原因:

json响应
{ "created": 8, "updated": 0, "skipped": 0, "errors": [] }
  • # 开头的注释与空行忽略;首个 = 分隔,值原样保留。
  • 同名键覆盖值但不动加密标记;空赋值 KEY= 跳过并计入 skipped。
  • 口令项记得在控制台勾选「加密存储」—— 读出即明文,消费方不必再碰环境变量。

6. 凭据红线#

明文口令 / 密钥不得进 Git 历史

真值只允许放在三处:

  • gitignored 的本地覆盖层,如 kth-deploys/local-dev/dev-plugins.patch.yml(明文口令只允许出现在这里);
  • 环境变量 —— 只放底座凭据与启动必需项;
  • 台账 —— 敏感项勾「加密存储」,界面脱敏、入库加密。

接口出参一律脱敏为 ***;入参传 *** 或留空 = 保留原值(加密项不回显,界面无法预填,改别的字段时不必重输)。

加密的边界

台账的 SM4-GCM 加密只防界面窥视 —— 同时拿到库与密钥的人仍可解密,不等于「安全存储」。 边界表述不得写成「已安全存储」。

7. 小结:配置该放哪#

配置类型放哪例子
运行期可调项台账(ctx.infraConfig,改后重启生效)引擎端点、阈值、上传限额、模板
装配级项patch 文件(insert 行的 config: / disabled)加载哪个插件、MCP 连接器端点
敏感值(口令 / 密钥)本地覆盖层 / 环境变量 / 台账加密项三者之一数据库口令、SM4 密钥、Bearer
底座启动必需项环境变量DSH_HOME
代码内缺省插件源码(最低优先,台账优先)未登记时的兜底默认值
下一步

打包发布与现场常见问题见 10 · 打包发布与 FAQ。