---
title: "New from Zuplo - July 2026"
description: ""
canonicalUrl: "https://zuplo.com/changelog/2026/08/01/monthly-changelog"
pageType: "changelog"
date: "2026-08-01"
tags: "runtime, dev-portal, portal, cli, policy, security, monetization"
---
July 2026 takes the **MCP Gateway** to general availability and adds role-based
tool access and Cross-App Access support. New **Audit Logs** capture a
structured, queryable record of every request to your API, and **observability
is now included on every plan**, with a new analytics Overview page. The AI
Gateway speaks the **Anthropic API** natively, and the Dev Portal adds
**Microsoft Entra ID authentication** and guided MCP connection setup.

## MCP Gateway Is Now Generally Available

The MCP Gateway, announced in beta last month, is now generally available. The
beta label is gone across the product and docs, and July brought a set of
access-control capabilities aimed squarely at enterprise rollouts.

**Role-based tool access**: The MCP Capability Filter policy now supports
per-caller access control. In `rolesAndGroups` mode, the policy matches the
caller's role and group claims against the roles and groups you assign to each
capability, so one virtual server can expose different tools, prompts, and
resources to different users.
Capabilities marked `public: true` stay visible to everyone, unclassified
capabilities are exposed to no one until you classify them, and everything
fails closed. A `function` mode accepts a custom resolver module for
authorization logic beyond roles and groups. The MCP Gateway wizard's Tools
step gains matching **Roles & groups** controls, so you can configure all of
this without editing JSON. See
[Per-Role Tool Catalogs for Your MCP Server](https://zuplo.com/blog/per-role-mcp-tool-catalogs)
for a worked example.

**Cross-App Access (ID-JAG)**: The MCP Gateway now supports the Identity
Assertion JWT Authorization Grant, the emerging standard behind Okta's
Cross-App Access, across the generic MCP OAuth policy and all identity provider
variants (Auth0, Okta, Microsoft Entra, Google, Amazon Cognito, Clerk, WorkOS,
Keycloak, Logto, OneLogin, and Ping). The MCP Token Exchange policy adds an
`id-jag` auth mode that exchanges the caller's identity token for an upstream
token without another round of user consent, so agents move between apps under
one enterprise identity. See the
[MCP Token Exchange documentation](https://zuplo.com/docs/policies/mcp-token-exchange-inbound)
and
[Decouple Agent Auth From Your MCP Server](https://zuplo.com/blog/decouple-agent-auth-mcp-server),
which includes a video walkthrough.

Also released this month:

- **API key upstream auth in the wizard**: The Outbound Auth step offers an API
  key mode that scaffolds a Set Upstream API Key policy sending
  `$env()`-sourced secrets to the upstream server
- **Visual policy designer**: The policy editor gains a Designer tab with a
  visual capability-filter editor that probes the live upstream catalog
- **Consent prompt control**: A `prompt` option on upstream OAuth configuration
  stops providers like Microsoft Entra from forcing a consent screen on every
  connection
- **Configured scopes on the wire**: Scopes set on the token exchange policy
  are now sent on upstream authorization requests, making refresh-token
  behavior like `offline_access` configurable

Get started with the
[MCP Gateway documentation](https://zuplo.com/docs/mcp-gateway/introduction).

---

## Audit Logs

Zuplo now records a complete audit trail of your API with a single policy: the
gateway captures a structured event for every request, stores the events for
you, and makes them available in the Zuplo Portal and through the Zuplo API. No
database, logging service, or other infrastructure of your own to run.

Add the Audit Logs policy to any route and every request produces a
[CloudEvents](https://cloudevents.io/) 1.0 event capturing the actor, HTTP
method and path, response status, caller IP address, and geolocation:

```json
{
  "name": "audit-logs",
  "policyType": "audit-logs",
  "handler": {
    "export": "AuditLogInboundPolicy",
    "module": "$import(@zuplo/runtime)"
  }
}
```

The policy's `include` options let you turn off individual fields (query
parameters, user identity, IP address, geolocation) to satisfy your PII
policies, and `samplingRate` captures a fraction of requests on high-volume
routes. You can also emit your own domain events (for example, "account
deleted") from handlers and custom policies with the static
`AuditLogInboundPolicy.log()` method. Audit logging is best-effort by design:
it never blocks or fails the request.

**In the Portal**, a new Audit Logs service under the Services tab lets you
search and filter events by time range, event type, actor, and subject, see
top event types and most active actors, and inspect any event's full payload.
MCP Gateway traffic is audited too, so tool calls are attributed to the end
users who made them.

**Through the API**, `GET /v1/audit-logs/{bucketId}/events` searches events
and `GET /v1/audit-logs/{bucketId}/stats` returns top event types and actors.
Both operations are also exposed as tools on the Zuplo MCP server, so you can
ask an agent what changed. Export to your SIEM from the same endpoints.

Audit Logs are an Enterprise add-on. See the
[Audit Logs documentation](https://zuplo.com/docs/articles/audit-logs) to get
started, and the
[Audit Logs policy reference](https://zuplo.com/docs/policies/audit-log-inbound)
for all options.

---

## Observability Included on Every Plan

Analytics, logs, and traces are now part of every Zuplo plan, including Free.
Plans differ by how much history you keep, not by which tools you get:

| Plan               | Analytics history | Log & trace history |
| ------------------ | ----------------- | ------------------- |
| Free               | 1 day             | Live tail (last 15 minutes) |
| Builder / Business | 7 days            | 1 day               |
| Enterprise         | 30 days           | 3 days              |

Custom retention is available on Enterprise plans, and every new account gets
an automatic 14-day trial with extended windows. The in-portal OpenTelemetry
tracing views launched in June are included under the same windows, so every
account can now drill into span waterfalls. See
[Analytics access and data retention](https://zuplo.com/docs/analytics/access-and-entitlements)
for details.

The Analytics section also opens on a new **Overview** page: a product-tailored
summary of key metrics, traffic, locations, latency, cache performance, and top
consumers. API Gateway projects lead with requests, server errors, and latency;
AI Gateway projects lead with tokens, estimated cost, and model usage. The AI
analytics section is now called **AI & LLMs**, and its report also renders on
AI Gateway app and team pages with one-click drill-in to full analytics. A
**Last 30 days** preset joins the time-range picker.

---

## AI Gateway: Native Anthropic API Support

The AI Gateway's `/v1/messages` endpoint is now a native Anthropic passthrough
instead of a translation to an OpenAI-compatible shape. Request bodies are
forwarded verbatim, new Anthropic fields and client headers like
`anthropic-beta` pass straight through, and Anthropic's own error format is
returned. Streaming responses reach your client untouched while usage is
metered from a background copy. The AI firewall, semantic cache, and Opik and
Galileo tracing all understand native Anthropic requests end to end, including
streaming.

Also released this month:

- **Semantic cache TTL**: A new Cache TTL setting (next to Semantic Tolerance)
  controls how long cached responses are served, up to 30 days
- **Standard cache headers**: Cache outcomes are reported in the RFC 9211
  `Cache-Status` response header, including the match similarity on hits, and
  the app Test page shows a matching cache hit badge
- **Cache hit rate fixed in analytics**: Semantic cache hits now emit analytics
  events (recorded with zero cost and zero tokens), so the dashboard's cache
  hit rate reflects reality
- **OpenAI gpt-5 and o-series support**: The gateway now sends
  `max_completion_tokens` to OpenAI, so client requests using `max_tokens` keep
  working against models that reject it
- **Provider-name routing**: Route requests to a provider by its display name
  using the `providerName/model` format, alongside a redesigned AI Providers
  page
- **Redeploy on demand**: A Redeploy Gateway button on Settings rolls your
  gateway onto the latest runtime whenever you choose

---

## Runtime Improvements

### AWS Upstream Authentication

Calling AWS from your gateway no longer requires hand-rolled request signing.
Two new inbound policies resolve AWS credentials and register them on the
request context: **Upstream AWS Service Auth** uses an IAM access key pair
(with optional STS AssumeRole), and **Upstream AWS Federated Auth** exchanges
Zuplo's ambient OIDC identity for temporary credentials via STS
AssumeRoleWithWebIdentity, so no AWS secrets are stored anywhere. The AWS
Lambda handler picks up the resolved credentials automatically:

```json
{
  "/lambda/{path}*": {
    "x-zuplo-route": {
      "handler": {
        "export": "awsLambdaHandler",
        "module": "$import(@zuplo/runtime)",
        "options": { "region": "us-east-1", "functionName": "my-function" }
      },
      "policies": { "inbound": ["upstream-aws-federated-auth"] }
    }
  }
}
```

For custom code, the new `@zuplo/runtime/aws` module exposes `AwsClient`,
`AwsV4Signer`, and credential providers, so a handler can sign any AWS request
with `signRequest()`. Both policies are in beta for Enterprise accounts. See
the
[Upstream AWS Federated Auth documentation](https://zuplo.com/docs/policies/upstream-aws-federated-auth-inbound)
and
[Upstream AWS Service Auth documentation](https://zuplo.com/docs/policies/upstream-aws-service-auth-inbound).

### Claims-Based Authorization Rules

The new Require User Claims policy authorizes requests against the
authenticated user's claims, separating authorization from authentication: any
auth policy (JWT, API key, mTLS) proves who the caller is, then a declarative
rule decides what they may call. Rules combine `and`/`or` logic with exact
(`eq`), allowlist (`in`), and prefix (`startsWith`) checks, and reach nested or
namespaced claims:

```json
{
  "rule": {
    "or": [
      { "claim": "sub", "in": ["ci-deployer@my-project.iam.gserviceaccount.com"] },
      { "claim": "['https://example.com/roles']", "eq": "admin" }
    ]
  }
}
```

Checks fail closed: no user means `401`, a failed rule means `403`, and denied
responses never echo claim values. See the
[Require User Claims documentation](https://zuplo.com/docs/policies/require-user-claims-inbound).

Also released this month:

- **WebSockets are generally available**: The WebSocket pipeline handler is out
  of beta. With no message policies configured it becomes a transparent
  passthrough that stays out of the data path, upstream connection failures
  return proper HTTP errors, and a new `onOpen` hook runs your code once when
  both sides of the connection are established. See the
  [WebSocket Pipeline Handler documentation](https://zuplo.com/docs/handlers/websocket-pipeline-handler)
- **Upstream request timeouts**: The URL Forward and URL Rewrite handlers
  accept a `requestTimeoutSeconds` option; when the upstream exceeds it, the
  gateway returns `504 Gateway Timeout` instead of waiting indefinitely
- **Data Loss Prevention supersedes Secret Masking**: The Secret Masking policy
  is deprecated (it keeps working). The
  [Data Loss Prevention policy](https://zuplo.com/docs/policies/data-loss-prevention-outbound)
  covers the same secret patterns as part of a catalog of 60+ built-in
  entities, adds `block`/`log` actions and per-pattern confidence scoring, and
  the Secret Masking docs include a migration guide
- **Upstream Zuplo JWT claims mapping**: The Upstream Zuplo JWT policy gains
  `subject` and `claimsFromUser` options for minting tokens with claims mapped
  from the authenticated user
- **Stable trace identity**: OpenTelemetry spans now carry consistent
  `zuplo.policy.type`, `zuplo.policy.name`, `zuplo.policy.direction`, and
  `zuplo.handler.type` attributes, so you can filter traces by policy in any
  backend
- **Fixes**: Errors thrown in `zuplo.runtime.ts` initialization are surfaced as
  a Gateway Initialization Error response instead of being swallowed, and the
  rate limit policy's async mode no longer logs unhandled promise rejections
  when the rate-limit service is unreachable

---

## Dev Portal Updates

### Microsoft Entra ID Authentication

The Dev Portal adds a first-class Entra ID auth provider. Unlike generic OpenID
configuration, it handles Entra's multi-tenant issuer templates, resolves the
concrete tenant from each token, and falls back to `preferred_username` when
the mutable `email` claim is absent. The immutable `oid` and `tid` claims are
surfaced on the user profile for reliable identity checks:

```typescript
// zudoku.config.ts
const config: ZudokuConfig = {
  authentication: {
    type: "entra",
    clientId: "<your-application-client-id>",
    tenantId: "common", // or your tenant ID, "organizations", "consumers"
  },
};
```

CIAM tenants are supported via an `issuer` override. See the
[Entra ID setup guide](https://zuplo.com/docs/dev-portal/zudoku/configuration/authentication-azure-ad).

### Guided MCP Connection Setup

The MCP endpoint page in the Dev Portal replaces the config tabs with a guided
onboarding flow: a prominent copyable server URL (with an
authentication hint when the server requires a key), a visual client picker,
and numbered per-client setup steps for Claude, Codex, Cursor, VS Code, and
generic clients. Cursor and VS Code get one-click install buttons using their
native deep links; the buttons only appear when no API key header is needed, so
secrets are never embedded in a link.

![Dev Portal MCP connection page with copyable server URL, client picker, and per-client setup steps](../public/media/changelog/2026-08/mcp-connect-page.png)

Generated install snippets also now use the MCP server's real `name` from the
route's MCP handler options, so the server name the docs tell users to install
matches what clients see when they connect. See the
[Documenting MCP Servers guide](https://zuplo.com/docs/dev-portal/documenting-mcp-servers).

### Server-Side Rendering

The Zuplo-hosted Dev Portal can now render server-side per deployment. Set
`devPortal.serverSideRendering: true` in `zuplo.jsonc` and protected routes are
enforced on the server: protected content leaves the public bundle entirely,
and unauthenticated requests cannot fetch it. SSR applies to preview and
production deployments and is an Enterprise add-on. See the
[server-side rendering guide](https://zuplo.com/docs/dev-portal/server-side-rendering).

Also released this month:

- **Search covers protected pages**: In statically rendered portals, pages
  behind `protectedRoutes` now appear in search results instead of silently
  missing, and builds log a warning listing any routes excluded from the index
- **Clearer pricing cards**: Monetization pricing cards now distinguish
  pay-as-you-go from hard caps, so unlimited usage no longer displays as a
  "0 / month" quota, and tiered price breakdowns render volume and graduated
  billing modes correctly
- **Multiple subscriptions**: When enabled for the environment, the pricing
  page lets customers subscribe to several plans at once (see Monetization
  Updates below)
- **Slimmer installs**: The Dev Portal CLI dropped its error-reporting
  dependency, removing 20 packages from every install and fixing a build
  failure mode caused by npm hoisting
- **Fixes**: The pricing page no longer crashes after logout, and top
  navigation links honor a configured `target` such as `_blank`

---

## Monetization Updates

July's monetization changes span the plan editor, billing, and the runtime:

- **Free trial phases**: A plan's first phase can be marked as a free trial in
  the plan editor; returning subscribers who already used their trial start on
  the paid phase automatically
- **Stripe Tax**: Enable and configure tax collection from the Payment Provider
  page: toggle Stripe Tax, set your supplier country, choose inclusive or
  exclusive pricing, and pick a tax code
- **Multiple active subscriptions**: Consumers can hold several subscriptions
  at once, enabled per environment on the Payment Provider page
- **Usage history**: Subscription pages now show historical usage for past
  billing periods, and the invoice status filter searches all invoices instead
  of the current page
- **Reliable metering**: Usage events are now retried with backoff and
  deduplicated by event ID, so a transient network blip no longer drops billable
  usage, and the new `MonetizationInboundPolicy.flushMeters()` API submits
  accumulated runtime meters immediately instead of at request end

Metering MCP traffic? See
[Charge Agents for MCP Tool Calls](https://zuplo.com/blog/charge-agents-for-mcp-tool-calls)
for a pattern that meters tool calls while protocol chatter stays free.

---

## Portal & CLI Updates

### Redesigned Route Test Console

The route test console was rebuilt around a two-pane layout: an editable URL
bar, a tabbed request builder with body editors (JSON, GraphQL, form, or
text), headers, and API-key or bearer auth, and a response panel with the
status line, timing, and size. On top of the redesign:

- **Request history**: Reopen any earlier request with its full setup restored
- **Endpoints panel**: A collapsible panel lists every route in your API, so
  you can switch what you're testing without leaving the console
- **MCP request bodies**: An MCP body type (auto-selected on MCP server routes)
  offers one-click standard calls like listing and calling tools, no
  hand-written JSON-RPC required
- **Build-aware testing**: When you test while a deploy is in flight, the
  console waits for the new build to go live before sending, so you always test
  the code you just saved

### Services Navigation Redesign

The Services tab now opens with a sidebar listing every service and its pages
(API Keys, Monetization, Audit Logs, and Metering where enabled), with one
environment switcher for the whole section. The API Key Service page also got
a full redesign with a cleaner consumer list, tidier key controls, dark mode
support, and an API Keys tab in the consumer dialog listing every key's
creation and expiry dates.

![Redesigned Services section with sidebar navigation, environment switcher, and the refreshed API Key Service page](../public/media/changelog/2026-08/services-sidebar.png)

Also released this month:

- **Route Designer: API metadata and files**: Edit your API's title, version,
  description, contact, and license from the top of the routes list, switch
  between OpenAPI files or add a new one in place, and imported OpenAPI files
  now save immediately
- **Route Designer: grouping and search**: Group routes by handler type or by
  upstream target, and find any route from the ⌘K palette by path, method,
  handler, or policy. Read-only environments show a banner offering to switch
  to Development or check out the branch
- **Environment variables in bulk**: The create dialog supports multiple rows
  with a per-row secret toggle, and pasting a `.env` file fills them in
  automatically
- **Account-level custom domains**: Add a custom domain from the account's
  Custom Domains page and pick the target project in the dialog
- **Programmatic project provisioning**: The Developer API's project create
  endpoints now support API-key authentication and account-admin callers, so
  you can provision projects from scripts and CI
- **CLI: local mTLS certificates**: `zuplo dev` auto-detects client
  certificates in `.zuplo-local/mtls` (or takes `--mtls-certs <dir>`), so
  managed-dedicated projects can develop against mTLS backends locally
- **Source control**: Connecting a repository whose default branch requires
  pull requests now pushes to a setup branch and opens the PR for you, and
  pushes no longer fail for GitHub users with private email addresses
- **Fixes**: Analytics chart timestamps are correct in every time zone,
  favoriting a project no longer scrambles the projects list, the MCP settings
  editor no longer discards tool edits, and your last-accessed project follows
  you across devices

---

## Documentation Updates

- [Zuplo Audit Logs](https://zuplo.com/docs/articles/audit-logs): New guide
  covering the Audit Log policy, custom events, the Portal viewer, the query
  API, and SIEM export
- [Dev Portal Server-Side Rendering](https://zuplo.com/docs/dev-portal/server-side-rendering):
  New guide for enabling SSR and protecting content server-side
- [Local Development Debugging](https://zuplo.com/docs/articles/local-development-debugging):
  Rewritten around attaching to the workerd runtime, with one-click VS Code
  setup and WebStorm/IntelliJ steps
- [Securing Backend mTLS](https://zuplo.com/docs/articles/securing-backend-mtls):
  Expanded with client certificate requirements, generation and validation
  steps, and the new local development workflow
- [Self-Hosted Overview](https://zuplo.com/docs/self-hosted/overview): Rewritten
  with how the hybrid model works, lifecycle responsibilities, and
  infrastructure requirements
- [Rate Limiting](https://zuplo.com/docs/rate-limiting/how-it-works): New
  section on sub-minute rate limit windows and the accuracy floor imposed by
  cross-region synchronization
- [Analytics Access & Data Retention](https://zuplo.com/docs/analytics/access-and-entitlements):
  New reference for per-plan observability access, retention windows, and the
  14-day trial