mcpField
V
vtex-io-app-settings

vtex-io-app-settings

github.com/vtex开发471.2k 次安装2 周前更新
代码仓库

关于 vtex-io-app-settings

这是面向 VTEX IO 开发者的技能,帮助设计和审查应用设置边界。内容涵盖设置模式、运行时读取、默认值验证与敏感信息保护。

主要功能

  1. 01区分应用设置与区块配置
  2. 02用 JSON Schema 定义设置
  3. 03验证或补齐缺失配置
  4. 04将密钥限制在后端
  5. 05判断设置与配置应用的适用场景

适用场景

  1. 01为商家定义可管理的应用选项
  2. 02审查设置是否应按页面或区块变化
  3. 03实现安全的密钥读取与使用
  4. 04排查工作区设置缺失或不一致

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vtex/skills --skill vtex-io-app-settings

安装后在 Claude Code 中输入/vtex-io-app-settings确认已加载。

详细介绍

应用设置与配置边界

何时使用此技能

在决定或实现 VTEX IO 应用应如何公开可配置设置时,使用此技能。

  • 定义 settingsSchema
  • 添加商家可配置的应用行为
  • 审查配置应属于应用设置还是自定义数据
  • 在应用代码中读取和验证设置

请勿将此技能用于:

  • service.json 中的运行时基础设施设置
  • Master Data 实体设计
  • 策略声明详情
  • 路由身份验证建模

决策规则

  • 对于商家或运营人员应能明确管理的稳定配置,请使用应用设置。
  • 对于通过 VTEX Admin 管理的应用级配置,请使用 settingsSchema;对于因页面或区块实例而异的 Store Framework 区块配置,请使用 store/contentSchemas.json。
  • 如果某个值适用于整个应用或账户,通常应放在 settingsSchema 中。如果它因页面、区块或主题组合而异,通常应放在 contentSchemas.json 中。
  • 请勿将应用设置用作高容量运营数据的替代存储。
  • 请明确使用 JSON Schema 的 properties、required、default、enum、format 及相关约束,而不要只使用通用的根级 type: object。
  • 仅对非敏感且有意通过 publicSettingsForApp 安全地向前端代码公开的值,使用 settingsSchema.access: "public"。
  • 如果省略 access,请勿假设前端 GraphQL 消费者可以读取这些设置。必须明确选择是否允许前端公开访问。
  • 对于 API 密钥、令牌和机密,请使用应用设置,而不要将它们硬编码在代码库中。
  • 切勿在 HTTP 响应、GraphQL 响应、HTML 或浏览器端属性中直接公开应用设置中的机密。
  • 也切勿在日志中公开应用设置中的机密。
  • 对于 API 密钥或密码等敏感字段,请将其设为 type: "string",并考虑将其标记为 format: "password"。某些平台消费者(例如使用 hidePasswords 时的 Apps GraphQL)可能会利用此元数据屏蔽响应中的值。不要将其视为唯一的安全层:机密仍必须仅供后端使用,绝不能出现在响应或日志中。
  • 某些渲染器可能支持 ui:widget: "password" 等 UI 专用提示,但它们不属于核心 JSON Schema 保证。不要假设标准 VTEX Admin App Settings UI 会强制执行这些提示。
  • 使用 ctx.clients.apps.getAppSettings(ctx.vtex.appId ?? process.env.VTEX_APP_ID) 读取后端设置,并在辅助函数中集中处理规范化或验证,而不要在各个处理程序中分散使用临时访问模式。
  • 在运行时读取或保存此应用自身的设置时,请使用正确的应用标识符,例如 process.env.VTEX_APP_ID 或 ctx.vtex.appId,并依赖应用令牌和标准应用设置权限。不要在 manifest.json 中声明额外的 License Manager 策略,也不要添加 read-workspace-apps 之类的工作区级策略或 write-workspace-apps 之类未公开文档的策略,来“修复” 403 错误。
  • 需要配置的 Pixel 应用也应在其后端使用 ctx.clients.apps.getAppSettings(...) 读取设置。如果注入的 JavaScript 必须使用某个值,只能通过 access: "public" 和 publicSettingsForApp 暴露非敏感字段,并严格将机密保留在服务端。
  • 请在设置缺失或不完整时,通过验证或在使用时应用默认值,使代码具备韧性。
  • 切勿假设不同账户或工作区中的设置完全相同。在开发、发布或调试期间,各个工作区可能具有不同的应用配置。

设置与配置构建器:

  • 如果配置仅适用于此应用,且预期由商家在 Apps > App Settings 中编辑,请使用 settingsSchema。
  • 如果配置契约需要在多个应用间共享、需要与运行时应用生命周期分开管理,或需要通过 ctx.vtex.settings 直接注入服务上下文,请考虑使用单独的应用和 configuration 构建器。
  • 如果主要目标是通过 VTEX IO 运行时上下文提供结构化服务配置,而不是由应用自行临时获取设置,请优先选择配置应用。

硬性约束

约束:可配置的应用行为必须有 schema

商家可配置的设置必须通过明确的 schema 建模,而不是使用未经验证的临时对象。

原因

没有 schema,配置就会变得含糊、难以验证,也更容易在不同环境中出错。

检测

如果代码依赖应用级配置,但不存在 schema 或验证约定,请停止并先定义它。

正确

