# Release 1.24.1 - Auth Hardening, Cookie-Size Fix, and Operations Runbooks

**May 2026**

---

## Upgrading from 1.24.0

This release ships the server-side OAuth session store (#971) bundled with related auth fixes, plus a glibc CVE remediation, telemetry schema v4, an nginx race fix, build-system fixes, and the first three operations runbooks. **It contains breaking changes for Docker Compose, Terraform, and Helm deployments** (Helm changes are subchart-rebuild only; Docker/Terraform changes require operator action).

### Breaking Changes

#### 1. Helm subchart rebuild required

Seven files changed under `charts/` between 1.24.0 and 1.24.1 (auth-server reserved env names, secret template, multiple `values.yaml`, oauth-provider secret template). The packaged `.tgz` files inside `charts/mcp-gateway-registry-stack/charts/` are gitignored and only repackage when consumers run `helm dependency build` / `helm dependency update`.

**Action required:** Stack-chart consumers must run `helm dependency build` and `helm dependency update` before `helm upgrade`. A plain `git pull` followed by `helm upgrade` will use the *old* packaged subcharts and silently miss these changes. The exact commands are in the Helm upgrade section below.

#### 2. All currently-active users will be force-logged-out on rollout

The new server-side session store rejects pre-rollout dict-payload session cookies and redirects to `/login`. The cookie format is incompatible across the upgrade boundary; existing cookies do not resolve to records in the new collection.

**Action required:** Annoying once; clean forever. Plan the upgrade for a low-traffic window or notify users in advance.

The new `oauth_sessions_<documentdb_namespace>` collection is created automatically on the first session write after the upgrade, with a TTL index on `expires_at` and a unique index on `session_id`.

#### 3. `SECRET_KEY` is now required for Docker Compose and Terraform deployments

The previous per-replica `secrets.token_hex(32)` fallback has been removed because it caused intermittent `BadSignature` errors across replicas (replica A signed a cookie, replica B couldn't verify it). Auth-server and registry containers now refuse to start if `SECRET_KEY` is unset, with a clear shell-error message in `docker logs` / `kubectl logs`.

**Action required for Docker / Terraform operators before upgrading:**

```bash
# Generate a strong key:
python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
```

Set the value identically across all auth_server and registry replicas (Docker `.env`, Terraform `secret_key` variable / Secrets Manager).

**Helm chart users are unaffected by this specific breaking change** — the chart auto-generates `global.secretKey` at install time if unset, so no operator-supplied `SECRET_KEY` is required. (Helm users still need to action breaking change #1 above for the subchart rebuild.)

#### 4. `OAUTH_STORE_TOKENS_IN_SESSION` is removed

The variable's purpose (keep `id_token` out of cookies) is now the default-and-only behavior with the server-side store. Setting the variable now has no effect.

**Action required:** Remove `OAUTH_STORE_TOKENS_IN_SESSION` from your `.env` files, Helm values, Terraform `.tfvars`, and any compose `extra_env/*.env` files. If left in place it is silently ignored, but in deployments that validate `extra_env` against the chart's reserved-env-names list it will trigger an "unknown variable" warning.

### New Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `ENTRA_GRAPH_BASE_URL` | empty (auto-inferred from `ENTRA_LOGIN_BASE_URL`) | Optional Microsoft Graph base URL override. Leave unset on standard Entra deployments — auto-inferred from the login URL via the documented sovereign-cloud mapping. Set explicitly only for proxied or air-gapped deployments where the Graph endpoint is fronted by a proxy. |

### Upgrade Instructions

#### Docker Compose

```bash
cd mcp-gateway-registry
git pull origin main
git checkout 1.24.1

# REQUIRED: set SECRET_KEY before upgrading
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')" >> .env

# Remove OAUTH_STORE_TOKENS_IN_SESSION from your .env if present.
# Optionally add ENTRA_GRAPH_BASE_URL if you run a proxied or
# air-gapped Entra deployment.

# Rebuild and restart:
./build_and_run.sh
```

#### Kubernetes / Helm (EKS)

**REQUIRED:** Rebuild subchart dependencies. Seven files changed under `charts/` in this release; without rebuilding the dependency `.tgz` files, your `helm upgrade` will silently use stale subcharts.

```bash
cd mcp-gateway-registry
git pull origin main
git checkout 1.24.1

# REQUIRED: Rebuild dependencies so the packaged subchart .tgz files
# inside charts/mcp-gateway-registry-stack/charts/ pick up the
# auth-server / mcpgw / registry / stack template and values changes.
cd charts/mcp-gateway-registry-stack
helm dependency build
helm dependency update

# Update values.yaml: remove any OAUTH_STORE_TOKENS_IN_SESSION entries.
# Optionally set entraGraphBaseUrl for proxied / air-gapped deployments.
# global.secretKey is auto-generated if unset; no action required here.

helm upgrade mcp-gateway . -f your-values.yaml
```

#### Terraform / AWS ECS

```bash
cd mcp-gateway-registry
git pull origin main
git checkout 1.24.1

# REQUIRED: set secret_key in terraform.tfvars or via env var
export TF_VAR_secret_key=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')

# Update your .tfvars: remove any oauth_store_tokens_in_session entries.
# Optionally add entra_graph_base_url for proxied / air-gapped deployments.

cd terraform/aws-ecs
terraform plan
terraform apply
```

#### DockerHub Images

Pre-built images are available:

```bash
docker pull mcpgateway/registry:1.24.1
docker pull mcpgateway/auth-server:1.24.1
docker pull mcpgateway/currenttime-server:1.24.1
docker pull mcpgateway/realserverfaketools-server:1.24.1
docker pull mcpgateway/fininfo-server:1.24.1
docker pull mcpgateway/mcpgw-server:1.24.1
docker pull mcpgateway/metrics-service:1.24.1
```

---

## Major Features

### Server-side OAuth session store

Moves the OAuth session payload (username, groups, encrypted `id_token`) out of the browser cookie and into a new MongoDB / DocumentDB collection. Eliminates the cookie-size bug class that broke login for Entra ID users with large group memberships.

Key capabilities:

- New `oauth_sessions_<documentdb_namespace>` collection with TTL on `expires_at` (auto-creation on first session write; no migration step required) and a unique index on `session_id`.
- `id_token` is encrypted at rest with AES-GCM under a 32-byte key derived from `SECRET_KEY` via HKDF-SHA256, with a random 96-bit nonce per record.
- Logout deletes the server-side record before clearing the cookie, closing the cookie-replay window.
- Cookie now carries only an opaque, signed `session_id` — small, fixed-size, immune to group-overage bloat.
- Entra group-overage support: when an Entra ID token signals overage (`hasgroups: true` or `_claim_names.groups`), auth-server falls back to Microsoft Graph `/me/memberOf` and pages the result, capped at 1000 group IDs. Sovereign-cloud aware via the new `ENTRA_GRAPH_BASE_URL` override.
- Unified admin / scope derivation: both the cookie-based (`enhanced_auth`) and header-based (`nginx_proxied_auth`) auth paths now call into the same `_derive_user_context` function. Same input, same output, no scope-heuristic synthesis.

[PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042), [PR #1055](https://github.com/agentic-community/mcp-gateway-registry/pull/1055) (follow-up: parameter surface, observability, defensive cleanup)

### Operations runbooks

Establishes a `docs/operations/` namespace with three new runbooks for on-call use, plus an updated incident-response runbook. Each runbook is self-contained and copy-pasteable, with a procedure block, verification commands per step, and links into the underlying code.

- `mongodb-export-import.md` — `mongoexport` / `mongoimport` for JSONL exports; `mongodump` / `mongorestore` for full-fidelity BSON backups; tenant-scoped operations.
- `audit-log-export.md` — query and export `audit_events_*` for compliance review and security investigations. Two paths: REST API and direct MongoDB.
- `rotate-secrets.md` — rotation procedures for `SECRET_KEY`, federation static tokens, IdP client secrets, M2M client secrets. Documents what each rotation invalidates and the rollout sequence.

DRAFT notices flag any section that wasn't fully validated end-to-end, and an environment-portability note clarifies that the docker-compose examples are directional only on EKS / ECS deployments.

[PR #1068](https://github.com/agentic-community/mcp-gateway-registry/pull/1068)

---

## What's New

### Security

- Remediate CVE-2026-4438 (glibc) by adding `apt-get upgrade -y` to all eight Dockerfiles built on `python:3.14-slim`. Pulls in the patched `2.41-12+deb13u3` libc6 instead of the vulnerable `2.41-12+deb13u2` baked into the upstream base image. ([#1062](https://github.com/agentic-community/mcp-gateway-registry/pull/1062))
- Strict `SECRET_KEY` enforcement: auth-server and registry refuse to start if `SECRET_KEY` is unset. Replaces the previous per-replica random fallback that silently caused cross-replica `BadSignature` failures. ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042))
- nginx config regeneration is now serialized with a per-process lock and uses atomic temp-file writes. Eliminates a race that could produce corrupt nginx configs on concurrent registration / removal. ([#1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052))

### Authentication

- Server-side session store (see Major Features above) ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042), [#1055](https://github.com/agentic-community/mcp-gateway-registry/pull/1055)).
- Fixed inconsistent admin authorization between proxied auth and `enhanced_auth` paths via unified `_derive_user_context` ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042)).
- Fixed Entra login creating sessions without groups when the ID token omits inline group claims; Graph `/me/memberOf` paging fallback ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042)).

### Build & Deploy

- Regenerate all eight `uv.lock` files and pin `uv==0.11.14` in seven Dockerfiles. Fixes a clean-build failure in `uv sync --locked` caused by `uv 0.11.x` orphaning the `[options].exclude-newer` field on read. ([#1065](https://github.com/agentic-community/mcp-gateway-registry/pull/1065))
- Pass `BUILD_VERSION` as an explicit build-arg to `docker compose build`. The registry now reports its actual git tag instead of the legacy `1.0.0` fallback after `build_and_run.sh`. ([#1058](https://github.com/agentic-community/mcp-gateway-registry/pull/1058))
- New `make uv-update-locks` target refreshes every `uv.lock` in the repo with a configurable supply-chain quarantine window via `UV_EXCLUDE_NEWER`. (Note: see [#1047](https://github.com/agentic-community/mcp-gateway-registry/issues/1047) for current `uv 0.11.x` orphan-field caveat — the target is wired up but the current `uv` line undermines its lockfile-anchor mechanism.) ([#1039](https://github.com/agentic-community/mcp-gateway-registry/pull/1039))

### Telemetry

- Heartbeat schema v4 adds deployment-shape fields (mode, registry mode, replica count, MongoDB backend) and usage-report retention metrics. Fixes mis-bucketing of long-lived instances in usage analytics. ([#1060](https://github.com/agentic-community/mcp-gateway-registry/pull/1060))

### MCP Proxy

- Fixed `auth_server` forcing `application/json` on upstream MCP responses, which broke SSE clients. Server-Sent Events now pass through correctly. ([#1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052))

### Frontend / API

- Fixed `Server.health_status` Pydantic enum rejecting backend values like `local`, `checking`, and granular `unhealthy: <reason>` strings. The CLI's `list` command no longer crashes when servers are in those states; the UI now renders `local` distinctly instead of collapsing to "unknown". ([#1067](https://github.com/agentic-community/mcp-gateway-registry/pull/1067))
- JSON Upload UI now reads `deployment` and `local_runtime` fields from uploaded configs. ([#1049](https://github.com/agentic-community/mcp-gateway-registry/pull/1049))

### CI / Testing

- Registry test suite now runs against a MongoDB service container in CI. Eliminates the 20-second-per-test connection timeout that was happening in the absence of a real database. ([#1054](https://github.com/agentic-community/mcp-gateway-registry/pull/1054))

### Documentation

- New `docs/operations/` runbook namespace (see Major Features above) ([#1068](https://github.com/agentic-community/mcp-gateway-registry/pull/1068)).
- Corrected 1.24.0 release notes Helm upgrade instructions.

---

## Bug Fixes

- Fixed oversized OAuth session cookie breaking login for Entra users with large group memberships ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042)).
- Fixed `OAUTH_STORE_TOKENS_IN_SESSION=false` still storing `id_token` in the session cookie ([#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042)).
- Fixed nginx config-regeneration race producing corrupt configs ([#1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052)).
- Fixed auth-server forcing `application/json` and breaking MCP SSE clients ([#1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052)).
- Fixed registry reporting version `1.0.0` after `build_and_run.sh` ([#1058](https://github.com/agentic-community/mcp-gateway-registry/pull/1058)).
- Fixed heartbeat events lacking deployment-shape fields, mis-bucketing long-lived instances ([#1060](https://github.com/agentic-community/mcp-gateway-registry/pull/1060)).
- Fixed clean-build failure in `uv sync --locked` ([#1065](https://github.com/agentic-community/mcp-gateway-registry/pull/1065)).
- Fixed `Server.health_status` enum mismatch crashing the CLI list command ([#1067](https://github.com/agentic-community/mcp-gateway-registry/pull/1067)).
- Fixed JSON Upload ignoring `deployment` and `local_runtime` fields in the UI ([#1049](https://github.com/agentic-community/mcp-gateway-registry/pull/1049)).
- Fixed registry-test workflow timing out 20s per test on MongoDB connection ([#1054](https://github.com/agentic-community/mcp-gateway-registry/pull/1054)).

---

## Security Notes

- The OAuth `id_token` is now stored in the database, encrypted with AES-GCM using a key derived from `SECRET_KEY` via HKDF-SHA256. Read access to the `oauth_sessions_*` collection is equivalent to credential compromise unless `SECRET_KEY` is high-entropy (32+ bytes from a CSPRNG) and never written to a logged location.
- Logout deletes the server-side record before clearing the cookie, closing the cookie-replay window after logout.
- Suspected credential leak: an operator can invalidate every active session immediately by dropping the `oauth_sessions_<namespace>` collection. See [`docs/operations/incident-response.md`](https://github.com/agentic-community/mcp-gateway-registry/blob/main/docs/operations/incident-response.md).
- For coordinated rotation of `SECRET_KEY`, federation tokens, and IdP client secrets, see [`docs/operations/rotate-secrets.md`](https://github.com/agentic-community/mcp-gateway-registry/blob/main/docs/operations/rotate-secrets.md) (DRAFT — destructive steps not exercised in validation; dry-run in non-prod first).

---

## Closed Issues

| Issue | Title | Closed By |
|-------|-------|-----------|
| #1066 | Client HealthStatus enum out of sync with backend (rejects 'local', 'checking', granular unhealthy reasons) | [PR #1067](https://github.com/agentic-community/mcp-gateway-registry/pull/1067) |
| #1064 | Regenerate uv.lock files: refresh exclude-newer anchor and pin uv in Dockerfiles | [PR #1065](https://github.com/agentic-community/mcp-gateway-registry/pull/1065) |
| #1061 | Remediate CVE-2026-4438 (glibc) in container base images | [PR #1062](https://github.com/agentic-community/mcp-gateway-registry/pull/1062) |
| #1059 | Heartbeat events lack deployment-shape fields, mis-bucketing long-lived instances in usage analytics | [PR #1060](https://github.com/agentic-community/mcp-gateway-registry/pull/1060) |
| #1057 | fix(build): registry reports version 1.0.0 instead of git tag after build_and_run.sh | [PR #1058](https://github.com/agentic-community/mcp-gateway-registry/pull/1058) |
| #1056 | docs(operations): expand operational runbooks under docs/operations/ | [PR #1068](https://github.com/agentic-community/mcp-gateway-registry/pull/1068) (partial; remainder tracked in [#1069](https://github.com/agentic-community/mcp-gateway-registry/issues/1069)) |
| #1053 | ci: Registry Test Suite times out 20s per test on MongoDB connection | [PR #1054](https://github.com/agentic-community/mcp-gateway-registry/pull/1054) |
| #1051 | fix(mcp-proxy): auth_server forces application/json on upstream MCP responses, breaking SSE clients | [PR #1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052) |
| #1050 | fix(ui): JSON Upload ignores deployment and local_runtime fields | [PR #1049](https://github.com/agentic-community/mcp-gateway-registry/pull/1049) |
| #1044 | Serialize nginx config regeneration to prevent race conditions and corrupt config writes | [PR #1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052) |
| #971 | Oversized OAuth session cookie breaks login for Entra users with large group memberships | [PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) |
| #933 | Bug: inconsistent admin authorization between proxied auth and session-cookie `enhanced_auth` paths | [PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) |
| #929 | Entra login can create sessions without groups when ID token omits inline group claims | [PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) |
| #915 | OAUTH_STORE_TOKENS_IN_SESSION=false still stores id_token in OAuth session cookie | [PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) |
| #399 | Implement server-side token storage to resolve session cookie size limit | [PR #1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) |

---

## Pull Requests Included

| PR | Title |
|----|-------|
| [#1068](https://github.com/agentic-community/mcp-gateway-registry/pull/1068) | docs(operations): add mongodb-export-import, audit-log-export, rotate-secrets runbooks |
| [#1067](https://github.com/agentic-community/mcp-gateway-registry/pull/1067) | fix(api): loosen Server.health_status to str + expand list emoji map |
| [#1065](https://github.com/agentic-community/mcp-gateway-registry/pull/1065) | fix(build): regenerate uv.lock files and pin uv to 0.11.14 in Dockerfiles |
| [#1062](https://github.com/agentic-community/mcp-gateway-registry/pull/1062) | fix(security): remediate CVE-2026-4438 (glibc) in container base images |
| [#1060](https://github.com/agentic-community/mcp-gateway-registry/pull/1060) | fix(telemetry): heartbeat schema v4 with deployment-shape fields + usage-report retention metrics |
| [#1058](https://github.com/agentic-community/mcp-gateway-registry/pull/1058) | fix(build): pass BUILD_VERSION as explicit build-arg to docker compose build |
| [#1055](https://github.com/agentic-community/mcp-gateway-registry/pull/1055) | follow-up to #1042: parameter surface, observability, defensive cleanup |
| [#1054](https://github.com/agentic-community/mcp-gateway-registry/pull/1054) | ci: add MongoDB service container to registry test workflow |
| [#1052](https://github.com/agentic-community/mcp-gateway-registry/pull/1052) | fix(nginx): serialize config regeneration + atomic writes; fix MCP proxy SSE passthrough |
| [#1049](https://github.com/agentic-community/mcp-gateway-registry/pull/1049) | fix(ui): JSON Upload now reads deployment and local_runtime |
| [#1048](https://github.com/agentic-community/mcp-gateway-registry/pull/1048) | chore: update Helm chart image tags to 1.24.0 |
| [#1042](https://github.com/agentic-community/mcp-gateway-registry/pull/1042) | Fix oversized session cookie + bundle related auth fixes |
| [#1039](https://github.com/agentic-community/mcp-gateway-registry/pull/1039) | uv.lock update make target |

---

## Contributors

Thank you to all contributors for this release:

- **Amit Arora** ([@aarora79](https://github.com/aarora79))
- **omrishiv** ([@omrishiv](https://github.com/omrishiv))
- **Nandini Kodali** ([@NandiniKodali](https://github.com/NandiniKodali))

---

## Note: `agents/cli_user_auth.py` test utility

The local cookie-minting path in `agents/cli_user_auth.py` is incompatible with the new server-side session store and now raises `NotImplementedError`. **This does not impact any deployment** — the file is a test utility used only by the A2A agent example, not part of any customer-facing code path or supported flow. Calling it out here for completeness; no operator action is required. If you were using this path for local A2A agent development, switch to the auth-server's browser OAuth flow instead.

---

## Support

- [GitHub Issues](https://github.com/agentic-community/mcp-gateway-registry/issues)
- [GitHub Discussions](https://github.com/agentic-community/mcp-gateway-registry/discussions)
- [Documentation](https://github.com/agentic-community/mcp-gateway-registry/tree/main/docs)

---

**Full Changelog:** [1.24.0...1.24.1](https://github.com/agentic-community/mcp-gateway-registry/compare/1.24.0...1.24.1)
