Skip to content

feat(workflow): allow using references for secret fields - #7995

Open
Nixieboluo wants to merge 14 commits into
labring:mainfrom
Nixieboluo:feat/more-params-ref
Open

Nixieboluo wants to merge 14 commits into
labring:mainfrom
Nixieboluo:feat/more-params-ref

Conversation

@Nixieboluo

Copy link
Copy Markdown
Collaborator

Context

Workflow users need to connect existing variables to password inputs, tool parameters, and HTTP/MCP authentication headers without converting references into encrypted or static values. The change preserves existing configurations while making reference selection explicit in workflow-aware editors.

Description

This branch introduces a structured secret-value protocol with strict static and reference branches: { value }, { secret }, and { ref: tuple | tuple[] }. Legacy { value?, secret? } pairs are normalized before canonical validation. Workflow editors expose manual/reference modes, reference values bypass encryption, and Runtime resolution reuses existing type conversion and scalar validation.

Changes in the codebase

  • Added strict secret schemas and shared helpers for static values, encrypted values, and structured references.
  • Added idempotent migration for legacy secret values across workflow inputs, system tool configs, selected tools, HTTP headers, and MCP tool sets.
  • Added Runtime reference resolution for HTTP tools, MCP tools, system tools, and nested tool configurations.
  • Added reference mode support for password workflow inputs.
  • Extended SecretInputModal to support manual/reference modes for secret, input, numberInput, switch, and select fields with type-aware reference filtering and conversion.
  • Extended HeaderAuthForm for Bearer, Basic, and custom header references while keeping header keys static.
  • Refined secret/value display states, edit controls, compact mode selectors, overflow handling, and key/value layout.
  • Updated configuration validation and added focused regression coverage for schemas, migration, Runtime resolution, HeaderAuthForm, and SecretInputModal behavior.

Changes outside the codebase

  • Persisted workflow values are normalized to { secret: '<ciphertext>' }, { value: '<plain value>' }, or { ref: ['nodeId', 'outputId'] }.
  • HTTP and MCP tool API schemas and examples now describe the canonical secret/reference value shapes.

Aditional information

The first UI iteration exposes single-tuple selection while retaining tuple-array compatibility in the schema and Runtime. Reference pickers are injected only when workflow context is available, so management and configuration pages keep their static-input boundary; invalid-reference handling remains aligned with the existing editor/runtime behavior.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

✅ Admin Preview Image Ready!

ghcr.io/labring/fastgpt-pr:admin_4172e434a24f83baae6aee0bfa1777b0fd091c6b

🕒 Time: 2026-10-23 17:51:12 (UTC+8)

@c121914yu c121914yu self-assigned this Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

✅ Build and publish successful - Preview fastgpt Image:

ghcr.io/labring/fastgpt-pr:fastgpt_4172e434a24f83baae6aee0bfa1777b0fd091c6b

🕒 Time: 2026-10-23 17:53:01 (UTC+8)

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 58.63% 6092 / 10389
🔵 Statements 58.19% 6430 / 11049
🔵 Functions 54.47% 1150 / 2111
🔵 Branches 52.88% 3267 / 6177
File CoverageNo changed files found.
Generated in workflow #4785 for commit 4172e43 by the Vitest Coverage Report Action

Signed-off-by: Nixieboluo <me@sagirii.me>
Signed-off-by: Nixieboluo <me@sagirii.me>
Signed-off-by: Nixieboluo <me@sagirii.me>

@c121914yu c121914yu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

基于 HEAD 85f694c0b5,按 upstream/main...HEAD 梳理了 55 个文件(+2089 / -403)。

本次变更将密钥统一为互斥的 { value }、{ secret }、{ ref },并打通编辑器、工作流迁移及 HTTP/MCP/系统工具运行时。上下游同步总体属于合理扩散,但共享解密和类型转换的语义变化影响了历史聊天、管理员配置及普通节点。已确认并复现 2 个 P1、2 个 P2 问题,详见行内评论,建议修复后再合并。

验证情况:

  • 局部 14 个文件、197 项测试通过。标准入口的 Service 阶段因 Mongo 内存实例启动超时中断;相关 Service/App 用例随后在跳过 Mongo 全局初始化的隔离配置下通过。
  • 只读脚本对比了变更前后行为,复现了旧密码读取为空、旧系统密钥失效及脱敏失效、普通 JSON 的 ref 字段触发迁移错误、普通对象跳过字符串转换。
  • 未运行全量测试、浏览器交互验证或最新主干合并后的验证。

测试缺口:部分历史兼容测试把 { value: '', secret } 样本直接替换成新格式,例如 packages/service/test/core/workflow/dispatch/variables.test.ts 的初始化用例。应保留旧格式回归,再补充新协议覆盖。

