跳转至

密钥集成示例

Exec 集成示例

此页面汇集了可用的集成示例:用于外部机密管理器的 exec 提供程序方案、MCP 服务器环境变量,以及沙箱 SSH 认证材料。

1Password
{
  plugins: {
    entries: {
      onepassword: {
        enabled: true,
      },
    },
  },
  secrets: {
    providers: {
      onepassword: {
        source: "exec",
        pluginIntegration: {
          pluginId: "onepassword",
          integrationId: "onepassword",
        },
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: {
          source: "exec",
          provider: "onepassword",
          id: "op://Engineering/OpenAI/apiKey",
        },
      },
    },
  },
}

捆绑的 1Password 插件 使用官方的 op CLI 以及该插件的服务账户令牌文件。

Bitwarden Secrets Manager (bws)

使用一个解析器包装器将 SecretRef id 映射到 Bitwarden Secrets Manager 条目键。仓库中包含 scripts/secrets/openclaw-bws-resolver.mjs;请将其安装或复制到运行 Gateway 的主机上的一个绝对可信路径。

要求:

  • 在 Gateway 主机上安装 Bitwarden Secrets Manager CLI(bws)。
  • Gateway 服务可访问 BWS_ACCESS_TOKEN。
  • 将 PATH 传递给解析器,或将 BWS_BIN 设置为 bws 二进制的绝对路径。
  • 使用自托管的 Bitwarden 实例时,在环境中设置 BWS_SERVER_URL。
{
  secrets: {
    providers: {
      bws: {
        source: "exec",
        command: "/usr/local/bin/openclaw-bws-resolver.mjs",
        passEnv: ["BWS_ACCESS_TOKEN", "BWS_SERVER_URL", "PATH", "BWS_BIN"],
        jsonOnly: true,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: {
          source: "exec",
          provider: "bws",
          id: "openclaw/providers/openai/apiKey",
        },
      },
    },
  },
}

解析器会批量处理所请求的 id,运行 bws secret list,并返回与 secret 的 key 字段匹配的值。请使用满足 exec SecretRef id 约定的键,例如 openclaw/providers/openai/apiKey;带有下划线的环境变量风格键会在解析器运行前被拒绝。如果多个可见的 Bitwarden 机密共享所请求的键,解析器会将该 id 视为不明确而失败,而不会进行猜测。更新配置后,请验证解析器路径:

openclaw secrets audit --allow-exec
HashiCorp Vault CLI
{
  secrets: {
    providers: {
      vault_openai: {
        source: "exec",
        command: "/absolute/non-symlink/path/to/vault",
        trustedDirs: ["/absolute/non-symlink/path/to"],
        args: ["kv", "get", "-field=OPENAI_API_KEY", "secret/openclaw"],
        passEnv: ["VAULT_ADDR", "VAULT_TOKEN"],
        jsonOnly: false,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: { source: "exec", provider: "vault_openai", id: "value" },
      },
    },
  },
}
password-store (pass)

使用一个小型解析器包装器将 SecretRef id 直接映射到 pass 条目。请将其保存为可执行文件,放在能够通过你的 exec 提供程序路径检查的绝对路径下,例如 /usr/local/bin/openclaw-pass-resolver。#!/usr/bin/env node shebang 会从解析器进程的 PATH 中解析 node,因此请在 passEnv 中包含 PATH。如果 pass 不在该 PATH 中,请在父环境中设置 PASS_BIN,并将其也包含在 passEnv 中:

#!/usr/bin/env node
const { spawnSync } = require("node:child_process");

let stdin = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
  stdin += chunk;
});
process.stdin.on("error", (err) => {
  process.stderr.write(`${err.message}\n`);
  process.exit(1);
});
process.stdin.on("end", () => {
  let request;
  try {
    request = JSON.parse(stdin || "{}");
  } catch (err) {
    process.stderr.write(`Failed to parse request: ${err.message}\n`);
    process.exit(1);
  }

  const passBin = process.env.PASS_BIN || "pass";
  const values = {};
  const errors = {};

  for (const id of request.ids ?? []) {
    const result = spawnSync(passBin, ["show", id], { encoding: "utf8" });
    if (result.status === 0) {
      values[id] = result.stdout.split(/\r?\n/, 1)[0] ?? "";
    } else {
      errors[id] = { message: (result.stderr || `pass exited ${result.status}`).trim() };
    }
  }

  process.stdout.write(JSON.stringify({ protocolVersion: 1, values, errors }));
});

然后配置 exec 提供程序,并将 apiKey 指向 pass 条目路径:

{
  secrets: {
    providers: {
      pass_store: {
        source: "exec",
        command: "/usr/local/bin/openclaw-pass-resolver",
        passEnv: ["PATH", "HOME", "GNUPGHOME", "GPG_TTY", "PASSWORD_STORE_DIR", "PASS_BIN"],
        jsonOnly: true,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: {
          source: "exec",
          provider: "pass_store",
          id: "openclaw/providers/openai/apiKey",
        },
      },
    },
  },
}

将密钥保存在 pass 条目的第一行,或者自定义包装器以返回完整的 pass show 输出。更新配置后,验证静态审计和 exec 解析器路径:

openclaw secrets audit --check
openclaw secrets audit --allow-exec
sops
{
  secrets: {
    providers: {
      sops_openai: {
        source: "exec",
        command: "/absolute/non-symlink/path/to/sops",
        trustedDirs: ["/absolute/non-symlink/path/to"],
        args: ["-d", "--extract", '["providers"]["openai"]["apiKey"]', "/path/to/secrets.enc.json"],
        passEnv: ["SOPS_AGE_KEY_FILE"],
        jsonOnly: false,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: { source: "exec", provider: "sops_openai", id: "value" },
      },
    },
  },
}

MCP 服务器环境变量

通过 plugins.entries.acpx.config.mcpServers 配置的 MCP 服务器环境变量接受 SecretInput,从而将 API 密钥和令牌保留在明文配置之外:

{
  plugins: {
    entries: {
      acpx: {
        enabled: true,
        config: {
          mcpServers: {
            github: {
              command: "npx",
              args: ["-y", "@modelcontextprotocol/server-github"],
              env: {
                GITHUB_PERSONAL_ACCESS_TOKEN: {
                  source: "env",
                  provider: "default",
                  id: "MCP_GITHUB_PAT",
                },
              },
            },
          },
        },
      },
    },
  },
}

纯文本字符串值仍然有效。类似 ${MCP_SERVER_API_KEY} 的环境模板引用和 SecretRef 对象会在网关激活期间、MCP 服务器进程生成之前解析。与其他 SecretRef 使用场景一样,未解析的引用仅在 acpx 插件实际生效时才会阻止激活。

沙箱 SSH 认证材料

核心 ssh 沙箱后端也支持将 SecretRefs 用于 SSH 认证材料:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",
        backend: "ssh",
        ssh: {
          target: "user@gateway-host:22",
          identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },
          certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },
          knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },
        },
      },
    },
  },
}

运行时行为:

  • OpenClaw 在沙箱激活期间解析这些引用,而不是在每次 SSH 调用时惰性解析。
  • 解析后的值会以严格的文件权限(0o600)写入临时目录,并用于生成的 SSH 配置中。
  • 如果有效的沙箱后端不是 ssh(或沙箱模式为 off),这些引用将保持非活动状态,并且不会阻止启动。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw