Enterprise MCP infrastructure | October 15, 2026

Private reachability is not authorization.

Outbound tunnels and in-cluster gateways keep MCP servers off the public internet. Production trust still depends on proving who initiated each call, what authority traveled with it, which downstream action occurred, and how the path fails and recovers.

Outbound tunnel In-cluster gateway Identity separation Sources checked Oct 15
Private MCP connectivity architecture with transport, identity, authorization, evidence, and recovery gates

Private MCP is becoming a deployment choice, not a workaround

Two current releases make the architecture concrete. Google announced MCP support in Apigee hybrid 1.17 on October 14, placing the MCP data plane inside a customer's Kubernetes cluster. OpenAI documents Secure MCP Tunnel as an outbound-only path from a customer-run client to an OpenAI-hosted tunnel endpoint. Both reduce the need to publish a private tool server directly. Neither turns connectivity into permission.

Apigee hybrid converts operations from an OpenAPI 3.0.x document into MCP tools. The control plane generates configuration, the cluster fetches that configuration, and agent requests reach an MCP data plane that runs beside the private APIs. Google states that MCP request traffic stays inside the cluster. Its production guidance still requires ingress policy so only Apigee Message Processor pods can reach the MCP service on TCP 443.

OpenAI's tunnel pattern moves the initiation point in the other direction. A customer-run tunnel-client authenticates to the OpenAI control plane, long-polls for queued work, forwards JSON-RPC to a private HTTP or stdio MCP server, and posts the response back. The private server needs no public listener, but the client must reach OpenAI over outbound HTTPS and must remain able to reach the private server. If the client disconnects, tunnel calls fail until it reconnects.

The official openai/tunnel-client repository showed 567 stars and 24 open issues when checked on October 15. Exact community discussion of these two releases was thin. That is a reason to keep the claims narrow: the public artifacts prove architecture and documented behavior, not broad adoption or field reliability.

A private route answers “how can the request get there?” Production review must still answer “who may ask, what may happen, how do we prove it, and what happens twice?”

Two patterns move different boundaries

Pattern A: outbound tunnel
hosted AI product -> hosted tunnel endpoint
                         ^
                         | outbound HTTPS poll / response
customer network: tunnel-client -> private MCP server -> internal API

Pattern B: in-cluster gateway
agent client -> Apigee Message Processor -> in-cluster MCP data plane
                                              -> private API
control plane ---------------- config bundle --------^

The tunnel pattern is useful when a hosted AI product must call a server on a laptop, VM, private service, or on-premises network. It avoids a new inbound firewall rule and provides health, readiness, metrics, and a loopback admin UI in the client. It also introduces a durable customer-side daemon, a hosted queue and endpoint, runtime credentials, and a polling path that operators must own.

The in-cluster gateway pattern is useful when APIs already sit behind Apigee hybrid and must stay within a regulated or multi-cloud runtime boundary. It reuses OpenAPI, gateway policies, analytics, and Kubernetes controls. It also depends on control-plane configuration delivery, watcher identity, Message Processor routing, cluster policy, and the correctness of the generated tool surface.

QuestionOutbound tunnelIn-cluster gateway
Inbound public listenerNot required for the private MCP serverNot required outside the cluster path
Request initiationCustomer client polls hosted control planeAgent traffic enters existing gateway path
Primary local componentLong-running tunnel clientMCP data-plane service and Message Processor
Config dependencyTunnel, profile, channel, proxy, server bindingOpenAPI, Discovery Proxy, fetched config bundle
Natural failureDisconnected client or stale queue workConfig, watcher, route, or network-policy failure
Best fitHosted product reaching private or local toolsGoverned APIs already running in Apigee hybrid

Do not choose from the table alone. An organization may use both: an in-cluster gateway exposes governed APIs as tools, while an outbound tunnel gives a hosted agent a private route to that gateway. Composition creates another end-to-end system. It must preserve identity, deadlines, cancellation, error classes, and evidence across every hop.

Review seven boundaries separately

  1. Placement. Identify where tool definitions, request bodies, responses, credentials, logs, queues, and configuration exist. “Data plane is local” does not mean every control-plane artifact is local.
  2. Transport identity. Prove which tunnel client, pod, workload, organization, and workspace may use the path. Rotate and scope runtime credentials independently from user credentials.
  3. Acting principal. Preserve the human or service principal on whose behalf the agent acts. A shared gateway account cannot explain which user requested a payroll export.
  4. Tool authorization. Limit discovery and calls by principal, task, environment, tool, resource, method, and consequence. A visible tool is not automatically an allowed tool.
  5. Downstream authority. Decide whether the MCP server uses delegated user tokens, a workload credential, a per-tool service identity, or a brokered token exchange. The downstream API is the enforcement point that matters.
  6. Evidence. Correlate product invocation, tunnel or gateway transport, MCP request, policy decision, downstream effect, response, and approval. Transport logs alone do not prove business outcome.
  7. Recovery. Define duplicates, retries, cancellation, stale work, partial effects, reconnects, rollbacks, and operator escalation. A private path can still repeat a destructive action.

