Skip to content

Release 1.0.7 - #6039

Merged
ja8zyjits merged 30 commits into
mainfrom
Release/v1.0.7
Aug 5, 2026
Merged

Release 1.0.7#6039
ja8zyjits merged 30 commits into
mainfrom
Release/v1.0.7

Conversation

@prakhar-singh1928

@prakhar-singh1928 prakhar-singh1928 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

[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:

  • Security - Root URI policy hardening, token-scope enforcement, safer admin demotion, A2A authorization, REST outbound validation, CSRF response correctness, and patched container dependencies.
  • API & Platform - Added v1 catalog and unified search endpoints, bulk team member creation, popup-based OAuth authorization, GatewayRead counts, and improved OAuth resource handling.
  • Dataplane & MCP - Added per-backend header publication, opaque dataplane subject IDs, session-token identity resolution, and deprecated MCP Apps metadata compatibility.
  • Observability & Plugins - Added CPEX control-execution telemetry and improved upstream MCP session diagnostics; replaced the in-tree SQL sanitizer with the maintained CPEX plugin.
  • Operations - Improved Redis session recovery and connection handling, health-check recovery, s390x builds, production smoke checks, dependency security, and developer tooling.

Breaking Changes

  • Unconditional weak-secret rejection - JWT_SECRET_KEY placeholder and known-weak values now cause SecurityConfigurationError at startup in every environment, including development. The __REPLACE_ME__ placeholder value is always rejected and will block startup. Update the JWT_SECRET_KEY manually to a strong secret (length > 32).

  • Root URI policy now defaults to deny (internal#294) - Set ROOT_ALLOWED_SCHEMES before restart for every network scheme used by DEFAULT_ROOTS or new root registrations. file:// roots additionally require ROOT_ALLOW_FILE_SCHEME=true and non-empty ROOT_ALLOWED_FILE_PREFIXES. Invalid DEFAULT_ROOTS abort gateway startup; configure policy before upgrading, not after.

    • Root management API payloads are strict - POST /roots rejects unknown fields. PUT /roots/{root_uri} accepts only optional name; existing full-root PUT payloads containing uri, _meta, or custom fields now return HTTP 422.
    • Root-inclusive exports require unrestricted platform administration - Unfiltered export includes roots and returns HTTP 403 for team-scoped administrators. Run backup exports with unrestricted platform-admin credentials, or explicitly exclude roots when a scoped export is intended.
    • Root registrations are runtime state - Roots are held in memory and are not database-persisted. Manual registrations do not survive process restart; configure DEFAULT_ROOTS together 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}, and DELETE /oauth/registered-clients/{client_id} now reject narrowed and public-only admin tokens with 403 Forbidden.

Security

  • Fixed SSRF vulnerability in url_to_markdown_server MCP server (CWE-918), including DNS-rebinding protection through connection pinning and configurable allowlisting.
  • API token scope enforcement (#4737) - Enforced scope-based access control for API tokens.
  • Search Token Scoping (#5668) - Applied token-scoped team filtering to unified search results for administrators.
  • Safe admin demotion (#5644) - Enforced safe rules when demoting administrators.
  • A2A admin edit authorization (#5922) - Hardened authorization for A2A administrative edits.
  • REST outbound validation (#5925) - Hardened validation of outbound REST tool requests.
  • Patched libpq dependency (#5809) - Bumped UBI_MINIMAL to include the patched libpq.

Added

API & Platform

  • v1 Catalog API (#5544) - Added the v1 catalog API.
  • Unified Search API (#5610) - Added versioned GET /v1/search unified search endpoint.
  • Bulk Team Member Creation (#5626) - Added bulk member creation support to TeamCreateRequest.
  • Popup-Based OAuth Authorization (#5661) - Added popup authorization support with CSP-nonce'd postMessage responses for success and error paths.
  • Gateway Counts (#5657) - Added prompt and resource counts to GatewayRead.

Dataplane & Observability

  • Per-Backend Header Publication (#5924) - Published per-backend add_headers and remove_headers configuration.
  • CPEX Control-Execution Telemetry (#6003) - Added structured per-plugin enforcement observability on tool invocations. Requires CPEX >= 0.1.2 and is a silent no-op on older builds. Added cpex.control.summary and cpex.control.result spans, configurable result flattening and limits, attribute policies, and optional reason and agent-id emission.
  • Upstream MCP Session Diagnostics (#5631) - Improved diagnostics for upstream MCP session errors.

Removed

  • lint-install-hooks, lint-pre-commit, lint-pre-push Make targets - Removed with the legacy lint-staged hook scripts. Remediation: remove stale .git/hooks/pre-commit and .git/hooks/pre-push, then run make configure-git.
  • Granian HTTP server option (#5607) - Removed the Granian server option.
  • Obsolete Redis fallback references (#5645) - Removed obsolete redis_fallback configuration references.

Changed

Auth, OAuth & Transport

  • OAuth Resource UI and Origin Handling (#4476) - Added the OAuth Resource UI field, origin fallback, and softened auto-derived validation.
  • Authorization-Code OAuth Reliability (#5244) - Resolved offline issues for authorization-code OAuth gateways.
  • Session-Token Identity Resolution (#5802) - Resolved session-token subject UUIDs to email in streamable HTTP authentication.
  • LLM Chat Session Resume (#5790) - Allowed any worker to resume LLM Chat sessions from Redis.
  • MCP Apps Metadata Compatibility (#5764) - Honoured deprecated flat ui/resourceUri metadata.

Dataplane, Plugins & Middleware

  • Opaque Dataplane Subject IDs (#5708) - Switched dataplane subjects to opaque identifiers.
  • SQL Sanitizer Plugin (#5961) - Replaced the in-tree sql_sanitizer with cpex-sql-sanitizer.
  • Auth-Context Middleware Refactor (#6008) - Extracted auth-context middleware registration into a testable submodule.

Fixed

Security, Auth & API

  • RBAC Seeder Race (#4636) - Added unique constraints and migration remapping for active roles and user-role assignments, with savepoint/retry handling for concurrent bootstrap.
  • CSRF Status Code (#5917) - Returned 401 for unauthenticated write requests instead of misleading 403 responses.
  • LLM Settings CSRF (#5780) - Fixed CSRF failures when saving LLM settings in the Admin UI.
  • Resource URI Conflict Message (#5920) - Showed a specific message for duplicate resource URI conflicts.
  • Vite Rollup Fallback on s390x (#5779, #5836, #5958) - Fixed and force-installed the rollup fallback, including a Vite downgrade from 8 to 7 for s390x.
  • CSRF Name Override Startup Warning (#6078) - Emitted a startup warning when CSRF_COOKIE_NAME or CSRF_TOKEN_NAME are overridden to non-default values, surfacing the misconfiguration at boot rather than at request time as intermittent 403 CSRF_TOKEN_INVALID errors.

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 HOST binding 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_KEY are 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 the JWT_SECRET_KEY manually to a strong secret (length > 32).

  • Hardened Helm chart defaults - JWT_SECRET_KEY in charts/mcp-stack/values.yaml now 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 runAsUser for postgres (999), redis (999), and fast-time-server (1001) so pods with runAsNonRoot: true no longer fail with CreateContainerConfigError. Also corrected migration.image.tag from v1.0.6 to v1.0.7 to 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_KEY placeholder rejection hardened (#6073) - The __REPLACE_ME__ placeholder value for JWT_SECRET_KEY is now unconditionally rejected at startup in all environments. Update the JWT_SECRET_KEY manually to a strong secret (length > 32).

Observability & Security

  • Support bundle secret redaction (#6080) - Secret exclusion in generated bundles is now derived from the Settings model rather than a hand-maintained list, ensuring newly added secret-typed fields are automatically covered. Credentials are stripped from all string-valued *_url settings and *_URL environment variables uniformly. csrf_secret_key and identity_claims_secret are now typed as SecretStr.

Documentation

  • OCP PGO Documentation (#5749) - Updated OCP PGO documentation.
  • CSRF, Middleware, and LLM Admin Documentation (#5979) - Documented CSRF protection, middleware ordering, and LLM admin endpoints.
  • Architecture Roadmap and Release History (#6037) - Updated the architecture roadmap and added release history.

Known Issues

  • CSRF Validation Failure Saving LLM Provider/Model (#5739) - Saving an LLM Provider or Model in the Admin UI can fail with 403 CSRF validation failed. Recurrence of the class of failure documented in #5151.
    • Workaround: Copy CSRF_EXEMPT_PATHS from .env.example into .env and restart the application.
  • LLM Chat Sessions Are In-Memory Only (#5740) - redis_client is hardcoded to None, so chat sessions are not shared across workers and are lost on process restart.
    • Workaround: Run a single worker (--workers 1) when session continuity is required.
  • LLM Chat Cannot Connect to a Same-Gateway Virtual Server (#5215) - The forwarded session token is rejected with 401 when LLM Chat targets a virtual server on the same gateway instance.
  • Tools Table Row Action Button Not Found (#5526) - The row action button is not found for the JSON-schema test tool in the Tools table.

Chores

PR Description Author
#5751 ci: enable all arch build for workflow_dispatch manual trigger madhu-mohan-jaishankar
#5269 fix(helm): resolve Helm chart linting issues cafalchio
#5775 chore(deps): bump cpex-secrets-detection to 0.3.10 lucarlig
#5788 fix detect secrets prakhar-singh1928
#4453 chore: developer tooling housekeeping — git hooks, secrets-scan tooling, agent docs, ignore files jonpspri
#5756 ci: add compose production smoke check madhu-mohan-jaishankar
#5787 chore: fix pip-audit prakhar-singh1928
#5840 chore: pin mcp>=1.28.1,<2 ahead of MCP Python SDK v2 stable release Altamimi-Dev
#5919 chore: update python dependencies prakhar-singh1928
#5923 ci: create .env before compose-up in prod smoke check madhu-mohan-jaishankar
#5927 test: Remove redundant waits gcgoncalves
#5438 Follow-on refinements to Docker Security Scan job jonpspri
#6035 chore: bump cryptography to 50.0.0 msureshkumar88
#6041 fix(helm): set runAsUser so non-root containers can start madhu-mohan-jaishankar
#6073 feat: relax AUTH_ENCRYPTION_SECRET enforcement in development environment prakhar-singh1928
#6078 fix: warn at startup when CSRF cookie or header names are overridden madhu-mohan-jaishankar
#6080 chore: improve support bundle redaction and settings secret typing msureshkumar88
#6084 fix(tests): re-check resources table before reading second row in view-modal test gcgoncalves

Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
@prakhar-singh1928
prakhar-singh1928 marked this pull request as draft August 4, 2026 15:18
Signed-off-by: prakhar-singh1928 <prakhar.singh1928@ibm.com>
@prakhar-singh1928
prakhar-singh1928 marked this pull request as ready for review August 4, 2026 15:35
vishu-bh and others added 20 commits August 4, 2026 16:42
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>
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>
Suresh Kumar Moharajan and others added 3 commits August 5, 2026 15:34
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>

@madhu-mohan-jaishankar madhu-mohan-jaishankar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@brian-hussey brian-hussey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my side too.

@Lang-Akshay Lang-Akshay left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✅

@gandhipratik203 gandhipratik203 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ja8zyjits
ja8zyjits added this pull request to the merge queue Aug 5, 2026
Merged via the queue into main with commit 4092d33 Aug 5, 2026
81 checks passed
@ja8zyjits
ja8zyjits deleted the Release/v1.0.7 branch August 5, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants