IBM 给 Agent 发了身份:真正值得抄的是那道网关

·阅读约12分钟·Evergreen Tools Team

2026 年 10 月 27 日,IBM 在亚特兰大的 TechXchange 上给 watsonx Orchestrate 加了一整套东西:Agent 身份、AI 网关、受治理的目录、以及一个把容器隔离做到硬件虚拟化层级的运行时。发布稿里最容易被忽略的一句是:目标不是限制 Agent 能做什么,而是建立让 Agent 能安全承担更多责任所需的信任基础。这句话把整件事的性质说清楚了——这不是又一个 Agent 构建器,这是一层控制面。而从工程角度看,最值得抄的不是 IBM 的目录,是那道网关。

数据中心走廊与安全访问控制

网关不是新功能,它把"你到底有什么在跑"变成可回答的问题。

一、这次发布的是控制面,不是构建器

IBM 自己的说法是:挑战已经不是"快速做出一个 Agent",而是在业务里管住几百上千个 Agent,确保它们可靠、安全、并且持续产生价值。围绕这个判断,公告拆成了三块——发现与准入(AI 网关 + 受治理目录)、运行时隔离(Premium Runtime)、以及生命周期里的评估与观测。三块拼起来就是一句话:Agent 从"某个团队偷偷跑起来的脚本"变成"有名有姓、有归属、有权限边界、有到期日的资产"。

二、借来的凭据,让审计日志失去意义

IBM 在 9 月把 Agent Identity 放进预览时说过一件事:今天大量 Agent 用共享服务账号认证。后果很具体——审计日志里出现一次转账,你分不清是某个人做的、是某个 Agent 替这个人做的、还是 Agent 自己决定做的。Agent Identity 的做法是给 Agent 一个独立于创建者和使用者的可验证身份,并且不新建一套身份存储,而是接到你已经在跑的 IdP 上,预览阶段支持 IBM Verify 与 Microsoft Entra。配套的 HashiCorp Vault 负责按最小权限发放凭据。

# An agent identity is a record, not a shared service account. Keep it in
# version control next to the agent's code and review changes like code.
agent:
  id: agt_invoice_reconcile
  version: 3
  owner: [email protected]
  lifecycle: production          # draft | staging | production | retiring
  runtime: premium-runtime
  authority:
    scopes: [invoices:read, vendors:read, ledger:write:draft]
    max_amount_usd: 5000
    requires_human_above: 5000
  approved_tools:
    - mcp://erp/invoices.list
    - mcp://erp/vendors.get
  review:
    last_reviewed: 2026-10-20
    review_due: 2027-01-20
  expires: 2027-04-30           # agents should not outlive their justification

# The audit log question this answers: was this action taken by the agent,
# by the person who built it, or by the person using it?

三、网关的价值在于"只有一个执行点"

watsonx Orchestrate AI Gateway 被描述成单一执行层:跨 Amazon Bedrock、Microsoft、Google 等平台发现第三方 Agent、模型和 MCP 服务器,然后用一致的观测、评估和优化去治理它们。企业还可以直接在 watsonx Orchestrate 的对话和渠道里调用这些第三方 Agent,不用重建。这条设计解决的是多平台采购之后的碎片化:每个平台只管自己生态里的资产,于是库存是碎的、控制是不一致的、可见性是局部的。一个网关不会让这些平台变好,但它让"你到底有什么"变成一个可以回答的问题。

# Admission control for MCP servers. IBM's catalog surfaces conformance,
# schema integrity, description safety, input validation and default-credential
# rejection at discovery time. You can check four of those in a pipeline.
import re, yaml, jsonschema

INJECTION = re.compile(r"(ignore (all )?previous|system prompt|do not tell)", re.I)
DEFAULT_CREDS = re.compile(r"(changeme|admin:admin|password123|sk-test)", re.I)

def admit(manifest_path: str) -> list[str]:
    m = yaml.safe_load(open(manifest_path))
    problems = []

    for tool in m.get("tools", []):
        try:
            jsonschema.Draft202012Validator.check_schema(tool["inputSchema"])
        except Exception as e:
            problems.append(f"schema invalid: {tool['name']}: {e}")

        desc = tool.get("description", "")
        if INJECTION.search(desc):
            problems.append(f"description looks like an instruction: {tool['name']}")
        if len(desc) > 800:
            problems.append(f"description too long to audit: {tool['name']}")

    blob = yaml.safe_dump(m)
    if DEFAULT_CREDS.search(blob):
        problems.append("default credential string found in manifest")

    return problems

# Reject on any finding. A catalog that lists risk without gating it is a
# dashboard, not a control.

四、目录被做成了准入清单

公告里最硬的一段是目录的校验项。对部分 MCP 服务器(Box、Visier、New Relic 等),目录会展示协议一致性、工具 schema 完整性、工具描述安全性、输入校验,以及默认凭据是否被拒绝。这几个检查项的排序其实是一份攻击面清单:描述可以被写成提示注入,schema 可以被写成越权参数,默认凭据可以直接把服务器交出去。同时目录在发现的那一刻就把评估数据摆出来,并对齐 OWASP、CoSAI 与 IBM AI Risk Atlas,部分 Agent 还能看到性能、可靠性、延迟,以及风险信号、控制项与 EU AI Act 这类合规信息。

# The agent should not hold the user's password. It should hold a token that
# says: this agent, on behalf of this user, for these scopes, until this time.
import time, requests