{
  "settingsSchema": {
    "title": "My App Settings",
    "type": "object",
    "properties": {
      "enableModeration": {
        "title": "Enable moderation",
        "type": "boolean",
        "default": false,
        "description": "If true, new content will require approval before going live."
      },
      "apiKey": {
        "title": "External API key",
        "type": "string",
        "minLength": 1,
        "description": "API key for the external moderation service.",
        "format": "password"
      },
      "mode": {
        "title": "Mode",
        "type": "string",
        "enum": ["sandbox", "production"],
        "default": "sandbox"
      }
    },
    "required": ["apiKey"]
  }
}

错误

const settings = ctx.state.anything
约束:敏感设置必须仅限后端使用,不得暴露给前端

应用设置中存储的密钥(例如 API 密钥、令牌或密码)必须作为仅限后端使用的配置处理。

原因

应用设置是存放密钥的常见位置,但如果通过 HTTP 响应、GraphQL 载荷、HTML 或前端属性暴露这些密钥,就会造成配置泄露。

检测

如果路由、解析器或面向前端的响应返回原始设置,或包含设置中的敏感字段,请停止,并将外部调用或密钥使用完全移至后端边界。

正确

const { apiKey } = await ctx.clients.apps.getAppSettings(
  ctx.vtex.appId ?? process.env.VTEX_APP_ID
)
const result = await externalClient.fetchData({ apiKey })

ctx.body = result

错误

const settings = await ctx.clients.apps.getAppSettings(
  ctx.vtex.appId ?? process.env.VTEX_APP_ID
)
ctx.body = settings
约束:公开的应用设置访问绝不能暴露敏感配置

如果将 settingsSchema.access 设为 public,那么通过 publicSettingsForApp 暴露的设置必须仅包含适合发送到前端代码的值。

原因

access: "public" 是一种交付方式,而非安全控制。一旦设置被公开,店面或前端代码就可以读取它们,因此绝不能在其中包含密钥或仅限后端使用的配置。

检测

如果设置 schema 将访问权限标记为公开,却包含 API 密钥、令牌、密码或任何仅用于后端集成的值,请停止并将这些设置设为私有。

正确

{
  "settingsSchema": {
    "title": "Public Storefront Settings",
    "type": "object",
    "access": "public",
    "properties": {
      "bannerText": {
        "title": "Banner text",
        "type": "string"
      }
    }
  }
}

错误

{
  "settingsSchema": {
    "title": "My App Settings",
    "type": "object",
    "access": "public",
    "properties": {
      "apiKey": {
        "title": "External API key",
        "type": "string",
        "format": "password"
      }
    }
  }
}
约束:不得将设置用作业务数据存储

应用设置必须表示配置,而非大量可变记录。

原因

设置用于配置边界,而非事务性或大规模的业务数据。

检测

如果拟议的设置要存储类似订单、评价、日志或队列项目的记录,请停止,并将其转移到更合适的数据机制中。

正确

{
  "enableModeration": true
}

错误

{
  "allReviews": []
}
约束:代码必须在使用边界验证设置或提供默认值

依赖设置的代码必须能够安全处理缺失或不完整的值。

原因

不同工作区和账户之间的配置可能存在差异。假定所有设置都存在的代码会变得脆弱。

检测

如果代码读取设置时假定必填字段始终存在,却没有验证或默认值,请停止并明确处理此依赖。

正确

const rawSettings = await ctx.clients.apps.getAppSettings(
  ctx.vtex.appId ?? process.env.VTEX_APP_ID
)
const settings = normalizeSettings(rawSettings)
const enabled = settings.enableModeration ?? false

错误

const enabled = settings.enableModeration.value

首选模式

使用设置存储稳定、由商家管理的配置,使用明确的 JSON Schema 属性定义设置,并在使用时进行验证或规范化。 对于密钥,应在后端读取密钥并发起外部调用,只向前端返回业务结果。 仅对有意公开的设置使用前端 GraphQL 访问,并通过 getAppSettings(...) 将仅限后端使用的设置保留在后端。

常见故障模式

  • 将设置用作运行时存储。
  • 只使用 type: object,却不显式声明 properties 和验证细节。
  • 读取设置时不设置默认值或进行验证。
  • 向前端暴露原始设置或机密信息。
  • 设置包含仅供后端使用的值或敏感值时,将其标记为 access: "public"。
  • 以纯文本形式记录设置或机密信息。
  • 将 API 密钥或令牌硬编码,而不是存储在应用设置中。
  • 遇到应用设置权限错误时,将 read-workspace-apps 等工作区级策略或 write-workspace-apps 等无效策略作为通用变通方案,而不是验证正确的 appId 和标准应用设置权限。
  • 需求实际是区块级 Store Framework 配置时,却使用 settingsSchema。
  • 创建范围过宽或含糊不清的架构。

审查清单

  • 这些数据确实应该属于应用设置吗?
  • settingsSchema 是否声明了带明确类型的 properties,并且仅在必要时将属性设为 required?
  • 敏感字段是否以安全的方式表示,例如使用 format: "password" 的 string 字段,并了解某些使用者(如带有 hidePasswords 的 Apps GraphQL)可能会利用这些元数据来隐藏输出?
  • 使用这些设置的代码是否会验证缺失值或提供默认值?
  • 机密信息是否仅供后端使用,且绝不暴露给前端?
  • 如果使用了 access: "public",所有公开的设置是否都确认可安全地供前端使用?
  • 设置的范围是否精简且经过审慎设计?

参考资料

评论

支持 Markdown