本文围绕 MCP Server 的密钥管理展开,指出随着 LLM 与外部工具通过 MCP 连接,服务器往往会同时接触 API Key、数据库凭证等敏感信息,若采用硬编码、长期凭证或缺乏审计与访问控制,容易放大安全风险。文章给出四类实践:避免把密钥写死在代码里;对自定义服务器优先使用短生命周期的动态凭证;对现成 MCP 服务通过 CLI 在运行时注入密钥;并用策略隔离不同服务器的访问范围。整体强调,MCP 的安全底座不只是协议本身,密钥治理才是关键。
随着 MCP servers 在统一 LLM clients 与各种 tools/services 之间交互方面越来越受欢迎,它们正成为 AI applications 安全架构中的焦点。在 Infisical,我们一直密切关注这一趋势,并注意到一个经常被忽视的关键方面:secrets management。
Model Context Protocol (MCP) servers 充当 Large Language Models (LLMs)(例如 Claude 或 GPT)与外部 tools 或 services 之间的“智能” middleware。
不同于仅仅路由请求的传统 API servers,MCP servers 会将来自 LLMs 的自然语言请求转换为对 tools 的结构化操作,然后再将结果转换回 LLM 能够理解的格式。这是通过实现 Anthropic 的 open MCP protocol 来完成的,它为 LLMs 访问 databases、调用外部 APIs、执行 code 或与任何 service 交互提供了统一的 interface——而无需为每一种场景单独进行 custom integration。
MCP servers 的价值在于,它们将 LLM 的能力扩展到其 knowledge cutoff 和文本生成能力之外。它们使 LLMs 能够执行实时操作,例如检索当前数据、执行 transactions 或访问专有信息——同时无论底层 tools 如何,都能保持一致的交互模式。
对于已经熟悉 API gateways 或 proxy servers 的工程师来说,你可以把 MCP servers 理解为增加了一层语义层,它既理解 LLM 的意图,也知道如何将其转换为具体的 tool operations。并且由于它们作为 LLMs 与外部 services 之间的中介存在,因此需要处理敏感 credentials 才能运行。
大多数 MCP servers 需要同时处理 API keys、database credentials 以及其他 secrets 才能正常运行。由于它们充当 LLMs 与外部 services 之间的中介,因此经常会同时处理许多不同系统的敏感 credentials。
观察典型的 MCP implementations,我们注意到 secrets management 并不总是被明确处理,这带来了一些潜在的安全风险:

