Apigee示例-MCP的外部访问控制
此存储库显示了一种包装不安全MCP服务器的方法 使用Apigee代理强制外部定义的访问 控制决策。
许多人认为MCP足够不同,需要 不同的网关,网络中完全不同的方法。
但这和你已经知道的没什么不同。
- MCP使用JSONRPC,众所周知,自2010年以来一直在使用
- MCP远程传输使用HTTP
- MCP安全建立在OAuth之上
听起来很熟悉?如果你有Apigee,你已经有了一个可以 为这种API风格提供正确的治理。
访问控制选项
可以包括 _基本的_ 使用Apigee进行访问控制 Apigee配置流语言。我所说的“基本”是指,你有可能 配置API代理以检查入站请求是否呈现令牌, 以及入站令牌对于给定操作是否有效。但这是一个 “面向客户端”的授权检查-它不考虑 附加用户-并且它是静态的。
但是要在Apigee API代理中包含更多的动态访问控制,通常 会想 _外化_ 访问控制决策,并允许Apigee 执行决定。这个外部化的决定可能依赖于任何武断的决定 数据,包括用户呼叫的身份、环境数据、最近的历史记录 对于该特定用户,一天中的时间等。
此存储库显示了一种实现方式,该实现涉及:
- MCP服务器,用Python实现,在云端运行
- 在Apigee X(云)中配置的API代理,代理到该服务器
- 一 _分开_ Cloud Run服务,用C#实现,用于做出访问控制决策
- Apigee代理中的ExternalCallout策略,用于调用访问控制云运行服务
萤幕录影
有一个 截屏视频 这表明 这一切是如何运作的。我鼓励你去看看!
免责声明
这个例子不是谷歌的官方产品,也不是 谷歌官方产品。这只是一个例子。
需要大量组装
这个例子依赖于许多运动部件和系统:
- 开放ID连接身份提供者
- 使用Python和FastMCP实现的MCP服务器,部署到Cloud Run
- 在C#中实现的授权规则服务器。NET,部署到云运行
- 包含上述授权服务器规则的电子表格
- Apigee的几个API代理
对我来说,这是一项巨大的努力,比我目前能够承诺的要大 与经过完全测试的工作代码和脚本共享一个仓库,使您能够 自己复制所有这些。
但无论如何,我都会发布代码和配置,因为我认为 只要阅读和检查运动部件就会有所帮助。
背景
_基础_ 使用Apigee配置流语言在Apigee中进行访问控制很容易。对于 例如,配置Apigee API代理以允许访问非常容易,只有当调用方 提供有效令牌(使用内置的Apigee策略 OAuthV2, 与操作= VerifyAccessToken).或者有效的、未过期的API密钥(使用内置Apigee 政策 VerifyAPIKey).
在简单的情况下,OAuthV2/VerifyAccessToken策略看起来像这样:
VerifyAccessToken
VerifyAPIKey策略看起来像这样:
在前一种情况下,当然,依赖于OAuthV2访问令牌的调用应用程序必须 先前已经通过某种授权流获得了访问令牌。这只是标准 OAuthV2模型,没什么新鲜事。
但正如你所看到的,无论是使用密钥还是令牌,控件都是 二元的。调用者具有对有效的密钥或令牌 当前通话,否则不会。如果你想要更细粒度的控制,特别是 使用MCP服务器和工具,您需要更多的控制和灵活性 粗粒度检查可以提供。
API产品用于访问控制
为了超越基本检查,Apigee采用了API产品概念。 API发布者可以配置特定的客户端凭据(客户端ID或API密钥) 获得特定API产品的授权。这些产品实际上只是 API代理,带元数据。每个入站请求都会提供一个凭据 将解析为有效的API产品。 然后,在运行时,Apigee将验证所提供的应用程序客户端凭据是否 授权用于API产品,该产品包括 当前API请求正在使用。
对API产品概念和隐含动词+路径进行15分钟的截屏回顾 授权检查, 看这里。但基本原则是:
- 配置时:
- API发行商定义API产品。每个包含1个或多个动词+路径对。 - 客户端开发人员获取其应用程序的凭据(客户端ID)。每个凭证都被授权用于一个或多个API产品。 - 客户端开发人员将这些凭据嵌入到他们构建的应用程序中。
- 运行时:
- 客户端应用程序发送GET/foo(动词=GET,路径=/foo)。 - 当您调用VerifyAPIKey或VerifyAccessToken时,Apigee会检查密钥或令牌。 - 如果有效,Apigee _隐含地_ 检查谓词+路径对是否经由与凭证相关联的API产品中的至少一个被授权。
除了基础知识之外,您还可以配置Apigee来检查Access Token上的作用域。
有一个方便的 试验样品 这将引导你完成这一过程,实际上是在Apigee工作。来看看吧.
那么更灵活的控制呢?
这里缺少的一件事是“基于角色的访问控制”,即/k/a RBAC, 这将允许基于 _人的身份_ 操作应用程序。ABAC也不见了,什么 OWASP称之为“基于属性 访问 控制”, 这不仅允许基于呼叫者的角色或身份进行控制 基于其他数据,如:工作角色、时间、项目名称、发起IP地址, 记录创建日期、之前的活动模式等。Apigee没有好的 该机制本身用于执行逐个用户的RBAC或更通用的ABAC。
为了实现基于用户的RBAC或更通用的ABAC,典型的模式是 _外化_ 访问控制决策并使用Apigee _强制执行_ 决定。你会用这个 _作为对_ Apigee可以对API产品进行的基本授权检查。
它处理呼入呼叫的方式(无论是MCP还是其他变体):
- Apigee运行时收集或确定它需要通知的所有信息
访问控制决策。这可能是关于请求用户的信息 计费帐户状态、最近活动的模式等。通常是用户 信息是从ID令牌之类的东西中获得的,该令牌由 独立身份提供者。
- Apigee向外部访问控制系统发送访问控制请求。这
请求必须包括外部系统需要创建的所有元数据 决定。调用者的身份、所请求的资源、特定的 请求的操作、源IP地址等。无论需要什么。
- 外部系统做出决定(允许或拒绝),并将其发送回Apigee。
- 然后Apigee API代理强制执行该决定。
此存储库中包含的示例显示了如何使用 定制的Cloud Run服务,用于外部化MCP服务器的访问控制决策。
实现细节
这里的例子显示了基本思想。 这是它的工作原理。
- 客户端应用程序(例如代理)向Apigee API代理发送MCP呼叫请求。这个电话
必须在授权标头中包含访问令牌。
- Apigee API代理验证访问令牌,检查它是否
对给定的代理有效。
- 如果通过,Apigee API代理将调用 [外部访问控制
服务](./access-control-server),传递它{jwt有效载荷,MCP方法,MCP 工具}。这个服务恰好是用C#实现的,但这只是一个 细节。
- 访问控制服务使用Google Sheets REST API来检索访问控制
谷歌表格中的规则。此数据缓存在访问控制服务中。
- 访问控制服务对入站数据应用访问规则。
它使用访问令牌上的“az_groups”声明以及MCP动词和工具来查找 匹配规则。如果存在ALLOW条目,则请求为 允许。否则,不会。
服务向代理返回“ALLOW”或“DENY”。
- 代理执行该决定,
否则发出403状态。
规则如下: Screenshot
以及评估请求是否应该被授权的逻辑,
一些实施说明:
- 在步骤1中,通过以下方式获得代理发送的访问令牌
OAuthV2授权码授权类型,来自OpenID Connect服务器 已注册特定MCP服务器。你需要提供自己的 OIDC服务器。
您可以使用 Auth0.com; 有关说明,请参阅 Auth0设置.
无论您使用何种OIDC服务器,它都必须发出一个带有声明的访问令牌 其中的“az_groups”应该是字符串列表。这 访问控制 服务器 检查该声明以确定是否 允许请求。
- API代理假定JWKS端点在
${OIDC_SERVER}/jwks 令牌发行者与 ${OIDC_SERVER} url。
- 访问控制服务是GRPC服务。这意味着它将相对较快
从您的Apigee API代理调用,效率高,并且应该是可接受的 对每个API请求进行检查。如果相对较低的延迟仍然没有 如果可以接受,您可以将规则评估逻辑移动到Apigee代理本身中。 此处未显示。
为什么不使用OPA进行访问控制?
_好问题!!_ 开放策略代理 很好 用于存储、管理和评估访问规则的解决方案,适用于任意系统或 资源。它是开源的,维护良好,可以作为可部署的容器使用 图像。您可以部署 集装箱 图像 有权参加Cloud Run之类的活动; 无需构建代码。
听起来不错,对吧?这 _一个缺点_ 我看到的是,OPA依赖于 雷戈 表达政策。这是 特定领域语言;我没有看到它在任何地方使用过 _其他_ 比OPA。 这有点新颖。这对一些球队来说可能是一个障碍。
对于这个特定的例子,我决定使用谷歌表格来存储访问规则,原因如下:
- 它是可视化的——很容易看到有什么具体的规则,也很容易演示;
- 更新和维护访问规则很容易。
- 这很容易 _保护_ “表格”文档上具有用户权限的访问规则。
- 很容易得到谁更改了什么的日志-只需查看工作表上的版本历史记录即可。
所有这些,你都可以通过谷歌表格“免费”获得。
检索和应用规则的C#逻辑也很容易理解。这 所有这些因素的结合意味着使用Sheets和C#可以得到一个解决方案 更广泛地说 _可访问的_ 而不是基于OPA和REGO的组合。
但是,使用OPA的解决方案的架构模型将是 _一模一样_ 正如我所拥有的 带着定制的C#服务和谷歌表格来到这里。
为您自己的目的部署它
要按照说明在您自己的环境中部署它,您需要 以下先决条件:
- Apigee X或混合动力
- 启用了Cloud Run和Cloud Build的Google Cloud项目
- 一个允许您创建和共享电子表格的Google Workspace环境
- .NET 8.0- _如果你想修改源代码并在本地构建_。否则,Cloud Build将为您远程构建,您不需要。NET在您的工作站上。
你可以在 Google Cloud Shell.
应遵循的步骤
这些需要您进行一些定制。这还没有经过充分的测试和审查。
- 修改 env.sh 文件以适应您的环境。然后获取它来设置这些
用于后续命令的变量:
source ./env.sh- 启用所需的服务:
./1-enable-services.sh- 使用gcloud登录以允许脚本创建电子表格:
./2-auth-login.sh- 将“产品”MCP服务器部署到云端运行
3-deploy-products-mcp-to-cloud-run.sh- 创建包含规则+角色的工作表。
./4-create-sheet.sh脚本完成后,为工作表ID定义shell变量。从输出中找到它 “创建工作表”步骤。
export SHEET_ID=VALUE-FROM-PRIOR-STEP- 为访问控制服务创建服务帐户。
./5-create-service-account-for-access-control-service.sh- 手动将之前创建的工作表与SA电子邮件地址共享。
- 部署云运行服务,该服务将读取并应用工作表中的规则。
./6-deploy-access-control-service-to-cloud-run.sh这需要几分钟的时间。它将源代码发送到Cloud Build, 构建服务,然后从映像部署它。
- 创建Apigee目标服务器。
这是指向访问控制服务器的服务器实体。
./7-create-apigee-target-server-for-authz.sh- 安装apigeecli
./8-install-apigeecli.sh- 导入和部署Apigee API代理
有一个用于处理MCP的“众所周知的端点”(basepath\`/.knowledge/),另一个用于 以处理其他MCP交易。
./9-import-and-deploy-apigee-proxies.sh- 在聊天机器人或代理中配置MCP服务器
您的选择(Gemini CLI有效),如下所示:
"mcpServers": {
"products": {
"httpUrl": "https://your-apigee-endpoint/mcp-access-control/mcp",
"oauth": {
"enabled": true,
"clientId": "ab4aded9d20f44RHgmrNCq",
"clientSecret": "26a86ab545704312b748e331f854"
}
}
}您的OIDC服务器需要知道clientId和clientSecret。 或者,如果您的服务器支持动态客户端注册(DCR),则可以省略它们。
- 启动代理;它应该启动OAuth流程,并最终
调用MCP服务器。您可以在Apigee上打开Trace会话以查看交互。
清理
- 删除Apigee资产。
这包括目标服务器和API代理。
./99a-clean-apigee-entities.sh- 删除Cloud Run资源。
这包括服务帐户。
./99b-clean-cloud-run-authorization-service.sh- 手动删除Google工作表。
支持
此标注和示例代理是开源软件,不受支持 阿皮吉。如果您有疑问或需要帮助,可以尝试查询 这 谷歌云社区论坛致力于Apigee 对于发布到该网站的查询的回复,没有服务级别保证。
许可证
这种材料是 版权所有©2025谷歌有限责任公司. 并根据 Apache 2.0许可证这包括Java 代码以及API代理配置。
漏洞
- 部署Cloud Run服务以允许“未经身份验证的访问”。如果你使用
在真实系统中,您需要将Cloud Run服务部署到 允许 run.invoke 从您的访问控制服务运行的服务帐户。
- API代理不对包含的客户端ID执行“VerifyAPIKey”
在访问令牌内。这是一个简单的扩展。它需要同步 Apigee中的应用程序与OIDC服务器中的客户端ID。
- 访问控制服务不检查格式错误的规则。