The MCP 2026-07-28 authorization specification requires OAuth 2.1 protections, protected-resource metadata, authorization-server discovery, token audience validation, and scope minimization. Those rules secure an MCP authorization flow. They do not decide whether a particular user may invoke refund_invoice for a particular account, or whether the server may reuse a system credential to bypass that user's business permissions.

Enterprise Managed Authorization adds a useful identity assertion pattern when the client and server share an enterprise identity provider. It still needs a policy that maps identity to resources and actions. Treat protocol conformance as a prerequisite, not a business-authorization verdict.

Write the connection as a versioned contract

A connectivity contract gives security, platform, API, and application owners one review object. Pin the protocol version, component versions, tool catalog, identities, destinations, timeouts, evidence fields, retry rules, and rollback. Keep secrets out of the file; reference secret-manager identities.

apiVersion: private-mcp.connectivity/v1
connection: finance-readonly-prod
transport:
  pattern: outbound-tunnel
  client_release: pinned-sha256
  control_plane: api.openai.com:443
  mcp_target: unix:///run/finance-mcp.sock
identity:
  workload: spiffe://corp/agent-connectors/finance
  acting_principal: required
  downstream_token: delegated-and-audience-bound
authorization:
  discover: [ledger.lookup, invoice.read]
  deny: [invoice.pay, vendor.write, journal.post]
  constraints:
    environment: production
    max_rows: 500
    purpose: approved_finance_analysis
reliability:
  deadline_seconds: 30
  max_attempts: 2
  idempotency_key: required_for_effects
  disconnected_behavior: fail_closed
evidence:
  correlation_id: required
  policy_decision: required
  downstream_receipt: required
  payload_logging: redacted
rollback:
  owner: platform-oncall
  action: disable-tunnel-and-revoke-runtime-key

For Apigee hybrid, the same contract would name the 1.17+ runtime, Discovery Proxy, OpenAPI document hash, watcher identity, MCP service, allowed Message Processor selectors, Kubernetes policy object, backend credential model, and configuration-reconciliation evidence. A generated tool catalog should not change merely because an API specification added an administrative operation.

Diff the contract in review. Additions to tools, scopes, destinations, identities, or retry counts are security changes even when the network route stays the same. Re-run acceptance tests after a protocol, client, gateway, OpenAPI, authorization-server, backend, model, or policy update.

Keep workload, user, and downstream identity distinct

The tunnel or gateway needs a workload identity to join the system. The agent request needs an acting principal to express whose task is running. The downstream API needs a credential and audience appropriate to the requested action. These may be related, but they are not interchangeable.

Use delegated OAuth when the downstream action must remain inside the user's authority. Use a service identity only for genuinely service-owned work, and constrain it with resource and action policy. Never accept “the agent was approved” as a substitute for deciding which principal owns the side effect.

OpenAI documents that OAuth discovery may travel through the tunnel while the authorization server itself is not automatically tunneled. That creates a precise failure to test: the MCP server is reachable, but browser-facing authorization cannot complete. The correct result is an explicit authentication failure, not a fallback to an overprivileged server token.

def authorize(call, transport, principal, policy):
    assert transport.client_id in policy.allowed_clients
    assert principal is not None
    assert call.tool in policy.tools_for(principal)
    assert call.resource in policy.resources_for(principal)
    assert call.purpose in policy.approved_purposes
    token = broker.issue(
        subject=principal,
        audience=call.downstream_audience,
        scopes=policy.min_scopes(call)
    )
    return token

Authorization-dependent discovery is preferable when the tool catalog itself reveals sensitive systems or operations. If the platform cannot filter discovery, return stable denial responses at call time and keep prohibited tools out of model context where possible. A denial needs a machine-readable reason, not a fabricated empty result.

Operate the path as a service, not a cable

OpenAI's client exposes /healthz, /readyz, /metrics, /health/mcp, and a loopback admin UI. Use them to prove process health, control-plane connectivity, MCP discovery, queue behavior, and channel availability. Do not expose the admin UI remotely without an explicit operator network and authentication decision.

Apigee hybrid needs its own evidence: configuration bundle age, watcher success, MCP service endpoints, Message Processor reachability, policy reconciliation, backend latency, tool-list version, and denied connections from non-authorized pods. A green Kubernetes pod is weaker than a synthetic call that proves the intended principal can list one allowed tool and cannot list or call a denied tool.