def exchange(agent_token: str, user_token: str, scopes: list[str]) -> dict:
    r = requests.post(
        "https://auth.example.com/token",
        data={
            "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
            "subject_token": user_token,          # the human
            "subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
            "actor_token": agent_token,           # the agent, named and accountable
            "actor_token_type": "urn:ietf:params:oauth:token-type:access_token",
            "scope": " ".join(scopes),
            "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
        },
        timeout=10,
    )
    r.raise_for_status()
    body = r.json()
    return {"token": body["access_token"], "expires_at": time.time() + body["expires_in"]}

# Read-only is a scope, not a promise. If the exchange cannot mint a read-only
# token, the integration does not ship — you do not fall back to the password.

五、运行时的三个词:隔离、无横向移动、可计量

Premium Runtime 的描述是"专用的、多后端的托管、隔离与计量层",具体给了三条:硬件虚拟化容器隔离、零横向移动、硬件绑定的资源约束。翻成运维语言:Agent 执行动态工具代码时,不能和别的 Agent 共享内核;一个 Agent 被拿下之后,不能顺着内核或网络摸到邻居;它的资源上限要绑在硬件上,而不是靠 cgroup 祈祷。这三条对自建团队同样适用——如果你的 Agent 在一个共享内核的容器里跑用户可控的代码,你其实没有隔离。

# One enforcement point, or you have zero enforcement points. Everything an
# agent can reach goes through here, including third-party tools.
from dataclasses import dataclass

@dataclass
class Decision:
    allow: bool
    reason: str

def authorise(identity: dict, tool: str, args: dict) -> Decision:
    if tool not in identity["authority"]["approved_tools"]:
        return Decision(False, "tool not in approved_tools")

    need = TOOL_SCOPES[tool]                      # e.g. "ledger:write:draft"
    if need not in identity["authority"]["scopes"]:
        return Decision(False, f"missing scope {need}")

    cap = identity["authority"].get("max_amount_usd")
    if cap is not None and args.get("amount_usd", 0) > cap:
        return Decision(False, f"amount above authority cap {cap}")

    return Decision(True, "ok")

# Log every decision, including the denies. The denies are what tell you an
# agent has started reaching for tools nobody gave it.

六、不是 IBM 用户也能抄的构建顺序

第一步,给每个 Agent 写一份身份记录:归属人、生命周期、可用工具、权限范围、金额上限、到期日,放进代码库跟着 Agent 一起评审。第二步,把工具调用收到一个执行点,所有拒绝也记日志——拒绝比允许更能暴露异常。第三步,对 MCP 服务器做准入检查,schema、描述、输入、默认凭据,任何一项不过就不进目录。第四步,让 Agent 拿交换来的、带 scope 的短时 token,而不是用户的密码。第五步,在生产流量上跑评估,IBM 那边给的是自定义 LLM-as-a-Judge、用户模拟与确定性校验、Trace Inspector 和一个专门排查失败的 AgentOps Agent。

# Trace records that make an incident review possible six weeks later.
import json, time, uuid

def trace(identity, tool, args, decision, result):
    return {
        "id": str(uuid.uuid4()),
        "ts": round(time.time(), 3),
        "agent_id": identity["id"],
        "agent_version": identity["version"],
        "on_behalf_of": identity.get("on_behalf_of"),   # the human, if any
        "tool": tool,
        "args_digest": hash_args(args),                 # never the raw payload
        "decision": decision.reason,
        "allowed": decision.allow,
        "outcome": result.get("status"),
        "duration_ms": result.get("duration_ms"),
    }

# Three fields do the work: agent_id (which agent), on_behalf_of (which human),
# args_digest (what it touched, without storing the customer's data twice).
开发者在终端里检查身份与令牌

Agent 不该拿着用户的密码;它该拿一个写着"哪个 Agent、代表谁、能做什么、到几号失效"的令牌。

📌 常见问题 FAQ

Agent Identity 和普通服务账号有什么区别?

服务账号是共享的、匿名的、通常不过期的;Agent Identity 是每个 Agent 一个、独立于创建者和使用者的可验证身份,带归属、生命周期状态、已批准工具和授权范围。区别体现在审计上:一次操作能追到具体是哪个 Agent、代表哪个人做的。

AI 网关只是做限流和协议转换吗?

按 IBM 的描述,它是跨平台的单一执行层:发现第三方 Agent、模型和 MCP 服务器,并统一施加观测、评估与优化策略。限流和协议转换只是其中一部分能力,更关键的是让多平台采购之后的资产有一个统一的库存和执行点。

目录里的 MCP 检查项为什么重要?

因为它检查的是真实攻击面:工具描述可以被写成提示注入,schema 可以被写成越权参数,默认凭据可以直接交出服务器。公告列出的一致性、schema 完整性、描述安全、输入校验和默认凭据拒绝,本质是一份可以在 CI 里自动化的准入清单。

Premium Runtime 的"零横向移动"具体指什么?

指 Agent 之间不存在共享内核或可穿越的网络路径,一个 Agent 被攻破之后无法借此访问邻居。配合硬件虚拟化容器隔离和硬件绑定的资源约束,目的是让 Agent 执行动态工具代码时的爆炸半径可控。

小团队有必要建这些东西吗?

规模不同,优先级不同,但顺序是对的:先有身份记录(否则审计无从谈起),再把工具调用收到一个执行点(否则策略无处施加),然后对第三方工具做准入检查,最后才是评估与观测。前两步一个下午就能做出雏形,收益也最大。