github agentic-community/mcp-gateway-registry 1.26.0
1.26.0 - Egress Auth & Security Hardening

one hour ago

Release 1.26.0 - Egress Auth & Security Hardening

July 2026


Upgrading from 1.25.0

This section covers everything you need to know to upgrade from 1.25.0 to 1.26.0.

Breaking Changes

This release adds a preflight validator to build_and_run.sh that refuses to start the stack when secrets are left at known-weak defaults. This affects LOCAL Docker Compose deployments only (e.g. a local box, EC2, or macOS running build_and_run.sh). Managed deployments are NOT affected - AWS ECS/DocumentDB and EKS/Helm supply their own secrets and do not run this preflight.

If you are a local Docker Compose user upgrading an existing deployment, build_and_run.sh will now fail with:

ERROR: DOCUMENTDB_PASSWORD is set to the known-weak default 'admin'.
ERROR: OPENBAO_TOKEN is set to the known-weak default 'dev-root-token'.

You must set strong values in .env. The two secrets are handled differently:

  • OpenBao token (OPENBAO_TOKEN) - the dev OpenBao container runs in-memory and is recreated on every restart, so there is no stored data to preserve. Just set a strong value (openssl rand -hex 32) in .env. Any previously vaulted egress credentials are re-established by reconnecting accounts after startup.
  • MongoDB password (DOCUMENTDB_PASSWORD) - your existing mongodb-data volume already holds a user created with the OLD password. MongoDB only creates that user on first boot, so changing .env alone does NOT update the stored user and will lock the app out of your existing data (registered servers/agents). You must rotate the stored user's password in place first, then set the same value in .env.

Full step-by-step instructions (including macOS sed variants, verification, and troubleshooting) are in the new FAQ:

  • How do I rotate my MongoDB password and OpenBao token? (local Docker Compose, EC2/macOS)

If you do not need to preserve local data, you can instead recreate the MongoDB volume - see How do I migrate an existing local MongoDB to authenticated mode?.