# Illustrative acceptance probes
curl --fail --silent http://127.0.0.1:PORT/readyz
curl --fail --silent http://127.0.0.1:PORT/health/mcp?details=true

# Then run signed end-to-end fixtures:
# 1. allowed principal + allowed read tool -> exact result + receipt
# 2. allowed principal + denied write tool -> structured denial
# 3. wrong audience token -> 401, no downstream request
# 4. duplicate effect request -> one effect, same receipt
# 5. stopped client / blocked pod route -> explicit unavailable state

Correlate evidence with one run ID across the hosted product, transport, MCP server, authorization service, and downstream API. OpenAI notes that tunnel transport requests are not themselves emitted as ChatGPT Compliance Platform app events, while normal app-level invocation and auth lifecycle logging still applies. That boundary belongs in the evidence map. Do not assume one compliance export contains every hop.

Measure availability by consequence. A read-only documentation tool can retry more freely than a payment or change-management tool. For effects, require idempotency at the downstream system, persist an outcome receipt, and distinguish “request accepted,” “action performed,” and “result confirmed.” Cancellation after the downstream effect is not a rollback.

Failure modes private placement does not remove

Failure modeWhat it looks likeRequired response
Tunnel or gateway unavailableTool list works from cache but calls hang or failExpire catalog, return unavailable, alert owner
Identity collapseEvery call reaches the backend as one admin service accountRequire acting principal and least-privilege token broker
Stale generated toolsOpenAPI changed but discovery or policy did notPin hashes, reconcile, block unmatched versions
OAuth path splitPrivate MCP is reachable; authorization server is notFail closed and route to operator, never substitute credentials
Duplicate effectReconnect or retry repeats a writeDownstream idempotency key and effect receipt
Partial evidenceTransport success exists without downstream outcomeCorrelate policy, call, effect, response, and confirmation
Fail-open fallbackPrivate route failure silently switches to public or local file pathExplicit fallback policy; default deny for sensitive tools
Overbroad discoveryModel sees tools the principal cannot useFilter catalog or return stable authorization denial
Control-plane driftLocal runtime uses old policy or routing materialMaximum config age, reconciliation alert, safe stop

One current r/mcp practitioner comment captured a small but important reliability rule: a server that cannot reach its intended application should fail instead of silently writing to a local fallback. Apply the same principle to enterprise connectivity. A fallback that changes destination, credential, evidence, or effect semantics is a new route and requires its own approval.

Use a four-stage rollout

  1. Map. Draw every hop, identity, credential, tool catalog, log, queue, and control plane. Mark which data leaves the runtime boundary and which metadata the hosted platform stores.
  2. Constrain. Start with read-only tools, a non-production backend, a single workspace, explicit scopes, low row limits, and no automatic fallback.
  3. Challenge. Test denied principals, token audience, stale config, network partitions, stopped clients, duplicate delivery, slow downstreams, cancellation, oversized responses, and audit export completeness.
  4. Release. Require platform, API, security, data, and application owners to approve the exact contract. Publish the operator runbook, escalation route, revocation action, recovery target, and review date.

Production gate

  • Exact component, protocol, config, OpenAPI, and policy versions are recorded.
  • Workload identity, acting principal, and downstream credential are distinguishable in evidence.
  • Allowed and denied discovery and call fixtures pass.
  • Network policy limits the local MCP service to intended callers.
  • Retries cannot duplicate consequential actions.
  • Health signals cover route readiness, not only process liveness.
  • Logs cover policy decision and downstream outcome without leaking secrets.
  • Operators can revoke the route, rotate credentials, reconcile config, and recover service.

The decision is not “tunnel versus gateway.” It is whether the composed route produces a narrower, observable, and recoverable authority path than the integration it replaces.

FAQ

Does a private MCP tunnel make a tool safe?

No. It removes a public inbound path. It does not establish user authority, downstream least privilege, safe retries, complete evidence, or recovery.

Is Apigee hybrid safer than an outbound tunnel?

Not categorically. It keeps the runtime data plane in the customer cluster and can reuse gateway and Kubernetes controls. The tunnel keeps the private server off the public internet and fits hosted products. Evaluate the exact topology and consequence.

Should every MCP call use the user's token?

No. Some work is service-owned. The rule is to name the acting principal and use the narrowest credential appropriate to the action. Shared administrative credentials need an exceptional, documented reason.

What is the minimum useful test?

Run one allowed read, one denied write, one wrong-audience token, one duplicate effect, and one disconnected-route test. Verify policy, downstream effect, evidence, and operator recovery for each.

Sources and further reading

Current facts and public artifacts were checked on October 15, 2026. Product behavior and availability can change; validate the current documentation and release before deployment.