关于 indykite-agent-gateway
用于配置 IndyKite Agent Gateway 的技能,可在请求到达 A2A Agent 或 MCP 服务前执行身份、工作流授权和委派链检查,涵盖单跳及多跳委派、配置与部署。
主要功能
- 01保护单个 A2A Agent 或 MCP 服务
- 02验证调用者身份与工作流访问权
- 03检查建模的委派链
- 04配置 IdP 或 Token Service 令牌交换
- 05部署并诊断网关实例
适用场景
- 01在 MCP 服务前执行授权
- 02保护 A2A 工作流中的 Agent
- 03配置多跳委派
- 04排查网关授权失败
MCP 相关
在 `mcp` 模式下,IAG 将 MCP Streamable HTTP 流量代理到受保护的 MCP 服务,并执行与 A2A 相同的身份、授权和委派检查。它仅转发指定的 MCP 协议修订版。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ indykite/ skills --skill indykite-agent-gateway安装后在 Claude Code 中输入/indykite-agent-gateway确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/config-template.yamltoken-service-config-template.yamlreferences/architecture.mdconfiguration.mdtoken-service.mdtroubleshooting.md详细介绍
IndyKite Agent Gateway
Indykite Agent Gateway(IAG)是一项独立服务,用于保护且仅保护一个下游服务——A2A Agent 或 MCP 服务。每个受保护的下游服务都应运行一个 IAG。从调用方的角度看,IAG 是目标端;从受保护的下游服务的角度看,IAG 是来源端。IAG 不是通用反向代理:默认情况下(protocol: a2a),它使用 A2A 协议,并跟踪 A2A 会话,确保 JSON-RPC 流正确传输;使用 protocol: mcp 时,它会代理 MCP Streamable HTTP 流量(转发 Mcp-Session-Id,并透传 SSE 流式响应),且仅转发 MCP 协议修订版本 2025-06-18、2025-11-25 和 2026-07-28。无论哪种模式,前置的授权流程都相同。
对于每个请求,IAG 都会验证以下三项:
- 调用方(在 IdP 处进行令牌内省)。
- 工作流(通过 AuthZEN/KBAC 检查主体是否具有
CAN_TRIGGER权限)。从 gateway 2.82.0 起,主体信息来自 ContX IQ 对调用方令牌执行的GET /contx-iq/v1/whoami:主体类型是项目中用于验证该令牌的 Token Introspect 配置的ikg_node_type,主体 ID 则是令牌的 subject(sub,或该配置中sub_claim指定的 claim)。 - 委派链(请求的
act链与 IKG 中建模的链匹配)。
承载 act 链的委派令牌由 IdP(RFC 8693 令牌交换)签发;也可以在配置可选的 token_service 部分后,由可自托管的 **IndyKite Token Service(ITS)**签发。使用 ITS 时,调用方自己的访问令牌会原样通过 Authorization 传递,委派令牌则通过 X-IK-Token 传递;带有 X-IK-Token 的请求表示后续跳转,其链会嵌套到下一个令牌中,因此工作流可以跨越一个以上的跳转。
适用场景
当用户遇到以下情况时,启用此技能:
- 正在构建 Agent-to-Agent(A2A)工作流,并希望在每个 Agent 前实施策略;
- 希望在 MCP 服务前设置执行点(
protocol: mcp),让 MCP 流量与 A2A 一样经过令牌内省、AuthZEN 检查和审计; - 需要通过 OAuth 令牌交换和
act链实现可追踪的用户到 Agent 委派,包括需要使用 IndyKite Token Service 和X-IK-Token请求头的多跳链; - 正在配置 Token Service 本身(签发方
base_url、签名密钥、受众、token_introspection配置); - 正在 IndyKite Graph(IKG)中使用
INVOKES关系为Workflow和Agent节点建模; - 正在为一个或多个 IAG 实例配置
JARVIS_*环境变量或config.yaml(包括token_service、healthcheck_port、缓存调优和审计传送); - 正在查看 IAG 或 Token Service 审计记录(
AUTHORIZED/NOT_AUTHORIZED、TOKEN_EXCHANGED/EXCHANGE_REFUSED、INTROSPECTED*),并尝试解释401或403; - 正在复现或扩展
iag-mcp-demo(A2A + MCP)或iag-token-exchange(Token Service)参考应用。
当用户遇到以下情况时,不要启用此技能:
- 需要通用 HTTP 反向代理或服务网格——IAG 只支持 A2A 或 MCP,不支持任意 HTTP;
- 询问与 Agent 访问控制无关的 IndyKite 功能(网关调用方所需范围之外的 Token Introspect 配置、普通 AuthZEN 策略、Agent 访问控制之外的 ContX IQ 查询);
- 正在调试受保护的 Agent 本身,而不是其前置网关。
前置条件
在以下任何步骤能够成功之前,用户需要具备:
- 一个已启用 AuthZEN / KBAC 和 ContX IQ 的 IndyKite 项目,并且已建模
Workflow节点和Agent节点(或计划进行建模——请参阅步骤 1)。 - 一个符合 OAuth2 标准、具备 introspect、client-credentials 和 token-exchange 端点的 IdP。将
IDP_BASE_URL设置为目标环境的 IdP 基础 URL。即使使用 Token Service,IdP 仍然是必需的:它会内省调用方的访问令牌,并对受保护的 Agent 进行身份验证。 - 每个受保护的下游服务(A2A Agent 或 MCP 服务)各有一组 client_id / client_secret,并已在 IdP 中注册。
- 一个 ContX IQ 查询,针对每个受保护的下游服务返回
(workflow, agent_list)对——其query_id需填入 IAG 配置。 - 对于 MCP 下游服务(
protocol: mcp):MCP 服务的源站和端点路径,以及版本 ≥ 2.0.1 的网关镜像indykite/agent-gateway(较旧镜像会忽略该协议,并作为 A2A 代理运行)。MCP 客户端必须是可内省的调用方,并由 Token Introspect 配置覆盖(网关 2.82.0+,见下一条),且通过 AuthZEN 检查。 - 从网关 2.82.0 开始,每个网关调用方都需要一个 Token Introspect 配置;其
ikg_node_type是触发器策略必须指定的主体类型——请参阅主体步骤(2.82.0 之前为authzen.subject_types)。 - 对于 超过一跳的工作流(Agent → Agent → Agent),或任何需要让受保护 Agent 看到调用方原始访问令牌的情况:需要运行中的 IndyKite Token Service(
indykite/token-service),其base_url为https发行者地址,至少有一个签名密钥、包含每个受保护 Agent 的受众,以及一个供网关使用的client_auth客户端——请参阅references/token-service.md。没有它,网关会在每一跳都向 IdP 交换令牌,调用链最多只能有一跳。 - Docker(和 Docker Compose),用于运行 iag-mcp-demo 参考应用。
如果缺少上述任何一项,请停止并告知用户——IAG 无法在缺少这些条件时运行。
步骤
1. 在 IKG 中建模工作流
创建一个由 external_id 标识的 Workflow 节点,为每个受保护的 Agent 创建一个 Agent 节点,并在 Agent 之间建立 INVOKES 关系。每条 INVOKES 关系都必须包含一个 workflow_name 属性,其值与 Workflow.external_id 相匹配。步骤 3 中的 ContX IQ 查询会静默排除任何不含此属性的调用链。
示例结构(演示中的规范 wf1 工作流):
(Workflow {external_id: "wf1"})
(Agent {external_id: "orchestrator"})
-[INVOKES {workflow_name: "wf1"}]-> (Agent {external_id: "retriever"})
(Agent {external_id: "orchestrator"})
-[INVOKES {workflow_name: "wf1"}]-> (Agent {external_id: "weather"})
通过 Capture API(POST /capture/v1/nodes、POST /capture/v1/relationships)、IndyKite Hub UI,或项目当前使用的 Terraform / 身份管道采集这些数据。
2. 将主体关联到工作流
对于所有获准触发工作流的主体,创建边 (:User)-[:CAN_TRIGGER]->(:Workflow)(或等效的 AuthZEN 关系)。没有这条边,即使调用链正确,IAG 仍会在 AuthZEN 检查时返回 403。
3. 构建 ContX IQ 查询
给定受保护的 Agent 标识符,查询必须返回 (workflow, agent_list) 对,其中 agent_list 是请求必须经过的有序 Agent 调用链。保存其 query_id——IAG 通过 JARVIS_CONTX_IQ_QUERY_ID(或 contx_iq.query_id)引用它。
如果 CAN_TRIGGER 背后的 KBAC 策略会读取委托令牌,则必须引用网关实际转发的令牌:由 IdP 签发时使用 $token(它会替换 Authorization),由 Token Service 签发时使用 $ik_token(它会通过 X-IK-Token 传递)。引用未发送的令牌会得到空值,导致决策被拒绝。
4. 配置每个 IAG 实例
选择以下两种配置形式之一:
- YAML 配置文件 - 使用
--config=/app/config.yaml传入。适用于配置管理严格的生产环境。请参阅此技能中的assets/config-template.yaml。 - 环境变量 - 键使用
JARVIS_前缀和下划线(例如JARVIS_SERVICE_NAME)。适用于多个 IAG 实例共用基础镜像(如 iag-mcp-demo),且仅覆盖每个 Agent 的字段。
完整的配置节包括 service、identity_provider、token_service(可选)、protected_agent、authzen、contx_iq 和 audit。所有字段及其默认值请参阅 references/configuration.md。
使用 protected_agent.protocol(环境变量 JARVIS_PROTECTED_AGENT_PROTOCOL)选择下游协议:a2a(默认值)用于 A2A Agent,mcp 用于 MCP 服务。其他任何值都会导致启动失败,并报错 invalid protected_agent protocol。在 mcp 模式下,protected_agent.base_url 只能是 MCP 服务的源地址——IAG 会追加传入请求的路径。授权流程保持不变,只有转发的协议不同。在 mcp 模式下,网关还会强制执行 MCP 协议修订版本:只转发 2025-06-18、2025-11-25 和 2026-07-28;除 initialize 外的所有请求都必须携带 Mcp-Protocol-Version,且其值必须是其中之一;JSON-RPC 批次、编码后的请求体以及超过 4 MiB 的请求体会在授权前被拒绝,并返回 JSON-RPC 错误。网关后面的 MCP 服务必须至少支持这三个修订版本之一。请参阅 references/configuration.md 中的 Protecting an MCP server 章节,以及 references/architecture.md 中的 MCP protocol revisions 章节。
使用可选的 token_service 配置节(base_url、exchange_endpoint、introspect_endpoint、client_auth.type: client_secret_basic、client_auth.client_id、client_auth.client_secret;环境变量 JARVIS_TOKEN_SERVICE_*)选择委托令牌的来源。不填写时,由 IdP 交换令牌。填写后,Token Service 会签发委托令牌,请求将同时转发 Authorization 和 X-IK-Token,传入的 X-IK-Token 会在 Token Service 处验证,并成为下一次交换的主体。启用此配置时,还需在 protected_agent.authentication.audiences 中列出网关请求的受众——每个受众都必须位于 Token Service 的 idp.audiences 中,否则交换会因 invalid_target 被拒绝。
以下每项实例级别的值在不同 IAG 实例之间必须不同:
service.name/JARVIS_SERVICE_NAMEservice.port/JARVIS_SERVICE_PORTservice.healthcheck_port/JARVIS_SERVICE_HEALTHCHECK_PORT(仅当多个实例共用一个网络命名空间时;默认值为9080)protected_agent.base_url/JARVIS_PROTECTED_AGENT_BASE_URLprotected_agent.protocol/JARVIS_PROTECTED_AGENT_PROTOCOL(若有实例保护 MCP 服务)protected_agent.authentication.client_id和client_secretprotected_agent.authentication.audiences(使用 Token Service 时,为该实例受保护 Agent 的受众)
所有实例的 token_service 配置节都相同。
5. 部署 IAG 实例(以及 Token Service,如有使用)
对于 Docker Compose,请遵循 iag-mcp-demo 模式:使用一个共享的 iag-base-docker.yaml,并为每个受保护的 Agent 配置一个服务,只覆盖上述每个实例对应的字段。对于 Kubernetes,可将每个 IAG 部署为独立 Pod,以便单独扩缩;也可以将其作为受保护 Agent 的 sidecar,以实现更紧密的耦合。
每个网关都在 service.healthcheck_port(默认值为 9080)上提供 /healthz、/readyz 和 /startupz,容器镜像的 HEALTHCHECK 会探测 http://localhost:9080/healthz。较旧的镜像不提供该端点,因此整个运行期间都会报告为不健康——如果编排系统依赖容器健康状态来触发操作,请拉取当前镜像。
所有网关共用一个 Token Service 部署:运行 indykite/token-service(固定到具体标签,例如 1.0.0,切勿使用 latest),并使用 --config=<file>;在生产环境中,使用 --config-dir=<dir>,以便将密钥(签名密钥、client_auth)作为单独文件挂载,并与非敏感配置合并。service.base_url(它是其签发的每个令牌的 iss)为必填项,没有默认值,且必须使用 https。详情见 references/token-service.md。
IndyKite 平台还必须信任 ITS 签发的令牌,否则所有携带 X-IK-Token 到达 AuthZEN、ContX IQ 或 MCP 服务的请求都会被拒绝,并返回 401 Invalid token in X-IK-Token header。为委托令牌可能携带的每个受众创建一个 Token Introspect 配置(POST /configs/v1/token-introspects,使用 Service Account 令牌):jwt_matcher.issuer = ITS 的 base_url,jwt_matcher.audience = 受保护 Agent 的受众,offline_validation.public_jwks = 签名密钥的公钥部分。确切的负载内容见 references/token-service.md 中的 Making the platform trust ITS tokens 一节。
验证每个 IAG 都能访问 IdP、AuthZEN、ContX IQ、Token Service(如已配置)和受保护的 Agent——常见的部署故障出在网络层,而非 IAG 本身。
6. 验证运行时路径
通过网关发送请求,并确认九步路径端到端执行。预期的 HTTP 响应如下:
200- 请求已获授权并转发。400- 错误请求。在mcp模式下,会返回 JSON-RPC 错误正文:-32020(缺少Mcp-Protocol-Version标头,或在2026-07-28,Mcp-Method/Mcp-Name标头与正文不一致)、-32022(不支持的版本,error.data.supported会列出三个版本)、-32600(JSON-RPC 批处理、不是 JSON-RPC 2.0 消息、存在歧义的键,或方法 / 工具名称 / URI 含有控制字符)、-32602(tools/call未指定工具,或resources/read、resources/subscribe或resources/unsubscribe未指定资源 URI),或-32700(无法读取正文、正文不是有效的 UTF-8,或正文不恰好包含一个 JSON 值)。网关会读取请求中每次指定的工具或资源,并拒绝无法明确读取的内容 - MCP 请求分类。401- 调用方令牌缺失或未激活(Missing bearer token、Invalid token, missing subject);自 2.82.0 起,项目中没有任何 Token Introspect 配置接受该令牌({"message":"Unauthorized","errors":["ContX IQ whoami failed"]},审计原因cannot resolve the subject of the access token);或传入的X-IK-Token无法使用(Invalid delegated token, subject mismatch/missing subject)。403- 调用方已通过身份验证,但未获准访问(主体、调用链,或两者均不符合条件)-Authorization check failed。原因仅记录在审计记录中:no workflow matches the actors chain(跳过了某一跳,或在另一条调用链上重用了委派令牌),或subject <type>/<id> is not authorized to trigger any of the workflows <ids>(调用链匹配,但用户没有CAN_TRIGGER;在 2.82.0 之前不含<type>/<id>)- 调用链拒绝。413/415- 仅限mcp模式:正文超过 4 MiB,或Content-Encoding不是identity;JSON-RPC 错误-32600。500- 内部错误。502- 上游 / 网关侧处理错误,包括无法访问或响应无法读取的 IdP 或 Token Service。提供方中断会报告为故障,绝不会计为拒绝。
同时查看服务日志(以 JSON 格式输出到 stdout)和审计记录 - 服务日志说明 IAG 执行了什么操作,审计记录说明 IAG 作出了什么决定。IdP 或 Token Service 调用遭拒时,日志会记录端点、状态和经过脱敏处理的响应正文预览,因此错误的客户端密钥和故障端点不会再显得相同。
7. 查看审计轨迹
审计记录作为独立于服务日志的流输出。可配置以下任一种传送方式:
- Webhook -
audit.delivery: webhook、audit.http.url、audit.http.method(post或put),以及身份验证type(no-auth、api-key、mTLS之一)。 - 文件 -
audit.delivery: file、audit.file.storage_path、audit.file.format(csv、json、txt)和audit.file.rotation_strategy(size、time、size-and-time)。
任一种方式都可以通过 audit.async.buffer_size(默认值为 512)启用缓冲;缓冲记录会在关闭时排空,队列已满时会丢弃记录,并在服务日志中发出警告。
每条网关记录都包含 decision(AUTHORIZED、NOT_AUTHORIZED,或请求无法判定时的 ERROR)、reason、subject、actor、actorsChain、action、service、timestamp、traceID。traceID 可用于关联受保护 Agent 的日志和上游客户端。Token Service 会针对每次交换和内省写入相同格式的记录,决策包括 TOKEN_EXCHANGED / EXCHANGE_REFUSED、INTROSPECTED / INTROSPECTED_INACTIVE / INTROSPECTION_REFUSED 和 ERROR,另含 tokenID(令牌的 jti)。
8. 有意测试拒绝路径
要确认 IAG 按预期执行,请有意触发 NOT_AUTHORIZED 结果:
- 跳过链中的某个 Agent(例如,在
act中不经过编排器,直接调用retriever-iag)。 - 从一条
INVOKES关系中移除workflow_name——ContX IQ 将不再返回该调用链。 - 删除主体与工作流之间的
CAN_TRIGGER边——AuthZEN 会拒绝请求。 - 使用 Token Introspect 配置中的
ikg_node_type没有任何触发策略名称的令牌发起调用——没有策略匹配,返回403(在 2.82.0 之前:主体类型缺少在JARVIS_AUTHZEN_SUBJECT_TYPES中的配置)。 - 使用 Token Service:将某个用户的访问令牌与另一个用户的
X-IK-Token一起重放——返回401 Invalid delegated token, subject mismatch。 - 在
mcp实例上:不带Mcp-Protocol-Version标头发送tools/list——返回400,JSON-RPC 错误为-32020,并记录NOT_AUTHORIZED审计结果,原因为MCP request refused: Header mismatch: Mcp-Protocol-Version header is missing。 - 在
mcp实例上:发送params中没有name的tools/call——返回400,JSON-RPC 错误为-32602,并记录NOT_AUTHORIZED审计结果,原因为MCP request refused: Invalid params: tools/call names no tool;服务端不会收到该请求。
每种情况都应返回 403 Forbidden(令牌配对错误时返回 401,MCP 版本和分类检查失败时返回 400),并生成包含有用 reason 的 NOT_AUTHORIZED 审计记录。
结果
成功应用此技能后:
- IKG 中存在一个
Workflow节点、相关的Agent节点以及带有workflow_name的INVOKES边。 - ContX IQ 查询会为每个受保护的 Agent 返回正确的
(workflow, agent_list)对。 - 每个受保护的 Agent 前都运行一个 IAG 实例,且各实例配置正确;
/healthz报告服务健康。 - 在网关 2.82.0 及更高版本上,
indykite-ciq-whoami技能会将网关的每个调用方解析为触发策略中指定的主体类型。 - 如果工作流包含多个跳转,则 Token Service 正在运行,每个网关都指向该服务,项目中为 ITS 签发令牌的每个受众都持有一个 Token Introspect 配置,并且转发的请求携带
Authorization和X-IK-Token,令牌链在每一跳都会增长。 - 规范的成功提示词会通过网关链,并在其经过的每个 IAG 上生成
AUTHORIZED审计记录(并在 Token Service 上生成TOKEN_EXCHANGED记录)。 - 规范的拒绝路径会返回
403 Forbidden,并生成包含人类可读reason的NOT_AUTHORIZED审计记录。
此技能中的文件
references/architecture.md- IAG 请求路径的九个步骤、委托令牌传递方式($token与$ik_token)、多跳链、网关转发的 MCP 协议版本以及 IKG 数据结构。references/configuration.md- IAG 配置的每个部分、字段和默认值,包括token_service、健康检查端口、缓存规则和审计传递。references/token-service.md- IndyKite Token Service:端点、配置(service.base_url、idp、token_introspection)、配置目录合并、审计决策和部署说明。references/troubleshooting.md- 常见故障及对应的修复方法。assets/config-template.yaml- 用于复制和调整的网关config.yaml起始模板。assets/token-service-config-template.yaml- Token Service 的config.yaml起始模板。
Agent 专属说明
此技能使用通用 Markdown 说明,适用于 README 中列出的所有 Agent。它不需要 Claude Code 钩子、Cursor @ 提及、Copilot 工作区上下文或任何 Agent 专属功能。只有在 Agent 要在任务期间直接调用 IndyKite API 时,才需要网络访问权限(curl、Agent 的 Web 工具或 MCP);仅进行设置时,无需特殊工具。
参考资料
- IndyKite Token Service 指南 - 端点、交换和内省约定、配置,以及通过 Token Introspect 实现的平台信任和审计记录。
- 使用 Agent Gateway 保护 MCP 服务(教程) - 网关配置的其余部分,演示采用 MCP 代理模式。
- AuthZEN 指南 和 ContX IQ 指南 - 策略如何读取
$token和$ik_token。 iag-mcp-demo参考应用 - 三个 A2A 网关(协调器、检索器、天气)以及一个mcp-iag实例(protocol: mcp),用于保护 IndyKite MCP 服务。iag-token-exchange参考应用 - 端到端运行 Token Service 设置(每个网关上都有token_service,X-IK-Token随请求逐跳增长)。canbank数据集- RFC 8693 OAuth 2.0 Token Exchange 和 RFC 7662 Token Introspection - Token Service 实现的两种协议。
- A2A 协议 - JSON-RPC 格式请参阅受保护 Agent 的供应商文档,IAG 会转发该格式。对于 MCP,IAG 会代理 MCP Streamable HTTP(
initialize、tools/list、tools/call,……),支持协议修订版本2025-06-18、2025-11-25和2026-07-28;无状态的2026-07-28风格请参阅indykite-mcp-server中的文档。