Related hardening in this release that local Docker Compose users should be aware of:

  • MongoDB now runs with authentication by default in docker-compose.yml (--auth + a keyfile-init helper). Fresh installs create the root user from DOCUMENTDB_USERNAME/DOCUMENTDB_PASSWORD on first boot; build_and_run.sh auto-generates a strong DOCUMENTDB_PASSWORD when it is unset (#1386).
  • Non-front-door Compose ports are now loopback-bound (127.0.0.1) by default; only the nginx front door (80/443) is published on all interfaces. Override with HOST_BIND_IP=0.0.0.0 if you deliberately need LAN access (#1376).
  • Keycloak realm setup uses sslRequired=external (not none). The orphaned disable-ssl.sh was removed and the setup guides were corrected (#1380, #1384).

Breaking changes for Helm / EKS

The weak-secret preflight does not run on EKS, but there are two required upgrade actions:

  • New openbao subchart dependency. The stack chart (charts/mcp-gateway-registry-stack/Chart.yaml) now declares an openbao dependency (condition: openbao.enabled) for the per-user egress credential vault. You must run helm dependency build / helm dependency update before helm upgrade (see Upgrade Instructions), or the packaged subcharts will be stale. Many other subchart templates/values also changed this release, so this is required regardless.
  • New required value egressAuth.markerSecret for standalone deployments. The chart now renders AUTH_SERVER_NGINX_MARKER_SECRET via {{ required ... }}, so a standalone install/upgrade fails to render unless egressAuth.markerSecret is set to a strong random value (identical across auth-server and registry). It guards all mcp-proxy token minting and is not egress-specific. Set it in your values before upgrading.

Breaking changes for Terraform / ECS

No mandatory new variables: the egress credential vault is off by default (egress_auth_enabled = false) and every new variable (cors_allowed_origins, mcp_proxy_timeout, the egress_* family) has a default. Two things to know:

  • If you enable the egress vault (egress_auth_enabled = true), ECS uses AWS Secrets Manager as the backend and the registry task role is granted scoped secretsmanager + KMS access under egress_secrets_manager_path_prefix. Set the egress_* variables accordingly (see terraform/aws-ecs/terraform.tfvars.example).
  • egress_nginx_marker_secret is auto-generated into Secrets Manager when left empty; set it only to pin a specific value. (ECS supplies this automatically, unlike the Helm standalone path which requires it explicitly.)

New Environment Variables

Variable Default Description
EGRESS_AUTH_ENABLED false Enable the per-user egress credential vault (third-party OBO).
SECRET_STORE_BACKEND openbao Secret store for per-user egress tokens: secrets-manager or openbao.
OPENBAO_ADDR http://openbao:8200 OpenBao backend address.
OPENBAO_TOKEN (required, no default) OpenBao token. The preflight rejects the old dev-root-token.
OPENBAO_NAMESPACE (empty) OpenBao namespace (enterprise/HCP).
OPENBAO_KV_MOUNT secret KV v2 mount path.
OPENBAO_AUTH_METHOD token OpenBao auth method (token for Compose; kubernetes for EKS).
OPENBAO_ROLE (empty) OpenBao role for kubernetes auth.
EGRESS_OAUTH_CALLBACK_BASE_URL (empty) Base URL for the egress OAuth callback.
EGRESS_TOKEN_REFRESH_SKEW_SECONDS 300 Refresh egress tokens this many seconds before expiry.
EGRESS_STATE_TTL_SECONDS 600 TTL for the egress OAuth state parameter.
SECRETS_MANAGER_PATH_PREFIX mcp/egress Path prefix for the AWS Secrets Manager backend.
SECRETS_MANAGER_KMS_KEY_ID (empty) Optional KMS key for the Secrets Manager backend.
AWS_SECRETS_REGION (empty) Region for the Secrets Manager backend (falls back to AWS_REGION).
CORS_ALLOWED_ORIGINS (empty) Exact allowlist of browser origins for credentialed CORS (fail-closed).
MCP_PROXY_TIMEOUT 30 Upstream read timeout (seconds) for the MCP proxy hop; supports long-running tool calls.
AUTH_SERVER_NGINX_MARKER_SECRET (auto-generated) Shared marker secret guarding mcp-proxy token minting; build_and_run.sh generates it if empty.
DOCUMENTDB_PASSWORD (required, no default) MongoDB/DocumentDB password. The preflight rejects admin; build_and_run.sh generates a strong value when unset.
SECRET_KEY (auto-generated) Session-signing key; enforced minimum length. build_and_run.sh generates it if empty.
PF_ADMIN_PASS (placeholder) PingFederate admin password; the shipped placeholder is rejected.

Upgrade Instructions

Docker Compose

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

# REQUIRED (local Docker Compose upgrades): set strong secrets before starting.
# OpenBao is in-memory (no data to preserve): set a strong OPENBAO_TOKEN in .env.
# MongoDB: rotate the stored password IN PLACE, then set it in .env -- otherwise
# you lose access to your existing data. Full steps:
#   docs/faq/rotate-mongodb-and-openbao-secrets.md

# Review new env vars in .env.example and update your .env, then:
./build_and_run.sh

Kubernetes / Helm (EKS)

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

# REQUIRED: chart files changed in this release, so rebuild packaged subcharts.
cd charts/mcp-gateway-registry-stack
helm dependency build
helm dependency update

# Update values.yaml (new egress-vault / OpenBao settings) then upgrade:
helm upgrade mcp-gateway . -f your-values.yaml

The weak-secret preflight is a build_and_run.sh check and does not run on EKS. Helm/EKS deployments supply DOCUMENTDB_PASSWORD and the OpenBao/vault configuration through their own values/secrets.

Terraform / ECS

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

# Update your .tfvars with any new variables (egress vault / Secrets Manager)
cd terraform/aws-ecs
terraform plan
terraform apply

ECS uses AWS DocumentDB (authenticated + TLS by the managed service) and AWS Secrets Manager, so the local weak-secret preflight and MongoDB password rotation do not apply.

Pre-built Images (Amazon ECR Public)

The three gateway service images are published to Amazon ECR Public and pulled by the prebuilt Compose path (./build_and_run.sh --prebuilt). Override the namespace with ECR_REGISTRY if you mirror them elsewhere.

docker pull public.ecr.aws/p3v1o3c6/registry:1.26.0
docker pull public.ecr.aws/p3v1o3c6/auth-server:1.26.0
docker pull public.ecr.aws/p3v1o3c6/mcpgw:1.26.0

The example MCP servers (currenttime, realserverfaketools) and the metrics service are built locally by build_and_run.sh and are not published as release images.


Major Features

Per-user egress credential vault (third-party OBO)

The gateway can now broker per-user, third-party credentials for egress to external MCP servers, so an authenticated user's connection to a downstream SaaS (e.g. Slack, Atlassian, GitHub) uses that user's own OAuth token rather than a shared credential. Tokens are held in a secret store - OpenBao (a dev-mode container ships with Docker Compose; a sealed, file-backed standalone OpenBao ships with Helm) or AWS Secrets Manager - and refreshed ahead of expiry. Off by default (EGRESS_AUTH_ENABLED=false).

PR #1312, PR #1305, PR #1349

Configurable MCP proxy timeout

The MCP proxy hop's upstream timeout was hardcoded to 30s, causing long-running tool calls to fail with 504. It is now a first-class parameter, MCP_PROXY_TIMEOUT, wired across all deployment surfaces (Compose, Helm, Terraform) and derived into nginx's proxy_read_timeout.

PR #1358, PR #1361, PR #1356

LLM tool-execution confirmation and A2A agent authentication

Agent tool execution is now gated behind an explicit confirmation step, and agent-to-agent (A2A) calls authenticate the calling agent, closing an unauthenticated-execution path.

PR #1392


What's New

Security Hardening

This release is a broad security-hardening pass across the auth, proxy, and data layers:

  • Enable MongoDB authentication by default in Docker Compose; drop the committed weak admin password (#1386)
  • Loopback-bind all non-front-door Compose ports by default (#1376)
  • Remove the orphaned disable-ssl.sh that weakened Keycloak TLS; keep sslRequired=external (#1380)
  • Remove weak default Keycloak credentials and stop forcing non-temporary passwords (#1381)
  • Remove the anonymous /.well-known/mcp-servers discovery endpoint (#1374)
  • Drop unused python-jose to remove CVE-bearing transitive dependencies (#1387)
  • Add access control to GET /servers/{path}/versions so it no longer leaks backend URLs (#1388)
  • Make peer federation tokens write-only in responses (#1389)
  • Separate internal service tokens from user tokens (#1359); MCP session-id hardening (#1357)
  • SSRF URL validation on registration and OAuth token calls (#1363, #1396)
  • CORS allowlist made fail-closed and credential-aware (#1364)
  • ID-token signature verification and secret-key length hardening (#1366, #1367)
  • Authorization/ownership checks tightened across management routes (#1365)
  • Enforce CSRF validation on IAM management and federation endpoints (#1390)
  • Stop relaying caller credentials to untrusted MCP/A2A upstreams (#1391); treat client auth headers as ingress-only and strip on egress (#1369)
  • Block script-scheme (javascript:/data:) URLs in dynamic frontend links (#1394)
  • MCP proxy body-integrity: re-authorize the exact forwarded body, fail closed on an uninspectable body (#1393)
  • Require a per-deployment secret for metrics API-key hashing and close a rate-limit oracle (#1399)
  • Restrict read-only info disclosure on management/search responses (#1397)
  • Harden Docker Compose stacks against insecure defaults, incl. a weak-secret denylist and preflight (#1400, #1368)
  • Raise dependency floors above known CVE fixes (incl. aiohttp), refresh all uv.lock files, and extend the python-jose guard to the root and all sub-project manifests/locks (#1401)
  • Federation credential hardening: validate peer endpoint URLs through the SSRF guard on create/update/sync and harden peer credential handling (#1398)
  • Log redaction and secret hygiene: redact secrets/tokens from logs across auth-server, providers, and CLI/discovery clients; keep freshly minted M2M secrets off stdout; write secret files with 0600 perms (#1405)

Deployment

  • Add an OpenBao dev-mode container to the Docker Compose stacks (#1349)
  • Pull prebuilt images from Amazon ECR Public instead of Docker Hub (#1352)

Documentation

  • New FAQ: rotate MongoDB password + OpenBao token for local Docker Compose (#1402)
  • Remove DockerHub publish steps from the release-notes skill (the project no longer publishes to DockerHub) (#1404)
  • Stop instructing sslRequired=none in the setup guides; external is correct (#1384)
  • Fix mermaid rendering in the auth and egress-vault docs (#1382, #1383, #1373, #1375)
  • Add a self-service lifecycle workflow demo video link

Bug Fixes

  • Repair the fresh-deploy path in docker-compose.podman.yml: mongo-init credentials, OAuth discovery env wiring, and realm-setup documentation (#1395)
  • Make the MCP proxy upstream timeout configurable to fix 504s on long-running tool calls (#1356)
  • Update TemplateResponse calls to the current Starlette signature (#1360)
  • Reduce authorization lookups and extend nginx header stripping (#1342)
  • Remove the invalid "file" storage backend from the terraform-setup skill docs (#1353)
  • Recurse into the FastAPI 0.138 included-router wrapper in the internal-route meta-test (#1347)

Closed Issues

Issue Title Closed By
#1379 docker-compose.podman.yml: mongodb-init default credentials don't match the no-auth mongodb-ce service #1395
#1378 docker-compose.podman.yml: KEYCLOAK_EXTERNAL_URL/MCP_HTTPS_REQUIRED not passed to containers; Keycloak has no host port mapping #1395
#1377 docker-compose.podman.yml: Keycloak realm import is silently broken #1395
#1320 MCP proxy hop upstream timeout is hardcoded to 30s (long-running tool calls fail with 504) #1356
#1266 Egress: ingress-token relay fix (relay-ingress + none) #1369

Pull Requests Included

PR Title
#1405 log redaction
#1404 docs(skill): remove DockerHub publish steps from release-notes skill
#1402 docs(faq): rotate MongoDB password + OpenBao token for local Docker Compose (EC2/macOS)
#1401 update dependencies (raise floors above CVE fixes; extend python-jose guard)
#1398 federation credential hardening
#1400 harden compose: case-insensitive weak-secret denylist; blank PF_ADMIN_PASS placeholder
#1399 fix(metrics-service): require per-deployment secret for API-key hashing; close rate-limit oracle
#1397 readonly info restriction
#1396 fix(egress): route OAuth token calls through the SSRF guard and escape callback HTML
#1395 fix(podman): repair fresh-deploy path in docker-compose.podman.yml
#1394 frontend xss hrefs
#1393 mcp proxy integrity
#1392 feat: gate LLM tool execution behind confirmation and authenticate A2A agents
#1391 fix: stop relaying caller credentials to untrusted MCP/A2A upstreams
#1390 fix: enforce CSRF validation on IAM management and federation endpoints
#1389 fix(security): make peer federation_token write-only in responses
#1388 fix(security): add access control to GET /servers/{path}/versions
#1387 fix(security): drop unused python-jose (removes CVE-bearing deps)
#1386 fix(security): enable MongoDB auth by default; drop weak admin password
#1384 docs: stop instructing sslRequired=none; external is correct
#1383 docs(egress-vault): fix mermaid render of placeholders
#1382 docs(auth): fix mermaid render of token placeholder
#1381 fix(security): remove weak Keycloak default credentials
#1380 fix(security): remove orphaned disable-ssl.sh that weakened Keycloak TLS
#1376 fix(security): loopback-bind non-front-door compose ports
#1375 docs(egress): make mermaid notes/messages parseable
#1374 security: remove /.well-known/mcp-servers anonymous discovery endpoint
#1373 docs(egress): fix mermaid render error from angle-bracket token placeholders
#1369 fix(egress): treat client auth headers as ingress-only, strip on egress
#1368 remove hardcoded placeholder secrets
#1367 secret key hardening
#1366 idtoken signature
#1365 authz and ownership
#1364 cors and cookies
#1363 ssrf url validation
#1361 feat(nginx): derive mcp-proxy proxy_read_timeout from MCP_PROXY_TIMEOUT
#1360 fix: update TemplateResponse calls to current Starlette signature
#1359 fix(security): separate internal service tokens from user tokens
#1358 feat(config): wire MCP_PROXY_TIMEOUT as a first-class param across all surfaces
#1357 (fix) mcp session id hardening
#1356 fix: make MCP proxy upstream timeout configurable
#1353 fix(terraform-setup): remove invalid "file" storage backend from skill docs
#1352 fix(compose): pull prebuilt images from ECR Public instead of Docker Hub
#1351 update python-jose dependency
#1350 docs(slides): update presentation PDF
#1349 feat(compose): add OpenBao dev-mode container to Docker Compose stacks
#1347 test(auth): recurse into FastAPI 0.138 included-router wrapper
#1344 build(deps): bump actions/checkout
#1342 fix: reduce authz lookups, extend nginx header stripping, reuse constants
#1312 Feat/egress auth
#1305 feat(helm): standalone OpenBao for per-user egress credential vault

Contributors

Thank you to all contributors for this release:


Support


Full Changelog: 1.25.0...1.26.0

What's Changed

  • chore: update image tags to 1.25.0 by @github-actions[bot] in #1338
  • build(deps): bump actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the actions group by @dependabot[bot] in #1344
  • test(auth): fix authserver test for FastAPI 0.138 by @omrishiv in #1347
  • chore(deps): weekly lockfile update (2026-06-29) by @github-actions[bot] in #1346
  • feat(helm): standalone OpenBao for per-user egress credential vault by @omrishiv in #1305
  • feat(compose): add OpenBao dev-mode container to Docker Compose stacks by @aarora79 in #1349
  • docs(slides): update presentation PDF by @aarora79 in #1350
  • fix(compose): pull prebuilt images from ECR Public instead of Docker Hub by @aarora79 in #1352
  • fix(terraform-setup): remove invalid "file" storage backend from skill docs by @aarora79 in #1353
  • Feat/egress auth by @omrishiv in #1312
  • (chore) update python-jose dependency by @omrishiv in #1351
  • (fix) mcp session id hardening by @omrishiv in #1357
  • fix: make MCP proxy upstream timeout configurable (#1320) by @zsxh1990 in #1356
  • feat(config): wire MCP_PROXY_TIMEOUT as a first-class param across all surfaces by @aarora79 in #1358
  • Separate internal service tokens from user tokens by @aarora79 in #1359
  • Fix TemplateResponse calls for current Starlette signature by @aarora79 in #1360
  • Derive mcp-proxy nginx proxy_read_timeout from MCP_PROXY_TIMEOUT by @aarora79 in #1361
  • fix: reduce authz lookups, extend nginx header stripping, reuse constants by @omrishiv in #1342
  • ssrf url validation by @omrishiv in #1363
  • authz and ownership by @omrishiv in #1365
  • cors and cookies by @omrishiv in #1364
  • idtoken signature by @omrishiv in #1366
  • secret key hardening by @omrishiv in #1367
  • remove hardcoded placeholder secrets by @omrishiv in #1368
  • reuse uv.lock for precommit tests by @omrishiv in #1371
  • (fix): checkov skip placement by @omrishiv in #1372
  • fix(egress): treat client auth headers as ingress-only, strip on egress (#1266) by @aarora79 in #1369
  • docs(egress): fix mermaid render error in egress-auth-design by @aarora79 in #1373
  • docs(egress): fix mermaid render (notes/messages with arrow syntax) by @aarora79 in #1375
  • security: remove anonymous /.well-known/mcp-servers discovery endpoint by @aarora79 in #1374
  • fix(security): loopback-bind non-front-door compose ports (SA-5) by @aarora79 in #1376
  • fix(security): remove orphaned disable-ssl.sh that weakened Keycloak TLS (SA-8) by @aarora79 in #1380
  • fix(security): remove weak Keycloak default credentials (SA-9) by @aarora79 in #1381
  • docs: stop instructing sslRequired=none; external is correct by @aarora79 in #1384
  • fix(security): enable MongoDB auth by default; drop weak admin password (SA-11) by @aarora79 in #1386
  • fix(security): drop unused python-jose to remove CVE-bearing deps (SA-13) by @aarora79 in #1387
  • fix(security): add access control to GET /servers/{path}/versions (SA-19) by @aarora79 in #1388
  • fix(security): make peer federation_token write-only in responses (SA-24) by @aarora79 in #1389
  • csrf protection by @omrishiv in #1390
  • close potential credential leak by @omrishiv in #1391
  • docs(egress-vault): fix mermaid render of placeholders by @zsxh1990 in #1383
  • docs(auth): fix mermaid render of token placeholder by @zsxh1990 in #1382
  • a2a example llm tool safety by @omrishiv in #1392
  • mcp proxy integrity by @omrishiv in #1393
  • frontend xss hrefs by @omrishiv in #1394
  • fix(podman): repair fresh-deploy path (realm setup, OAuth discovery, mongo-init) (#1377, #1378, #1379) by @aarora79 in #1395
  • route OAuth token calls through the SSRF guard by @omrishiv in #1396
  • readonly info restriction by @omrishiv in #1397
  • metrics key hardening by @omrishiv in #1399
  • compose hardening by @omrishiv in #1400
  • docs(faq): rotate MongoDB password + OpenBao token for local Docker Compose (EC2/macOS) by @aarora79 in #1402
  • update dependencies by @omrishiv in #1401
  • docs(skill): remove DockerHub publish steps from release-notes skill by @aarora79 in #1404
  • federation credential hardening by @omrishiv in #1398
  • chore: update image tags to 1.26.0 by @github-actions[bot] in #1403
  • log redaction by @omrishiv in #1405

New Contributors

Full Changelog: 1.25.0...1.26.0

Don't miss a new mcp-gateway-registry release

NewReleases is sending notifications on new releases.