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, orgeneric_proxy_custom. Anything filteringtarget_kind="unknown"stops matching it. - On those series,
serverholds the entity's authz key (for exampleskill/skills/pdf) instead of the literalgateway. successis lowercasetrue/falseon every exporter. A query writtensuccess="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_millisecondsno longer carriesserver. Group it bytarget_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.shKubernetes / 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.yamlTerraform / 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 applyMajor 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/skillsand their single-asset variants (query parameter), plusPOST /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-fieldsonlist,agent-list,skill-list, andserver-search;metadata_fieldson the client library'ssemantic_search()andlist_skills(). - Database-level projection: the server list path projects the subdocument inside MongoDB via an aggregation
$setstage 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
Authorizationcarve-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
:8080and:8443so 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/listagainst 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_URLto 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_redirectdirective that brokenginx -t(#1670) - Add
proxy_http_version 1.1to the/validateblock and forward the missing headers (#1644) - Forward caller-identity headers in virtual-server backend locations (#1627)
- Fix virtual
tools/listendpoint resolution and partial caching (#1634, adopts #1526) - Keep empty
inputSchemaarrays 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
initializeinstead 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_pathfromregister --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 offin 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
Authorizationcarve-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_URLdiagnostic once, not per request (#1683) - Serve
ROOT_PATH-prefixed static assets and favicon in path mode (#1679) - Keep empty
inputSchemaarrays as[](#1676) - Fail closed on caller-identity headers in the virtual-server path (#1672)
- Remove the duplicate
absolute_redirectdirective that breaksnginx -t(#1670) - Filter
tools/listagainst the normalized server name (#1659) - Reject a half-filled provider pair with 400 instead of 500 (#1658)
- Pass
KEYCLOAK_EXTERNAL_URLto 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.1to the/validateblock and forward headers (#1644) - Package patched urllib3 via a build step so the pin remediates (#1636)
- Use relative nginx redirects on
:8080and:8443to prevent internal URL leaks (#1635) - Fix virtual
tools/listendpoint 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_pathfromregister --config(#1619) - Stream MCP
initializeinstead 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:
- Amit Arora (@aarora79)
- omrishiv (@omrishiv)
- CJ Taylor (@cj-taylor)
- Evolver-sweden (@Evolver-sweden)
- Amir Fathi (@AmirF194)
- rahul188 (@rahul188)
- Gonçalo Faustino (@go-faustino)
- Don Couture (@doncouture)
- doppelc (@doppelc)
- Bill Tarr (@billtarr-aws)
- br3cc (@br3cc)
- Ehsan Barkhordar (@ebarkhordar)
- Harshad Khetpal (@everyinch360-sys)
- zsxh1990 (@zsxh1990)
- ssafari (@soheilkhan)
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
- @doppelc made their first contribution in #1612
- @AmirF194 made their first contribution in #1614
- @doncouture made their first contribution in #1627
- @cj-taylor made their first contribution in #1637
- @harshadkhetpal made their first contribution in #1654
- @Evolver-sweden made their first contribution in #1656
- @br3cc made their first contribution in #1705
Full Changelog: 1.29.0...1.30.0