Skip to content

1.30.0 - The Gateway for Any Resource: Inference, MCP, A2A, and REST

Latest

Choose a tag to compare

@aarora79 aarora79 released this 09 Sep 03:38
· 1 commit to main since this release

Release 1.30.0 - The Gateway for Any Resource: Inference, MCP, A2A, and REST

September 2026


Upgrading from 1.29.0

This section covers everything you need to know to upgrade from 1.29.0 to 1.30.0.

Breaking Changes

1. Metrics labels on mcpgw_registry_auth_request_total changed. Saved queries, alert rules, and dashboards need a look:

  • Gateway traffic is now classified as target_kind="generic_proxy_skill", generic_proxy_agent, or generic_proxy_custom. Anything filtering target_kind="unknown" stops matching it.
  • On those series, server holds the entity's authz key (for example skill/skills/pdf) instead of the literal gateway.
  • success is lowercase true / false on every exporter. A query written success="True" returns an empty result rather than an error, so it looks like zero traffic instead of a broken query.
  • mcpgw_registry_auth_request_duration_milliseconds no longer carries server. Group it by target_kind.

The shipped Grafana dashboards are already updated. See Observability for the full label reference and what an upgrade changes for the operator checklist.

2. /api/internal/* is no longer served on the public listeners. The internal vend, virtual-server session store, and service-management routes are reachable only on the dedicated internal listener. Anything calling those paths through the internet-facing 8080/8443 listeners must move to the internal listener. Application-level gates were already in place, so this closes the network path rather than an authorization hole (#1697).

3. A legacy methods: ["all"] grant authorizes no HTTP verb on a gateway-proxied entity. This is deliberate: a wildcard minted for MCP tool calls must not silently grant POST or DELETE on a REST backend. Grant verbs explicitly. Registry admins receive them automatically (#1732).

Everything else is additive. No environment variables were removed or renamed, and no Helm chart dependencies changed.

New Environment Variables

The generic proxy ships disabled, so a deployment that sets none of these behaves exactly as 1.29.0 did.

Variable Default Description
GATEWAY_GENERIC_PROXY_ENABLED false Master switch for generating generic-proxy location blocks for proxied non-MCP entities. The feature ships dark.
GATEWAY_PROXY_PREFIX gateway URL path prefix for auto-generated client routes (/{prefix}/{type}/{name}).
GATEWAY_PROXY_ALLOW_PRIVATE_TARGETS false SSRF egress policy. When false, proxy_target_url hosts in loopback, private, or reserved ranges are rejected at registration and render. Link-local and metadata addresses stay denied regardless.
GATEWAY_GENERIC_TLS_VERIFY true TLS verification for the generic hop to HTTPS targets. true uses the system trust store; a filesystem path supplies a custom CA bundle.
GATEWAY_GENERIC_MAX_CONCURRENCY 32 Semaphore cap on in-flight buffered generic-hop requests (OOM guard).
GATEWAY_GENERIC_ACQUIRE_TIMEOUT_SECONDS 5 Max seconds to wait for either concurrency pool before returning 503.
GATEWAY_GENERIC_CLIENT_MAX_BODY_SIZE 1m nginx client_max_body_size for generic-proxy blocks (inbound request body).
GENERIC_PROXY_MAX_BODY_BYTES 10485760 Upper bound on the buffered upstream response body the generic hop reads before returning.
GENERIC_PROXY_TOKEN_TTL_SECONDS 30 TTL for the generic-proxy internal token.
GATEWAY_GENERIC_REQUIRE_BEARER_FOR_WRITES true CSRF defense: refuse a state-changing verb on a generic route when the caller authenticated with a session cookie, before any token mint.
GATEWAY_GENERIC_STREAM_MAX_CONCURRENCY 8 Separate semaphore cap for long-lived streams.
GATEWAY_GENERIC_STREAM_MAX_BYTES 104857600 Raw response-byte ceiling per stream (100 MiB).
GATEWAY_GENERIC_STREAM_MAX_DURATION_SECONDS 3600 Absolute lifetime for one stream, even while chunks keep arriving.
GATEWAY_GENERIC_STREAM_READ_TIMEOUT_SECONDS 3600 nginx upstream read timeout for proxy_streaming routes.
GATEWAY_EGRESS_SELFCHECK_ENABLED true Startup egress self-check: when the generic proxy is enabled, probe-connect to the cloud metadata IPs and latch the feature off if they are reachable.
GATEWAY_CANONICAL_NAMESPACE_ENABLED false Emit canonical /entity_type/path blocks alongside the legacy flat aliases. Keep false; this is a placeholder for a later slice.
EGRESS_CREDENTIAL_ENCRYPTION_KEY (unset) Enables application-layer encryption of per-user egress credentials at rest. When set (32+ chars, high entropy), stored token payloads are AES-256-GCM encrypted.
EGRESS_CREDENTIAL_ENCRYPTION_REQUIRE_ENCRYPTED false Terminal strict mode. When true, and the key above is set, reads reject any remaining legacy plaintext entry instead of accepting it.
EGRESS_OAUTH_TRUSTED_IDP_HOSTS (unset) Operator-named trusted identity providers for per-user egress OAuth token endpoints, so consent works against a self-hosted IdP.

Upgrade Instructions

Docker Compose

cd mcp-gateway-registry
git pull origin main
git checkout 1.30.0

# Review new env vars in .env.example and update your .env if needed
# Then rebuild and restart:
./build_and_run.sh

Kubernetes / Helm (EKS)

cd mcp-gateway-registry
git pull origin main
git checkout 1.30.0

# REQUIRED: 23 files changed under charts/ in this release. The packaged
# subchart .tgz files are gitignored and only repackage when you run these,
# so a plain `helm upgrade` would deploy the OLD subcharts.
cd charts/mcp-gateway-registry-stack
helm dependency build
helm dependency update

# Update values.yaml if needed, then upgrade:
helm upgrade mcp-gateway . -f your-values.yaml

Terraform / ECS

cd mcp-gateway-registry
git pull origin main
git checkout 1.30.0

# 18 new variables are available in terraform/aws-ecs/variables.tf, all with
# safe defaults. Set them in your .tfvars only if you are enabling the
# generic proxy or egress credential encryption.
cd terraform/aws-ecs
terraform plan
terraform apply

Major Features

The gateway fronts any HTTP backend, not only MCP servers

One authenticated entry point now covers four kinds of traffic: model inference (OpenAI, Amazon Bedrock, any OpenAI-compatible endpoint), MCP servers, A2A agents, and any generic REST endpoint registered as a custom entity. Callers hold one gateway token and reach everything through a registry URL, while the backend URL and its credential stay in the registry, encrypted at rest and injected on egress, so no provider key lands on a laptop.

  • Two credential models per record. Caller passthrough is the default and the right choice whenever a human is behind the request, because the provider sees one client per user and quota and billing stay attributable. A shared operator key is optional and meant for service-to-service traffic where there is no end user to attribute.
  • Per-entity response streaming carries SSE and AWS event-stream bodies incrementally, with bounded concurrency, byte, and duration ceilings.
  • The same governance as everything else: scopes, audit trail, and rate limits. A legacy methods: ["all"] grant authorizes no HTTP verb, so nothing gains access by accident.
  • Defense in depth on egress: registration-time and render-time SSRF validation, a startup self-check that latches the feature off if cloud metadata is reachable, internal headers stripped on the generic hop, and a CSRF gate on state-changing verbs for cookie-authenticated callers.
  • Operator surface: a connect affordance and operator notes in the UI, a CLI create path, an auto-derived client URL, and a scope editor.

Off by default (GATEWAY_GENERIC_PROXY_ENABLED=false), per-entity opt-in, no schema migration.

PR #1628 · PR #1691 · PR #1714 · PR #1701 · PR #1731 (closes #1565)

Documentation: Design · Operational Guide · FAQ: call OpenAI or Bedrock through the gateway · FAQ: what an upgrade changes

Per-request observability for the gateway hop

Two counters answer questions the authorization metric never could. mcpgw_registry_auth_request_total reports the authorization decision, which means a 502 from a backend used to read as success=true. The new mcpgw_registry_generic_proxy_request_total records one outcome per request at the hop itself, across 13 values that keep distinct failures distinct: two different 503s (disabled versus capacity) and three different 502s (auth_unavailable, egress_blocked, upstream_error) never collapse into one another, so a switched-off feature cannot page for saturation and an SSRF refusal cannot page for a credential outage. A companion lifecycle counter tracks streams, and every series exists at zero from startup so a rate() alert binds at deploy instead of waiting for the first failure.

PR #1736 · PR #1737 (closes #1735)

Application-layer encryption for per-user egress credentials

Per-user egress credentials can now be encrypted at rest inside the vault payload. Set EGRESS_CREDENTIAL_ENCRYPTION_KEY and stored token payloads are AES-256-GCM encrypted, with a write-carrying migration that upgrades entries as they are used. EGRESS_CREDENTIAL_ENCRYPTION_REQUIRE_ENCRYPTED=true then makes reads reject any remaining plaintext entry, giving a verifiable terminal state rather than an indefinite mixed mode. Egress destination binding and an internal-only vend endpoint complete the isolation.

PR #1675 · PR #1655 · PR #1697 (closes #1665)

Egress OAuth against self-hosted and public-client identity providers

Two gaps closed for per-user egress consent. Public OAuth clients are supported with PKCE for providers that advertise token_endpoint_auth_methods_supported: ["none"] and issue no client secret, which is what Datadog's MCP server requires. And operators can name trusted identity providers via EGRESS_OAUTH_TRUSTED_IDP_HOSTS, so the OAuth token endpoint of a self-hosted IdP is reachable without weakening the credential-bearing egress profile for anything else.

PR #1613 · PR #1707 · PR #1717 (closes #1706)

Metadata-field projection for search and list APIs

Read and search endpoints accept an optional metadata_fields parameter that returns only the requested dot-notation paths from an asset's metadata subdocument. Callers with large or deeply nested metadata can shrink response payloads without affecting any other field. Omitting the parameter returns full metadata exactly as before, so existing integrations need no change.

  • Surfaces: GET /api/servers, GET /api/agents, GET /api/skills and their single-asset variants (query parameter), plus POST /api/search/semantic (request-body field).
  • Two input forms: comma-separated (?metadata_fields=owner,config.region) and repeated query params, which may be mixed.
  • CLI: --metadata-fields on list, agent-list, skill-list, and server-search; metadata_fields on the client library's semantic_search() and list_skills().
  • Database-level projection: the server list path projects the subdocument inside MongoDB via an aggregation $set stage rather than transferring large blobs, with a Python fallback that is provably equivalent to the canonical projection.
  • Fail-closed validation (HTTP 422): at most 20 paths, at most 5 levels deep, segments at most 64 characters, no $-prefixed or empty segments, and a positive character allowlist, so a projection cannot inject a MongoDB operator into the pipeline.
curl "http://localhost/api/servers?metadata_fields=owner,config.region" \
  -H "Authorization: Bearer $TOKEN"
# -> "metadata": {"owner": "team-platform", "config": {"region": "us-east-1"}}

PR #1637 · PR #1673 (closes #1277)

Documentation: Metadata field projection · FAQ


What's New

Security

  • Remove /api/internal/* from the public listeners, completing the network isolation started by the internal vend endpoint (#1697)
  • Fail closed when a failed security scan cannot auto-disable a server, instead of leaving it enabled (#1712)
  • Strip internal headers on the generic hop, close a prefix-match gap, and document the config surface (#1698)
  • Centralize the Authorization carve-out so registration and the storage decrypt cannot disagree about one header name (#1729)
  • Strip ingress proxy-context headers on the egress hop, so an upstream cannot read the caller's ingress context (#1685)
  • Fail closed on caller-identity headers in the virtual-server path (#1672, follow-up to #1627)
  • Send relative nginx redirects on :8080 and :8443 so an internal URL cannot leak (#1635, adopts #1610)
  • Detect SKILL.md redirects from response history rather than the pinned-IP URL, so an allowlisted private forge is reachable while genuine redirects to metadata or non-allowlisted addresses stay refused (#1741)

Authentication and Authorization

  • Grant registry-admins HTTP verbs on gateway-proxied entities (#1732)
  • Filter tools/list against the normalized server name, closing an authorization mismatch on un-normalized names (#1659)
  • Rewrite every internal URL in the Keycloak discovery document (#1688)
  • Pass KEYCLOAK_EXTERNAL_URL to the prebuilt registry image and warn when it cannot work (#1657), and emit that diagnostic once rather than per request (#1683)

Routing and nginx

  • Accept percent-encoded ARNs so AgentCore A2A agents are routable (#1596)
  • Build the A2A agent-card route from the URL origin rather than the JSON-RPC endpoint (#1734)
  • Serve ROOT_PATH-prefixed static assets and the favicon in path mode (#1679)
  • Send relative redirects from the front-door server blocks (#1620)
  • Remove a duplicate absolute_redirect directive that broke nginx -t (#1670)
  • Add proxy_http_version 1.1 to the /validate block and forward the missing headers (#1644)
  • Forward caller-identity headers in virtual-server backend locations (#1627)
  • Fix virtual tools/list endpoint resolution and partial caching (#1634, adopts #1526)
  • Keep empty inputSchema arrays as [] via a Lua fix plus the OpenResty cjson runtime (#1676)

Health and Reliability

  • Stream the MCP ping so a held-open response cannot stall the health check (#1645)
  • Stream MCP initialize instead of buffering the full response (#1614)
  • Make the Keycloak container healthcheck runnable inside the image, which lacks curl (#1656)

Infrastructure

  • Grant the registry exec role read access on the embeddings IdP secret (#1684)
  • Remove > from the auth-server security-group rule description, which Terraform rejects (#1728)
  • Package patched urllib3 into the rotation Lambdas via a build step, so the pin actually remediates (#1636)

API and CLI

  • Reject a half-filled provider pair with 400 instead of 500 (#1658)
  • Forward append_mcp_path from register --config (#1619)
  • Nudge operators about recommended-but-optional configuration (#1694)

Testing and Code Quality

  • Operator test clients, a preflight gate, and a gateway-proxy regression suite (#1730)
  • Cover absolute_redirect off in the front-door server blocks (#1669)
  • Enforce ruff F821 (undefined name) instead of ignoring it (#1682), and fix the annotations it flagged (#1654)

Documentation

  • Position the gateway as an AI gateway for inference, MCP, A2A, and REST (#1739)
  • Add the gateway-proxy operational guide, and fix a log string nothing emitted (#1733)
  • FAQs for registering OpenAI and Bedrock endpoints, and what the gateway proxy changes on upgrade (#1738)
  • Keycloak identity-brokering guide for multi-tenant federation (#1629), plus Cognito and PingFederate examples with a login sequence diagram (#1633)
  • How to choose custom_token_auth_style, and a Datadog MCP public-client FAQ (#1638)
  • Add Salesforce Headless 360 to the third-party MCP server guide (#1605)
  • Resource links in the executive brief (#1674), a refreshed registry-first presentation deck (#1690), and a duplicate-header fix in the debug skill (#1705)

Bug Fixes

  • Detect SKILL.md redirects from history, not the pinned-IP URL, so allowlisted private forges work again (#1741)
  • Build the A2A agent-card route from the URL origin (#1734)
  • Grant registry-admins HTTP verbs on gateway-proxied entities (#1732)
  • Centralize the Authorization carve-out across registration and storage decrypt (#1729)
  • Remove > from the auth-server SG rule description (#1728)
  • Fail closed when failed-scan auto-disable cannot disable a server (#1712)
  • Strip internal headers on the generic hop and close a prefix match (#1698)
  • Rewrite every internal URL in the Keycloak discovery document (#1688)
  • Strip ingress proxy-context headers on the egress hop (#1685)
  • Grant registry exec role read on the embeddings IdP secret (#1684)
  • Emit the KEYCLOAK_EXTERNAL_URL diagnostic once, not per request (#1683)
  • Serve ROOT_PATH-prefixed static assets and favicon in path mode (#1679)
  • Keep empty inputSchema arrays as [] (#1676)
  • Fail closed on caller-identity headers in the virtual-server path (#1672)
  • Remove the duplicate absolute_redirect directive that breaks nginx -t (#1670)
  • Filter tools/list against the normalized server name (#1659)
  • Reject a half-filled provider pair with 400 instead of 500 (#1658)
  • Pass KEYCLOAK_EXTERNAL_URL to the prebuilt registry, warn when it cannot work (#1657)
  • Make the Keycloak container healthcheck runnable inside the image (#1656)
  • Import missing annotation types flagged by ruff F821 (#1654)
  • Stream the MCP ping so a held-open response cannot stall the check (#1645)
  • Add proxy_http_version 1.1 to the /validate block and forward headers (#1644)
  • Package patched urllib3 via a build step so the pin remediates (#1636)
  • Use relative nginx redirects on :8080 and :8443 to prevent internal URL leaks (#1635)
  • Fix virtual tools/list endpoint resolution and partial caching (#1634)
  • Forward caller-identity headers in virtual-server backend locations (#1627)
  • Send relative redirects from the front-door server blocks (#1620)
  • Forward append_mcp_path from register --config (#1619)
  • Stream MCP initialize instead of buffering the full response (#1614)
  • Update Lambda dependencies for urllib3 vulnerabilities (#1612)
  • Accept percent-encoded ARNs so AgentCore agents are routable (#1596)

Closed Issues

Issue Title Closed By
#1740 fix(skills): pinned-IP rewrite makes the redirect check reject SKILL.md fetches from allowlisted private forges PR #1741
#1735 feat(metrics): count gateway-proxy requests and stop reporting hop failures as successes manual
#1725 docs(faq): add FAQs for registering OpenAI/Bedrock endpoints and gateway-proxy backwards compatibility PR #1738
#1724 fix(a2a): build the agent-card route from the URL origin, not from the JSON-RPC endpoint PR #1734
#1706 Egress OAuth consent is impossible against a self-hosted IdP: credentialed-OAuth allowlist is hardcoded empty PR #1707
#1702 Optional Tool Outcome Attestation (TOA) verify gate for MCP CI / promote / register manual
#1695 1.28.0: egress vend keys on username/email while consent writes the OIDC sub, so all bearer clients get an empty tools/list manual
#1665 Security: add application-layer encryption for per-user egress credentials before vault persistence PR #1675
#1660 Ingress template missing /static path rule in path-based routing mode — breaks frontend static assets PR #1679
#1651 Registering with only one of the two provider fields returns an unhandled 500 instead of a validation error PR #1658
#1650 Keycloak container healthcheck uses curl, which is not present in the Keycloak image, so the container is permanently unhealthy PR #1656
#1649 Registry does not receive KEYCLOAK_EXTERNAL_URL, so authorization server metadata and generated nginx config use the internal Docker URL manual
#1648 Scope resolution does not union a user's groups, and picks a different single group between requests manual
#1647 tools/list filtering authorizes against the un-normalized server name, returning 0 tools to every external MCP client PR #1659
#1643 /validate auth subrequest missing proxy_http_version 1.1 - causes 502s on ECS Service Connect PR #1644
#1626 Virtual server _vs_backend locations do not forward caller identity headers (X-User/X-Username) to backends manual
#1625 MCP proxy forwards ingress X-Forwarded-Proto to upstream servers, causing HTTPS redirect loops behind TLS-terminating proxies PR #1685
#1606 bug: MCP server endpoint without trailing slash returns a 301 to an internal http://<host>:8080/... origin, causing MCP clients to hang/time out PR #1620
#1595 AgentCore A2A agents are unroutable: nginx url-safety regex rejects the percent-encoded ARN that AgentCore invocation urls require PR #1596
#1565 Securely proxy arbitrary registered resources through the gateway PR #1714
#1532 Virtual server tools/list corrupts empty JSON-Schema required: [] into {}, breaking strict MCP clients PR #1676
#1337 harden(ard): close DNS-rebinding TOCTOU in the ai-catalog ingestion SSRF guard manual
#1277 feat: optional metadata-field projection (source/select) for search and list APIs PR #1637
#959 Self-signed user tokens include full groups claim even though authorization is scope-based, causing oversized/malformed bearer tokens manual
#893 Upgrade Python base image to 3.14.5 when released (June 9, 2026) manual
#616 AgentCard.streaming AttributeError in discover_agents_by_skills (partial fix from #244 missed this route) manual
#574 Security scan blocks registration response and ignores MCP Endpoint override manual
#553 nginx config hardcodes bare auth-server hostname, breaks Cloud Map DNS deployments manual
#310 Client ssl certificate configuration issue manual

Pull Requests Included

PR Title
#1741 fix(skills): detect redirects from history, not the pinned-IP URL
#1739 docs(readme): position the gateway as an AI gateway for inference, MCP, A2A, and REST
#1738 docs(faq): registering OpenAI/Bedrock endpoints, and what the gateway proxy changes on upgrade
#1737 feat(metrics): record the gateway hop's own outcome, not just the authz decision
#1736 feat(metrics): classify gateway-proxy routes and put the authz key in the server label
#1734 fix(a2a): build the agent-card route from the URL origin, not the JSON-RPC endpoint
#1733 docs(gateway-proxy): add the operational guide, and fix a log string nothing emitted
#1732 fix(scopes): grant registry-admins HTTP verbs on gateway-proxied entities
#1731 feat(gateway-proxy): connect affordance, operator notes, and a CLI create path
#1730 test(gateway-proxy): operator test clients, preflight gate, and regression suite
#1729 fix(gateway-proxy): centralize the Authorization carve-out so registration and the storage decrypt cannot disagree
#1728 fix(terraform): remove ">" from the auth-server SG rule description
#1727 chore(deps): weekly lockfile update (2026-09-07)
#1726 chore(deps): bump the actions group in /.github/workflows with 3 updates
#1717 feat(egress): propagate EGRESS_OAUTH_TRUSTED_IDP_HOSTS to the auth-server
#1714 feat(gateway-proxy): generic-proxy extensions — streaming, static upstream auth headers, caller passthrough
#1712 fix(security): fail closed when failed-scan auto-disable cannot disable a server
#1710 chore(deps): weekly lockfile update (2026-08-31)
#1708 chore(deps): bump the actions group in /.github/workflows with 3 updates
#1707 feat(url-guard): allow operator-named trusted IdP hosts for egress OAuth token endpoints
#1705 docs: Fix duplicate header in debug SKILL.md
#1701 feat(gateway-proxy): scope-editor support, entity-form toggles, and auto-derived client URLs
#1698 fix(gateway-proxy): strip internal headers on generic hop, close prefix-match, document config
#1697 Remove /api/internal/* from the public listeners
#1694 feat(observability): nudge operators about recommended-but-optional config
#1691 Gateway proxy for any registry resource - deployment (PR 2 of 1565)
#1690 docs(slides): refresh presentation PDF with restructured registry-first deck
#1688 fix(keycloak): rewrite every internal URL in the discovery document
#1685 fix(auth): strip ingress proxy-context headers on the egress hop
#1684 fix(ecs): grant registry exec role read on embeddings-idp-secret
#1683 fix(keycloak): emit the KEYCLOAK_EXTERNAL_URL diagnostic once, not per request
#1682 chore(ruff): enforce F821 (undefined name) instead of ignoring it
#1681 chore(deps): weekly lockfile update (2026-08-24)
#1680 chore(deps): bump the actions group in /.github/workflows with 4 updates
#1679 fix(nginx): serve ROOT_PATH-prefixed static assets and favicon in path mode
#1676 fix(1532): keep empty inputSchema arrays as [] (lua fix + OpenResty cjson runtime)
#1675 feat(egress): application-layer encryption for per-user egress credentials
#1674 docs: add resource links to the executive brief
#1673 docs+hardening: metadata field projection follow-up (#1277)
#1672 fix(lua): fail-closed caller-identity headers on virtual server path (follow-up to #1627)
#1670 fix(nginx): remove duplicate absolute_redirect directive (breaks nginx -t)
#1669 test(nginx): cover absolute_redirect off in front-door server blocks
#1659 fix(auth): filter tools/list against the normalized server name
#1658 fix(servers): reject a half-filled provider pair with 400 instead of 500
#1657 fix(keycloak): pass KEYCLOAK_EXTERNAL_URL to the prebuilt registry, warn when it cannot work
#1656 fix(keycloak): make the container healthcheck runnable inside the image
#1655 Egress destination binding + internal-only vend endpoint
#1654 fix: import missing annotation types flagged by ruff F821
#1645 fix(health): stream the MCP ping so a held-open response cannot stall the check
#1644 fix(nginx): add proxy_http_version 1.1 to /validate block + forward i…
#1641 chore(deps): weekly lockfile update (2026-08-17)
#1640 chore(deps): bump the actions group in /.github/workflows with 3 updates
#1639 chore(deps): bump python from 3.14.6-slim to 3.14.7-slim in /docker in the docker-images group across 1 directory
#1638 docs(egress): how to choose custom_token_auth_style + Datadog MCP public-client FAQ
#1637 feat: optional metadata-field projection for search and list APIs
#1636 fix(lambda): package patched urllib3 via build step so the #1612 pin remediates the CVEs
#1635 fix: relative nginx redirects on :8080 and :8443 to prevent internal URL leak (adopts #1610)
#1634 Fix virtual tools/list endpoint resolution and partial caching (adopts #1526)
#1633 docs: add Cognito and PingFederate identity-brokering examples + login sequence diagram
#1629 docs(idp): add Keycloak identity brokering guide for multi-tenant federation
#1628 Gateway proxy for any registry resource - foundation (PR 1 of 1565)
#1627 fix(nginx,lua): forward caller identity headers in virtual server backend locations
#1620 fix(nginx): send relative redirects from the front-door server blocks (#1606)
#1619 fix(cli): forward append_mcp_path from register --config (#1603)
#1614 fix(health): stream MCP initialize instead of buffering the full response
#1613 feat(egress): support public OAuth clients (token_endpoint_auth_method=none) with PKCE
#1612 fix: update Lambda dependencies for urllib3 vulnerabilities
#1605 docs: add Salesforce Headless 360 to the third-party MCP server guide
#1596 fix(a2a): accept percent-encoded ARNs so AgentCore agents are routable

Security Dependency Updates

Package Previous Updated Scope
urllib3 <2.7.0 >=2.7.0 terraform/aws-ecs/lambda/rotate-documentdb, rotate-rds (#1612, #1636)
python (base image) 3.14.6-slim 3.14.7-slim all Docker images (#1639)
GitHub Actions see PRs see PRs CI workflow action groups (#1640, #1680, #1708, #1726)
Python and frontend lockfiles see PRs see PRs weekly automated refresh (#1641, #1681, #1710, #1727)

Contributors

Thank you to all contributors for this release:


Support


Full Changelog: 1.29.0...1.30.0

What's Changed

  • chore: update image tags to 1.29.0 by @github-actions[bot] in #1632
  • docs(idp): add Keycloak identity brokering guide for multi-tenant federation by @omrishiv in #1629
  • docs: add Cognito and PingFederate identity-brokering examples + login sequence diagram by @aarora79 in #1633
  • Fix virtual tools/list endpoint resolution and partial caching (adopts #1526) by @aarora79 in #1634
  • fix(a2a): accept percent-encoded ARNs so AgentCore agents are routable by @billtarr-aws in #1596
  • docs: add Salesforce Headless 360 to the third-party MCP server guide by @billtarr-aws in #1605
  • fix: relative nginx redirects on :8080 and :8443 to prevent internal URL leak (adopts #1610) by @aarora79 in #1635
  • fix: update Lambda dependencies for urllib3 vulnerabilities by @doppelc in #1612
  • fix(lambda): package patched urllib3 via build step so the #1612 pin remediates the CVEs by @aarora79 in #1636
  • feat(egress): support public OAuth clients (token_endpoint_auth_method=none) with PKCE by @doppelc in #1613
  • docs(egress): how to choose custom_token_auth_style + Datadog MCP public-client FAQ by @aarora79 in #1638
  • chore(deps): bump the actions group in /.github/workflows with 3 updates by @dependabot[bot] in #1640
  • chore(deps): weekly lockfile update (2026-08-17) by @github-actions[bot] in #1641
  • chore(deps): bump python from 3.14.6-slim to 3.14.7-slim in /docker in the docker-images group across 1 directory by @dependabot[bot] in #1639
  • fix(health): stream MCP initialize instead of buffering the full response by @AmirF194 in #1614
  • fix(health): stream the MCP ping so a held-open response cannot stall the check by @aarora79 in #1645
  • fix(cli): forward append_mcp_path from register --config (#1603) by @rahul188 in #1619
  • fix(nginx): send relative redirects from the front-door server blocks (#1606) by @rahul188 in #1620
  • test(nginx): cover absolute_redirect off in front-door server blocks by @aarora79 in #1669
  • fix(nginx): remove duplicate absolute_redirect directive (breaks nginx -t) by @aarora79 in #1670
  • fix(nginx,lua): forward caller identity headers in virtual server backend locations by @doncouture in #1627
  • fix(lua): fail-closed caller-identity headers on virtual server path (follow-up to #1627) by @aarora79 in #1672
  • feat: optional metadata-field projection for search and list APIs by @cj-taylor in #1637
  • docs+hardening: metadata field projection follow-up (#1277) by @aarora79 in #1673
  • fix(nginx): add proxy_http_version 1.1 to /validate block + forward i… by @doncouture in #1644
  • docs: add resource links to the executive brief by @aarora79 in #1674
  • fix(1532): keep empty inputSchema arrays as [] (lua fix + OpenResty cjson runtime) by @aarora79 in #1676
  • fix: import missing annotation types flagged by ruff F821 by @harshadkhetpal in #1654
  • chore(ruff): enforce F821 (undefined name) instead of ignoring it by @aarora79 in #1682
  • fix(keycloak): make the container healthcheck runnable inside the image by @Evolver-sweden in #1656
  • chore(deps): bump the actions group in /.github/workflows with 4 updates by @dependabot[bot] in #1680
  • chore(deps): weekly lockfile update (2026-08-24) by @github-actions[bot] in #1681
  • fix(keycloak): pass KEYCLOAK_EXTERNAL_URL to the prebuilt registry, warn when it cannot work by @Evolver-sweden in #1657
  • fix(ecs): grant registry exec role read on embeddings-idp-secret by @aarora79 in #1684
  • fix(keycloak): emit the KEYCLOAK_EXTERNAL_URL diagnostic once, not per request by @aarora79 in #1683
  • fix(servers): reject a half-filled provider pair with 400 instead of 500 by @Evolver-sweden in #1658
  • fix(auth): filter tools/list against the normalized server name by @Evolver-sweden in #1659
  • fix(nginx): serve ROOT_PATH-prefixed static assets and favicon in path mode by @AmirF194 in #1679
  • Gateway proxy for any registry resource - foundation (PR 1 of 1565) by @omrishiv in #1628
  • docs(slides): refresh presentation PDF with restructured registry-first deck by @aarora79 in #1690
  • Egress destination binding + internal-only vend endpoint by @omrishiv in #1655
  • feat(egress): application-layer encryption for per-user egress credentials by @omrishiv in #1675
  • feat(observability): nudge operators about recommended-but-optional config by @aarora79 in #1694
  • fix(gateway-proxy): strip internal headers on generic hop, close prefix-match, document config by @aarora79 in #1698
  • Gateway proxy for any registry resource - deployment (PR 2 of 1565) by @omrishiv in #1691
  • docs: Fix duplicate header in debug SKILL.md by @br3cc in #1705
  • chore(deps): bump the actions group in /.github/workflows with 3 updates by @dependabot[bot] in #1708
  • chore(deps): weekly lockfile update (2026-08-31) by @github-actions[bot] in #1710
  • fix(auth): strip ingress proxy-context headers on the egress hop by @AmirF194 in #1685
  • fix(keycloak): rewrite every internal URL in the discovery document by @Evolver-sweden in #1688
  • Remove /api/internal/* from the public listeners by @omrishiv in #1697
  • fix(security): fail closed when failed-scan auto-disable cannot disable a server by @aarora79 in #1712
  • feat(gateway-proxy): scope-editor support, entity-form toggles, and auto-derived client URLs by @omrishiv in #1701
  • feat(url-guard): allow operator-named trusted IdP hosts for egress OAuth token endpoints by @go-faustino in #1707
  • feat(egress): propagate EGRESS_OAUTH_TRUSTED_IDP_HOSTS to the auth-server by @omrishiv in #1717
  • feat(gateway-proxy): generic-proxy extensions — streaming, static upstream auth headers, caller passthrough by @omrishiv in #1714
  • fix(terraform): remove ">" from the auth-server SG rule description by @aarora79 in #1728
  • fix(gateway-proxy): centralize the Authorization carve-out so registration and the storage decrypt cannot disagree by @aarora79 in #1729
  • chore(deps): bump the actions group in /.github/workflows with 3 updates by @dependabot[bot] in #1726
  • chore(deps): weekly lockfile update (2026-09-07) by @github-actions[bot] in #1727
  • test(gateway-proxy): operator test clients, preflight gate, and regression suite by @aarora79 in #1730
  • feat(gateway-proxy): connect affordance, operator notes, and a CLI create path by @aarora79 in #1731
  • fix(scopes): grant registry-admins HTTP verbs on gateway-proxied entities by @aarora79 in #1732
  • fix(a2a): build the agent-card route from the URL origin, not the JSON-RPC endpoint by @aarora79 in #1734
  • docs(gateway-proxy): add the operational guide, and fix a log string nothing emitted by @aarora79 in #1733
  • feat(metrics): classify gateway-proxy routes and put the authz key in the server label by @aarora79 in #1736
  • feat(metrics): record the gateway hop's own outcome, not just the authz decision by @aarora79 in #1737
  • docs(faq): registering OpenAI/Bedrock endpoints, and what the gateway proxy changes on upgrade by @aarora79 in #1738
  • docs(readme): position the gateway as an AI gateway for inference, MCP, A2A, and REST by @aarora79 in #1739
  • fix(skills): detect redirects from history, not the pinned-IP URL by @aarora79 in #1741
  • docs: 1.30.0 release notes by @aarora79 in #1742

New Contributors

Full Changelog: 1.29.0...1.30.0