Release 1.0.7 - #6039
Merged
Merged
Conversation
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
prakhar-singh1928
requested review from
Lang-Akshay,
brian-hussey,
crivetimihai,
ja8zyjits and
msureshkumar88
as code owners
August 4, 2026 14:51
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
prakhar-singh1928
marked this pull request as draft
August 4, 2026 15:18
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
prakhar-singh1928
marked this pull request as ready for review
August 4, 2026 15:35
Signed-off-by: Vishu Bhatnagar <vishu.bhatnagar@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
The uv run invocation of create_jwt_token imports mcpgateway.config at module level, triggering the full settings validator. DYNAMIC_ENC_SECRET from GITHUB_ENV is not automatically named AUTH_ENCRYPTION_SECRET — it must be explicitly mapped in each step's env: block that invokes Python. Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
fix(helm): set runAsUser so non-root containers can start
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
…ants Signed-off-by: Madhu Mohan Jaishankar <madhu.mohan.jaishankar@ibm.com>
migration-fix
fix: warn at startup when CSRF cookie or header names are overridden
Signed-off-by: Gabriel Costa <gabrielcg@proton.me>
…s_search fix(tests): re-check resources table before reading second row in view-modal test
Derive the set of settings fields excluded from a generated support
bundle from the Settings model itself instead of a hand-maintained list.
A hardcoded list goes stale as settings are added; deriving it means any
field declared with a secret type is covered without a second edit. A
narrow name-based rule acts as a backstop for string-typed fields, with
SecretStr typing remaining the enforced convention.
Type csrf_secret_key and identity_claims_secret as SecretStr. Their
fallback behaviour is unchanged: both still derive from JWT_SECRET_KEY
when left unset. Note that SecretStr("") is truthy, so the emptiness
checks guarding those fallbacks go through get_secret_value(), and the
assignments wrap explicitly because Settings does not enable
validate_assignment.
Strip credentials from every string-valued *_url setting rather than two
named ones, and mask environment variables whose names end in _URL, so
inline credentials in connection strings are handled uniformly.
Describe what each bundle member actually offers in the bundle README,
the module docstring, and the Admin UI blurb: deterministic exclusion for
the settings file, name-based masking for environment variables, and
best-effort pattern matching for logs. Prompt the operator to review a
bundle before sharing it.
Document that CSRF_SECRET_KEY reuses JWT_SECRET_KEY when unset, so the
two can be set separately and rotated independently.
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Two gaps in the support bundle's settings redaction, both raised in review. The userinfo pattern shared by the URL and log sanitizers required at least one character for the username, so a DSN of the form scheme://:password@host — accepted by several clients, and the common Redis shape — did not match and the password reached the bundle verbatim. The username group now matches zero characters. Sanitization also keyed off the field name, applying only to keys ending in _url and only to scalar strings. A field name says nothing about the shape of the value behind it, so this missed collection-typed settings entirely: webhook_logging_urls (list[str]), siem_destinations (list[dict], whose entries hold per-destination tokens), and otel_exporter_otlp_headers, a key=value blob that conventionally carries an Authorization header and whose name matches no secret-name rule. Every settings value is now walked and sanitized on its content. Strings are matched against the same patterns already applied to log text; lists and dicts are walked element-wise. Inside a dict, a key whose name looks like a secret has its value replaced outright, since the value carries no pattern to match on — that check is deliberately broader than the one screening our own typed settings, because nested keys come from operator-authored config where "token" is a credential far more often than it is part of a benign name like token_expiry. An empty string now stays empty instead of becoming null, since "set but blank" and "unset" are different facts to whoever reads the bundle. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
chore: improve support bundle redaction and settings secret typing
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
brian-hussey
approved these changes
Aug 5, 2026
brian-hussey
left a comment
Member
There was a problem hiding this comment.
Looks good from my side too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[1.0.7] - 2026-08-04 - Security Hardening, Unified Search, OAuth Improvements, Dataplane Enhancements, and Operational Reliability
Overview
Release 1.0.7 consolidates 57 PRs focused on security hardening, unified search and catalog APIs, OAuth and CSRF improvements, dataplane publishing, CPEX control-execution telemetry, MCP Apps compatibility, and CI/operational reliability:
Breaking Changes
Unconditional weak-secret rejection -
JWT_SECRET_KEYplaceholder and known-weak values now causeSecurityConfigurationErrorat startup in every environment, including development. The__REPLACE_ME__placeholder value is always rejected and will block startup. Update theJWT_SECRET_KEYmanually to a strong secret (length > 32).Root URI policy now defaults to deny (internal#294) - Set
ROOT_ALLOWED_SCHEMESbefore restart for every network scheme used byDEFAULT_ROOTSor new root registrations.file://roots additionally requireROOT_ALLOW_FILE_SCHEME=trueand non-emptyROOT_ALLOWED_FILE_PREFIXES. InvalidDEFAULT_ROOTSabort gateway startup; configure policy before upgrading, not after.POST /rootsrejects unknown fields.PUT /roots/{root_uri}accepts only optionalname; existing full-root PUT payloads containinguri,_meta, or custom fields now return HTTP 422.DEFAULT_ROOTStogether with matching root policy when persistent startup roots are required.OAuth DCR endpoints now enforce un-narrowed admin scope (internal#460) -
GET /oauth/registered-clients,GET /oauth/registered-clients/{gateway_id}, andDELETE /oauth/registered-clients/{client_id}now reject narrowed and public-only admin tokens with403 Forbidden.Security
url_to_markdown_serverMCP server (CWE-918), including DNS-rebinding protection through connection pinning and configurable allowlisting.UBI_MINIMALto include the patched libpq.Added
API & Platform
GET /v1/searchunified search endpoint.TeamCreateRequest.postMessageresponses for success and error paths.GatewayRead.Dataplane & Observability
add_headersandremove_headersconfiguration.cpex.control.summaryandcpex.control.resultspans, configurable result flattening and limits, attribute policies, and optional reason and agent-id emission.Removed
lint-install-hooks,lint-pre-commit,lint-pre-pushMake targets - Removed with the legacylint-stagedhook scripts. Remediation: remove stale.git/hooks/pre-commitand.git/hooks/pre-push, then runmake configure-git.redis_fallbackconfiguration references.Changed
Auth, OAuth & Transport
ui/resourceUrimetadata.Dataplane, Plugins & Middleware
sql_sanitizerwithcpex-sql-sanitizer.Fixed
Security, Auth & API
401for unauthenticated write requests instead of misleading403responses.CSRF_COOKIE_NAMEorCSRF_TOKEN_NAMEare overridden to non-default values, surfacing the misconfiguration at boot rather than at request time as intermittent403 CSRF_TOKEN_INVALIDerrors.Reliability & Infrastructure
Redis Connection Leak (#5711) - Fixed a Redis connection leak.
Health Check Recovery (#4862) - Increased health-check timeout from 5 seconds to 30 seconds and reset the failure counter after recovery.
Docker Compose Startup (#5808) - Restored gateway
HOSTbinding and fast-time-server startup.OAuth Callback JavaScript (#5997) - Removed a Python comment from JavaScript in the OAuth callback.
DCR Client Uniqueness (#5198) - Removed a blocking unique constraint for multi-user DCR clients.
Startup secret validation -
JWT_SECRET_KEYare validated at startup with a minimum 32-byte length requirement and a comprehensive blocklist of known-weak values.The__REPLACE_ME__placeholder value is always rejected and will block startup. Update theJWT_SECRET_KEYmanually to a strong secret (length > 32).Hardened Helm chart defaults -
JWT_SECRET_KEYincharts/mcp-stack/values.yamlnow defaults to an empty string with deployment guidance, rather than shipping a sample weak key.Docker Compose and entrypoint hardening - Compose
:?variable guards and entrypoint secret checks updated to match the new enforcement policy.Helm non-root container startup (#6041) - Set
runAsUserfor postgres (999), redis (999), and fast-time-server (1001) so pods withrunAsNonRoot: trueno longer fail withCreateContainerConfigError. Also correctedmigration.image.tagfromv1.0.6tov1.0.7to ensure the four new Alembic migrations are applied by the init job.E2E test view-modal race (#6084) - Re-checked the resources table and row count before reading the second row in the view-modal test, eliminating a re-render race that could cause a 60-second hang.
Changed
Security & Configuration
JWT_SECRET_KEYplaceholder rejection hardened (#6073) - The__REPLACE_ME__placeholder value forJWT_SECRET_KEYis now unconditionally rejected at startup in all environments. Update theJWT_SECRET_KEYmanually to a strong secret (length > 32).Observability & Security
Settingsmodel rather than a hand-maintained list, ensuring newly added secret-typed fields are automatically covered. Credentials are stripped from all string-valued*_urlsettings and*_URLenvironment variables uniformly.csrf_secret_keyandidentity_claims_secretare now typed asSecretStr.Documentation
Known Issues
403 CSRF validation failed. Recurrence of the class of failure documented in #5151.CSRF_EXEMPT_PATHSfrom.env.exampleinto.envand restart the application.redis_clientis hardcoded toNone, so chat sessions are not shared across workers and are lost on process restart.--workers 1) when session continuity is required.401when LLM Chat targets a virtual server on the same gateway instance.Chores