这看起来显而易见,但这种情况仍然会发生。
// 不要这样做
const API_KEY = "sk_1234567890abcdef";
// 相反,从环境变量或 secrets management 工具中加载
const API_KEY = process.env.WEATHER_API_KEY;
MCP servers 面临的一个挑战是,它们通常充当通往多个外部 services 的 gateway——这使它们成为攻击者的目标。
无论你是在构建自己的 MCP server,还是在运行像 npx -y weather-mcp 这样的预构建 server,你都可以通过利用像 Infisical 这样的现代 secrets management 解决方案来降低所需 credentials 的暴露面。
在构建 custom MCP Server 时,一个好的策略是实现 ephemeral credentials,也就是短生命周期且作用域限定到特定操作的凭证。通过按需生成 credentials,并限制其有效期,你可以确保即使 credentials 以某种方式被泄露,风险暴露的时间窗口也会很小。
Dynamic secrets 是短生命周期、会话特定的 keys,通过将暴露窗口最小化,提供了最佳的安全保障。它们非常适合像 database access 这样的场景,在这些场景中,你可能希望为查询生成只读 credentials,但在更新或 schema changes 时需要更高权限。
然而,并非所有 integrations 都支持 dynamic credentials,这也是我们仍然需要安全方法来处理 static secrets 的原因。下面的示例展示了这两种方式:在安全性至关重要的 database access 中使用 dynamic secrets,而对于不支持 ephemeral authentication 的 services,则安全地获取 static API keys。通过使用 Infisical SDK,server 避免了在代码中直接硬编码任何 secrets。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { InfisicalSDK } from "@infisical/sdk";
import { Client as PostgresClient } from "pg";
// ----- Infisical 初始化 -----
const infisicalClient = new InfisicalSDK({
siteUrl: "https://app.infisical.com"
});
await infisicalClient.auth().universalAuth.login({
clientId: process.env.INFISICAL_CLIENT_ID,
clientSecret: process.env.INFISICAL_CLIENT_SECRET,
});
// ----- 创建 MCP Server 实例 -----
const server = new McpServer({
name: "my-mcp-server",
version: "1.0.0",
});
// ----- Dynamic Secret 获取示例 -----
// 使用 dynamic、短生命周期 credentials 的 database query 工具
server.tool(
"query-database",
"使用 dynamic credentials 运行只读查询",
{
query: z.string().describe("SQL query string"),
},
async ({ query }) => {
// 生成有效期为 5 分钟的 dynamic credentials
const lease = await infisicalClient.dynamicSecrets().leases.create({
dynamicSecretName: "POSTGRES_READONLY",
environmentSlug: "production",
projectSlug: "your-project-slug",
ttl: "5m",
});
const dbCreds = lease.data;
const dbClient = new PostgresClient({
host: dbCreds.host,
user: dbCreds.username,
password: dbCreds.password,
database: dbCreds.database,
});
await dbClient.connect();
const results = await dbClient.query(query);
await dbClient.end();
return {
content: [
{
type: "text",
text: JSON.stringify(results.rows, null, 2),
},
],
};
}
);
// ----- Static Secret 获取示例 -----
// 使用 static API key 的天气预报工具
server.tool(
"get-forecast",
"使用 static API key 获取天气预报",
{
latitude: z
.number()
.min(-90)
.max(90)
.describe("位置的纬度"),
longitude: z
.number()
.min(-180)
.max(180)
.describe("位置的经度"),
},
async ({ latitude, longitude }) => {
// 从 Infisical 获取 static secret(这里没有硬编码)
const { secretValue: apiKey } =
await infisicalClient.secrets().getSecret({
secretName: "WEATHER_API_KEY",
environment: "production",
projectId: "weather-mcp-server",
});
const response = await fetch(
`https://api.weather.gov/points/${latitude},${longitude}`,
{
headers: {
"User-Agent": "weather-app/1.0",
Authorization: `Bearer ${apiKey}`,
},
}
);
const data = await response.json();
return {
content: [
{
type: "text",
text: JSON.stringify(data.properties.forecast, null, 2),
},
],
};
}
);
database query 示例会创建仅在 5 分钟内有效的临时只读 credentials,使用有限权限执行查询,并在使用后自动终止访问。与此同时,weather forecast 示例演示了如何使用特定于环境的参数从 Infisical 安全检索 API key,从而在不暴露代码中 credentials 的情况下发起经过身份验证的请求。
大多数 pre-built MCP servers 都要求你将 secrets 暴露为环境变量。与其将这些值存储在容易泄露的文件中,不如使用 Infisical CLI 在子命令中按需注入 API keys 或其他 secrets,这样更安全也更实用。
不要像这样运行命令:
env FIRECRAWL_API_KEY=fc-YOUR_API_KEY npx -y weather-mcp-server
你应该像这样将 secrets 注入到本地环境中:
infisical run -- npx -y weather-mcp-server
请注意,要使该命令成功,Infisical CLI 必须已完成身份验证。这可以通过手动执行 infisical login 命令实现,也可以通过多种方法自动完成,其中最常见的是 machine identity authentication。
在更大型的部署中,当不同 server 负责彼此隔离的功能时,并非所有 MCP servers 都需要访问每一个 secret。通过根据每个 server 管理的具体 integrations 或 services 来组织 secrets,你可以实施细粒度的 access control policies。这种隔离确保每个 MCP server 只访问其所需的 credentials,从而最小化整体攻击面并简化审计。
例如,你可以在 Infisical 中定义如下的 access governance policies:
// 为不同的 MCP servers 定义 access policies
const policies = [
{
name: "weather-server-policy",
permissions: [
{
subject: "secrets",
inverted: false,
action: "read",
conditions: {
environment: "weather-server",
secretPath: "secrets/WEATHER_API_KEY"
}
}
]
},
{
name: "database-server-policy",
permissions: [
{
subject: "secrets",
inverted: false,
action: "read",
conditions: {
environment: "database-server",
secretPath: "dynamic-secrets/POSTGRES_READONLY"
}
}
]
}
];
通过通过 policies 授予 access,你可以实现:
正确的 secrets management 是安全 MCP server implementation 中至关重要但常被忽视的组成部分。随着这些 servers 逐渐成为连接 LLMs 与外部 tools 和 services 的中枢神经系统,它们也成为潜在攻击者的高价值目标。通过避免硬编码 credentials、在可能的情况下实现 ephemeral secrets、安全地将 secrets 注入到 pre-built servers,以及在不同 MCP instances 之间隔离 access,你可以显著降低安全暴露。
请记住,单个被攻破的 API key 或 database credential 都可能让攻击者访问你整个 infrastructure 中的敏感 data 或 services。
Infisical 提供了一个对 developer 友好的解决方案,可以与现有 workflows 无缝协作,既可 self-hosted 使用,也可作为 fully-managed cloud service 使用。确保你的 AI infrastructure 的安全基础与它所支持的 LLMs 一样先进。
- 原文链接: infisical.com/blog/manag...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码