IBM Gave Agents Their Own Identities. The Gateway Is the Part to Copy

·12 min read·Evergreen Tools Team

On October 27, 2026, at TechXchange in Atlanta, IBM added a stack of things to watsonx Orchestrate: agent identities, an AI gateway, a governed catalog, and a runtime that pushes isolation down to hardware-virtualised containers. The sentence in the announcement worth pinning to a wall is this one: the objective is not to restrict what agents can do, but to establish the trust and security foundation needed for agents to take on greater responsibility safely. That tells you what this is. Not another agent builder — a control plane. And the piece most teams should copy is not the catalog. It is the gateway.

A data centre corridor with access control

The gateway is not a new feature. It makes "what do we actually have running" answerable.

1. What was announced, and what it is for

IBM frames the problem as a shift: the challenge is no longer building an agent quickly, it is managing hundreds or thousands of them across a business, keeping them reliable and secure, and improving what they deliver. The announcement splits into three parts — discovery and admission (AI gateway plus governed catalog), runtime isolation (Premium Runtime), and evaluation across the lifecycle. Put together, the message is that an agent stops being a script some team quietly runs and becomes an asset with a name, an owner, a permission boundary and an expiry date.

2. Borrowed credentials make audit logs useless

When Agent Identity went into preview in September, IBM put the problem plainly: many agents today authenticate with shared service accounts. The consequence is concrete. A transfer appears in the audit log and you cannot tell whether a person did it, whether an agent did it for that person, or whether the agent decided on its own. IBM's answer is a verifiable identity per agent, separate from the person who built it and the person using it, wired into the identity provider you already run rather than a new identity store — preview support covered IBM Verify and Microsoft Entra. HashiCorp Vault supplies least-privilege credential access alongside it.

# 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?

3. The gateway matters because there is exactly one enforcement point

The watsonx Orchestrate AI Gateway is described as a single enforcement layer that discovers third-party agents, models and MCP servers across platforms such as Amazon Bedrock, Microsoft and Google, then governs them with consistent observability, evaluation and optimisation. Customers can also call those third-party agents directly from watsonx Orchestrate chat and channels without rebuilding them. This is aimed at the fragmentation that follows multi-vendor purchasing: each platform manages its own estate well and the estate as a whole badly, so inventory is scattered, controls are inconsistent and visibility is local. A gateway does not fix those platforms. It makes "what do we actually have running" an answerable question.

# 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.

4. The catalog is admission control wearing a UI

The hardest paragraph in the announcement is the checks the catalog surfaces. For selected MCP servers — Box, Visier, New Relic among them — it shows protocol conformance, tool schema integrity, tool description safety, input validation, and whether default credentials are rejected. Read that list again as an attack surface: a description can be written as a prompt injection, a schema can be written to accept an over-broad argument, and a default credential hands over the server. The catalog also shows evaluation data at the moment of discovery, aligned to OWASP, CoSAI and the IBM AI Risk Atlas, and for some agents surfaces performance, reliability and latency alongside risk signals, controls and compliance information such as the 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.

5. Three words about the runtime: isolated, lateral-free, metered

Premium Runtime is described as a dedicated, multi-backend hosting, isolation and metering layer, with three concrete properties: hardware-virtualised container isolation, zero lateral movement, and hardware-bound resource containment. In operations language: when an agent executes dynamic tool code it must not share a kernel with another agent; a compromised agent must not be able to walk sideways to its neighbours through the kernel or the network; and its resource ceiling should be bound to hardware rather than to a cgroup setting someone forgot to review. All three apply to teams building this themselves. If your agents run user-influenced code in a shared-kernel container, you do not have isolation, you have a convention.

# 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.

6. A build order that works without buying IBM

First, write an identity record per agent — owner, lifecycle, approved tools, scopes, amount caps, expiry — and keep it in the repo so it gets reviewed with the code. Second, funnel tool calls through one enforcement point and log the denials too, because denials are what reveal an agent reaching for tools nobody granted. Third, gate MCP servers on admission: schema, description, input validation, default credentials. Fourth, give the agent an exchanged, scoped, short-lived token instead of a human password. Fifth, evaluate on production traffic: IBM's set is a custom LLM-as-a-Judge, simulated users with deterministic checks on tool calls, a Trace Inspector, and an 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).
A developer inspecting identity and tokens in a terminal

An agent should not hold a password. It should hold a token that says which agent, for whom, for what, until when.

📌 Frequently Asked Questions

How is Agent Identity different from a service account?

A service account is shared, anonymous and usually long-lived. An Agent Identity is per-agent, verifiable, and separate from both the builder and the user, carrying an owner, lifecycle status, approved tools and granted authority. The difference shows up in audit: one action traces back to which agent did it and which human it acted for.

Is the AI Gateway just rate limiting and protocol translation?

Per IBM it is a single cross-platform enforcement layer: it discovers third-party agents, models and MCP servers and applies consistent observability, evaluation and optimisation. Rate limiting and protocol translation are small parts of it; the larger point is a single inventory and enforcement point across a multi-vendor estate.

Why do the MCP checks in the catalog matter?

Because they map to real attack surface. A tool description can be written as a prompt injection, a schema can be written to accept over-broad arguments, and default credentials can hand over the server. Conformance, schema integrity, description safety, input validation and default-credential rejection form an admission checklist you can automate in CI.

What does zero lateral movement actually mean?

It means agents do not share a kernel or a traversable network path, so a compromised agent cannot reach its neighbours. Combined with hardware-virtualised container isolation and hardware-bound resource containment, the goal is a bounded blast radius when an agent executes dynamic tool code.

Does a small team need all of this?

Different scale, same order. Start with identity records, because without them audit is impossible. Then collapse tool calls into one enforcement point, because otherwise policy has nowhere to live. Then gate third-party tools on admission. Evaluation and observability come last. The first two are an afternoon of work and carry most of the benefit.