Skip to content

Plugin Secrets

worable edited this page Oct 12, 2026 · 1 revision

密钥存储

插件可能需要存储敏感信息(如第三方 API Key、OAuth Client Secret)。StackPanel 提供插件命名空间的加密密钥存储。

接口

interface PluginSecrets {
  isAvailable(): boolean;
  get(key: string): Promise<string | null>;
  set(key: string, value: string): Promise<void>;
  remove(key: string): Promise<void>;
}

通过 PluginContext 注入:ctx.secrets。

命名空间隔离

每个插件的密钥自动加前缀 plugin.<pluginId>.,由内核强制执行。插件只能读写自己的命名空间,无法访问其他插件的密钥。

// 插件 my-plugin 调用 ctx.secrets.get('api_key')
// 实际存储键:plugin.my-plugin.api_key

加密机制

  • 算法:AES-256-GCM
  • 格式:iv.tag.ciphertext(base64)
  • 随机 IV + 认证标签,密文非确定性且防篡改
  • 密钥从环境变量 SETTINGS_ENCRYPTION_KEY 经 SHA-256 派生

使用示例

onActivate: async (ctx) => {
  if (!ctx.secrets.isAvailable()) {
    ctx.logger.warn('加密密钥存储未配置,请设置 SETTINGS_ENCRYPTION_KEY');
    return;
  }

  // 读取密钥
  let apiKey = await ctx.secrets.get('api_key');
  if (!apiKey) {
    ctx.logger.warn('API Key 未配置');
    return;
  }

  // 存储密钥
  await ctx.secrets.set('api_key', 'sk-xxxxxxxxxxxxx');

  // 删除密钥
  await ctx.secrets.remove('api_key');
},

密钥键格式

密钥键(key)必须匹配:/^[a-z0-9][a-z0-9._-]{0,63}$/。即小写字母、数字开头,可包含点、下划线、短横线,最长 64 字符。

前置条件

加密密钥存储需要配置 SETTINGS_ENCRYPTION_KEY 环境变量(≥32 字符)。如果未配置:

  • isAvailable() 返回 false
  • get() 返回 null
  • set() 抛出错误
  • remove() 静默跳过

管理后台密钥

除了插件命名空间密钥,管理员还可以通过 PUT /admin/secrets/:key 存储全局密钥。这些密钥使用相同的加密机制,但键名无前缀,由管理员直接管理。

插件密钥不应通过管理后台接口设置——应使用 ctx.secrets,确保命名空间隔离。

Clone this wiki locally