其他风格与范围建议:

  • HeaderAuthForm.tsx:110 使用了 t(condition ? keyA : keyB),请拆成两个静态 t('literal') 调用,保持与 i18n 清理脚本的约定一致。对应四套语言包目前均有 key。
  • 工作流工具 app/create、app/update 同时移除了 secretsVal 持久化,与引用能力无直接依赖,请说明原因或拆分。
  • 协议允许 ref: tuple[],但当前请求头和系统配置运行时会拒绝数组结果,请明确预期的兼容语义。

return val.value;
if (typeof val !== 'object' || val === null) return val;
if (hasSecretValueField(val, 'ref')) return val;
if (hasSecretValueField(val, 'value')) return getSecretValueField(val, 'value');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 保留旧密码对象的解密兼容

旧版本的正常持久化结果是 { value: '', secret: ciphertext }。这里改为只要存在 value 字段就返回,会把该结构及其 JSON 字符串形式都解密成空字符串,而不是原密码。新增的 workflow 迁移没有覆盖聊天变量;WorkflowVariableState.initConfiguredVariable 仍直接调用本函数,并把返回的空字符串重新加密为 storeValue。普通 password 输入的 input.value 也未在 migrateInputSecrets 中归一化。

已用同一旧对象对比:变更前返回原密码,当前返回 ''。请在历史数据读取边界先归一化旧结构,并覆盖旧聊天变量和密码输入默认值,避免升级后凭据失效或在后续保存时被空值覆盖。现有旧格式测试样本应保留。


if (typeof value.value === 'string' && value.value !== '') return value.value;
if (!isEncryptedValue(value)) return value.value ?? '';
if (hasSecretValueField(value, 'value') && hasSecretValueField(value, 'secret')) return '';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 系统密钥尚未迁移,不能直接丢弃双字段结构

变更前的 encryptSystemToolSecrets 正常生成 { secret: ciphertext, value: '' },这些值仍由 MongoSystemTool 的 secretsVal/inputListVal 经 SystemToolCodec 直接读取,没有经过 workflow 迁移。此处将双字段值直接解密为空,导致已有系统密钥失效;同文件的 isConfiguredValue 也将其判为未配置,使 maskSystemToolSecrets 原样返回密文对象,并在提交 masked 标记时删除旧字段。

已复现:旧对象运行时得到空密钥,mask 返回对象而非标记,保留 masked 字段的更新结果变成空配置。请在系统密钥读取、脱敏及保留旧值的边界统一兼容/归一化,或先完成该存储范围的迁移,再拒绝旧格式。

Comment on lines +19 to +21
if ('ref' in value) {
// 引用必须在迁移边界校验,避免空引用进入 canonical workflow。
return SecretRefValueSchema.parse(value);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 不要把任意业务 JSON 的 ref 字段当成密钥引用

migrateSelectedToolsSecrets 会对全部 tool.config 参数调用本函数,而这些参数允许普通业务 JSON。这里只判断存在 ref 就按严格密钥引用 schema parse,会把合法参数(例如 payload: { ref: 'main', repository: 'example' })判为非法,导致整个工作流迁移失败,影响版本读取、导入和发布。

已对比复现:基线正常保留上述 config,当前在这里抛出 Zod 错误。请根据输入定义或已知密钥容器限定迁移范围,避免将普通 JSON 字段解释为密钥协议;补充含 ref 字段的普通对象回归用例。


// Password check
if (valueType === WorkflowIOValueTypeEnum.string && isSecretValue(value)) return value;
if (valueType === WorkflowIOValueTypeEnum.string && isSecretValueLike(value)) return value;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 收窄密钥判断,保留通用字符串转换的原有语义

isSecretValueLike 仅判断对象是否包含 value、secret 或 ref,并不保证它是合法密钥 wrapper。用于通用 valueTypeFormat 后,普通对象也会跳过字符串转换。例如 valueTypeFormat({ value: 1, other: 'data' }, 'string') 在变更前返回 JSON 字符串,当前直接返回对象。

该函数用于所有节点运行参数和变量更新,不限于密码字段,因而对象/any 输出流向 string 输入时会破坏原有类型约定。请将特殊处理限制为明确的密钥形态或密码输入上下文,保持普通对象继续 JSON 序列化,并补充此边界测试。

Normalize JSON-encoded legacy records before migration and resolution. Persist system-tool secrets on create and update.
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

✅ Docs preview deployed

🔗 👀 Click here to visit preview

ghcr.io/labring/fastgpt-docs-pr:4172e434a24f83baae6aee0bfa1777b0fd091c6b

🕒 Time: 2026-10-23 17:49:18 (UTC+8)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants