diff --git a/en/docs/api-design-manage/design/create-api/create-streaming-api/create-a-websocket-streaming-api.md b/en/docs/api-design-manage/design/create-api/create-streaming-api/create-a-websocket-streaming-api.md index ae98c33ddc..50b13f8957 100644 --- a/en/docs/api-design-manage/design/create-api/create-streaming-api/create-a-websocket-streaming-api.md +++ b/en/docs/api-design-manage/design/create-api/create-streaming-api/create-a-websocket-streaming-api.md @@ -185,3 +185,5 @@ Once you create and publish a WebSocket API, you can also /repository/conf/deployment.toml`. Add one `[[transport.ws.proxy_profile]]` block per profile for `ws://` backends and one `[[transport.wss.proxy_profile]]` block per profile for `wss://` backends. + +### Parameters + +| Parameter | Required | Description | +|---|---|---| +| `target_hosts` | Yes | List of Java regex patterns matched against the backend hostname. Use `["*"]` for a catch-all profile. Escape dots: `"example\\.com"`. | +| `proxy_host` | Yes | Hostname or IP address of the HTTP CONNECT proxy. | +| `proxy_port` | Yes | Port of the HTTP CONNECT proxy. | +| `bypass_hosts` | No | List of Java regex patterns. Hosts matching any pattern connect directly, bypassing the proxy for this profile. | +| `proxy_username` | No | Username for `Proxy-Authorization: Basic` authentication. Omit for an unauthenticated proxy. | +| `proxy_password` | No | Password for proxy authentication. | + +### Example: Multiple Profiles + +```toml +# Route payments backend through a dedicated proxy +[[transport.ws.proxy_profile]] +target_hosts = ["payments\\.internal\\.corp"] +proxy_host = "proxy.payments.corp" +proxy_port = 3128 +proxy_username = "gw_user" +proxy_password = "gw_pass" + +# Route all other backends through the default proxy, +# except localhost which should connect directly +[[transport.ws.proxy_profile]] +target_hosts = ["*"] +proxy_host = "proxy.corp.internal" +proxy_port = 3128 +bypass_hosts = ["localhost", "127\\.0\\.0\\.1"] +``` + +For `wss://` backends, use `[[transport.wss.proxy_profile]]` with the same parameters: + +```toml +[[transport.wss.proxy_profile]] +target_hosts = ["payments\\.internal\\.corp"] +proxy_host = "proxy.payments.corp" +proxy_port = 3128 +proxy_username = "gw_user" +proxy_password = "gw_pass" + +[[transport.wss.proxy_profile]] +target_hosts = ["*"] +proxy_host = "proxy.corp.internal" +proxy_port = 3128 +bypass_hosts = ["localhost", "127\\.0\\.0\\.1"] +``` + +!!! note + `[[transport.ws.proxy_profile]]` and `[[transport.wss.proxy_profile]]` are independent. If your WebSocket API has a `ws://` backend endpoint, only the `ws` profiles are evaluated. If it has a `wss://` backend, only the `wss` profiles are evaluated. Configure both sections if you serve both protocols. + +## Scenarios + +### Route a Backend Through an Anonymous Proxy + +Match a specific backend hostname and forward all traffic through a proxy. The proxy requires no authentication. + +```toml +[[transport.ws.proxy_profile]] +target_hosts = ["analytics\\.backend\\.corp"] +proxy_host = "127.0.0.1" +proxy_port = 3128 +``` + +A WebSocket API with endpoint `ws://analytics.backend.corp:9090` will route its outbound connection through `127.0.0.1:3128` via an HTTP CONNECT tunnel. + +### Route a Backend Through an Authenticated Proxy + +Include `proxy_username` and `proxy_password`. The gateway sends a `Proxy-Authorization: Basic` header in the CONNECT request. + +```toml +[[transport.ws.proxy_profile]] +target_hosts = ["secure\\.backend\\.corp"] +proxy_host = "proxy.corp.internal" +proxy_port = 3128 +proxy_username = "gateway" +proxy_password = "s3cr3t" +``` + +### Bypass the Proxy for Selected Hosts + +Use `bypass_hosts` within a profile to exclude specific backends from proxying. The host matches `target_hosts` so the profile applies, but `bypass_hosts` suppresses the proxy for that host. + +```toml +[[transport.ws.proxy_profile]] +target_hosts = [".*\\.internal\\.corp"] +proxy_host = "proxy.corp.internal" +proxy_port = 3128 +# dev-backend.internal.corp can be reached directly; bypass the proxy for it +bypass_hosts = ["dev-backend\\.internal\\.corp"] +``` + +### Use a Catch-All Profile With Exclusions + +A `*` profile routes any backend not matched by a specific profile. Combine with `bypass_hosts` to carve out hosts that should connect directly. + +```toml +# Specific profile: payments cluster has its own proxy +[[transport.ws.proxy_profile]] +target_hosts = [".*\\.payments\\.internal"] +proxy_host = "payments-proxy.corp" +proxy_port = 3128 + +# Catch-all: everything else goes through the corporate proxy, +# except the staging server which is reachable directly +[[transport.ws.proxy_profile]] +target_hosts = ["*"] +proxy_host = "proxy.corp.internal" +proxy_port = 3128 +bypass_hosts = ["staging\\.ws\\.corp"] +``` + +### Connect to a WSS Backend Through a Proxy + +For `wss://` backend endpoints, the gateway opens a raw TCP tunnel through the proxy (HTTP CONNECT), then performs the TLS handshake with the backend directly inside that tunnel. The proxy does not terminate or inspect TLS. + +**Prerequisites:** + +1. Import the backend's TLS certificate (or the signing CA) into the API Manager client truststore: + + ```bash + keytool -import -trustcacerts \ + -alias my-backend \ + -file /path/to/backend.crt \ + -keystore /repository/resources/security/client-truststore.jks \ + -storepass wso2carbon -noprompt + ``` + +2. Restart the server so the truststore change takes effect. + +3. Configure the `wss` proxy profile: + + ```toml + [[transport.wss.proxy_profile]] + target_hosts = ["secure-backend\\.corp"] + proxy_host = "proxy.corp.internal" + proxy_port = 3128 + ``` + +## Limitations and Things to Note + +- **Server restart required.** Proxy profile configuration is read at startup. Changes to `deployment.toml` require a server restart to take effect. + +- **Regex matching is on the hostname string, not the resolved IP.** A profile with `target_hosts = ["127\\.0\\.0\\.1"]` matches only when the backend endpoint uses the IP `127.0.0.1` literally. It does not match `localhost` even though both resolve to the same address. + +- **Profile order matters only within the same priority class.** Among specific profiles (no `*`), the first matching profile wins. Declare more-specific patterns before broader ones to ensure the intended profile is selected. + +- **A single `*` catch-all is supported.** Defining more than one catch-all profile is allowed syntactically, but only the first one is applied. + +- **Only Basic authentication is supported** for `proxy_username` / `proxy_password`. The gateway sends `Proxy-Authorization: Basic `. + +- **`ws` and `wss` profiles are independent.** `[[transport.ws.proxy_profile]]` entries have no effect on `wss://` backends and vice versa. Define both if you use both protocols. + +- **WSS backend certificates must be trusted by the gateway.** When connecting to a `wss://` backend through a proxy, the gateway performs TLS with the backend after the CONNECT tunnel is established. The backend's certificate must be present in the client truststore (`client-truststore.jks`), and the server must be restarted after importing the certificate. + +- **Proxy profiles apply to outbound backend connections only.** They do not affect inbound traffic from API clients to the gateway, or HTTP/REST API backends. Only WebSocket transport senders (`ws` and `wss`) use this configuration. diff --git a/en/docs/reference/config-catalog.md b/en/docs/reference/config-catalog.md index c96c6dddad..02d2032cfa 100644 --- a/en/docs/reference/config-catalog.md +++ b/en/docs/reference/config-catalog.md @@ -4240,7 +4240,7 @@ mode = "HYBRID"
-

Use the application_sharing_impl as default implmentationIf it is saml, the group extractor extracts the claims to group the applications from the saml response.

+

Use the application_sharing_impl as default implementation. If it is saml, the group extractor extracts the claims to group the applications from the saml response.

@@ -11978,7 +11978,7 @@ sender.trust_store.password = "$ref{truststore.password}" -## Message Builders (non-blocking mode) +## WebSocket Proxy Profile
@@ -11990,6 +11990,358 @@ sender.trust_store.password = "$ref{truststore.password}"
+
# Example deployment.toml entry
+[[transport.ws.proxy_profile]]
+target_hosts = ["example\\.backend\\.corp"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+proxy_username = ""
+proxy_password = ""
+bypass_hosts = ["localhost", "127\\.0\\.0\\.1"]
+
+[[transport.ws.proxy_profile]]
+target_hosts = ["*"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+bypass_hosts = ["localhost"]
+
+
+
+
+
+
+ [[transport.ws.proxy_profile]] + +

+ Configures an HTTP CONNECT proxy profile for outbound WebSocket (ws://) connections from the gateway to the backend. Multiple profiles can be defined; the gateway evaluates them in order and uses the first matching profile. Specific profiles (no wildcard in target_hosts) are evaluated before the catch-all profile (target_hosts = ["*"]). +

+
+
+
+
+ target_hosts +
+
+
+

+ string + Required +

+
+ Default: +
+
+ Possible Values: ["example\\.com"], ["*"] +
+
+
+

A list of Java regular expression patterns matched against the backend hostname. Use ["*"] to create a catch-all profile that applies to all hosts not matched by a specific profile. Escape dots: "example\\.com".

+
+
+
+
+ proxy_host +
+
+
+

+ string + Required +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Hostname or IP address of the HTTP CONNECT proxy server.

+
+
+
+
+ proxy_port +
+
+
+

+ integer + Required +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Port number of the HTTP CONNECT proxy server.

+
+
+
+
+ bypass_hosts +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: ["localhost", "127\\.0\\.0\\.1"] +
+
+
+

A list of Java regular expression patterns. Backend hosts matching any pattern connect directly, bypassing the proxy for this profile. Takes precedence over target_hosts.

+
+
+
+
+ proxy_username +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Username for Proxy-Authorization: Basic authentication. Omit for an unauthenticated proxy.

+
+
+
+
+ proxy_password +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Password for proxy authentication.

+
+
+
+
+
+
+
+
+ + + + + +## Secure WebSocket Proxy Profile + + +
+
+
+
+ + + +
+
+
# Example deployment.toml entry
+[[transport.wss.proxy_profile]]
+target_hosts = ["secure-backend\\.corp"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+proxy_username = ""
+proxy_password = ""
+bypass_hosts = ["localhost", "127\\.0\\.0\\.1"]
+
+[[transport.wss.proxy_profile]]
+target_hosts = ["*"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+bypass_hosts = ["localhost"]
+
+
+
+
+
+
+ [[transport.wss.proxy_profile]] + +

+ Configures an HTTP CONNECT proxy profile for outbound secure WebSocket (wss://) connections from the gateway to the backend. The gateway opens a raw TCP tunnel through the proxy via HTTP CONNECT, then performs TLS with the backend inside that tunnel. Multiple profiles can be defined; evaluation rules are the same as for ws proxy profiles. +

+
+
+
+
+ target_hosts +
+
+
+

+ string + Required +

+
+ Default: +
+
+ Possible Values: ["example\\.com"], ["*"] +
+
+
+

A list of Java regular expression patterns matched against the backend hostname. Use ["*"] to create a catch-all profile that applies to all hosts not matched by a specific profile. Escape dots: "example\\.com".

+
+
+
+
+ proxy_host +
+
+
+

+ string + Required +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Hostname or IP address of the HTTP CONNECT proxy server.

+
+
+
+
+ proxy_port +
+
+
+

+ integer + Required +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Port number of the HTTP CONNECT proxy server.

+
+
+
+
+ bypass_hosts +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: ["localhost", "127\\.0\\.0\\.1"] +
+
+
+

A list of Java regular expression patterns. Backend hosts matching any pattern connect directly, bypassing the proxy for this profile. Takes precedence over target_hosts.

+
+
+
+
+ proxy_username +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Username for Proxy-Authorization: Basic authentication. Omit for an unauthenticated proxy.

+
+
+
+
+ proxy_password +
+
+
+

+ string + +

+
+ Default: +
+
+ Possible Values: - +
+
+
+

Password for proxy authentication.

+
+
+
+
+
+
+
+
+
+
+ + + +## Message Builders (non-blocking mode) + + +
+
+
+
+ + + +
+
[message_builders]
 application_xml = "org.apache.axis2.builder.ApplicationXMLBuilder"
 form_urlencoded = "org.apache.synapse.commons.builders.XFormURLEncodedBuilder"
@@ -12220,8 +12572,8 @@ application_binary = "org.apache.axis2.format.BinaryBuilder"
- - + +
[blocking.message_builders]
@@ -12265,8 +12617,8 @@ application_binary = "org.apache.axis2.format.BinaryBuilder"
- - + +
[message_formatters]
@@ -12311,7 +12663,7 @@ application_binary =  "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'application_xml' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'application_xml' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12332,7 +12684,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'form_urlencoded' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'form_urlencoded' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12353,7 +12705,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'multipart_form_data' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'multipart_form_data' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12374,7 +12726,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'text_plain' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'text_plain' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12395,7 +12747,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'application_json' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'application_json' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12416,7 +12768,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'json_badgerfish' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'json_badgerfish' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12437,7 +12789,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'text_javascript' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'text_javascript' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12458,7 +12810,7 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
-

The message formatting implementation that formats messages with the 'octet_stream' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class.

+

The message formatting implementation that formats messages with the 'octet_stream' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class.

@@ -12543,8 +12895,8 @@ application_binary = "org.apache.axis2.format.BinaryFormatter"
- - + +
[blocking.message_formatters]
@@ -12590,8 +12942,8 @@ application_binary =  "org.apache.axis2.format.BinaryFormatter"
- - + +
[[custom_message_builders]]
@@ -12670,8 +13022,8 @@ class = "org.apache.axis2.json.JSONBadgerfishOMBuilder"
- - + +
[[blocking.custom_message_builders]]
@@ -12708,8 +13060,8 @@ class = "org.apache.axis2.json.JSONBadgerfishOMBuilder"
- - + +
[[custom_message_formatters]]
@@ -12788,8 +13140,8 @@ class = "org.apache.axis2.json.JSONBadgerfishMessageFormatter"
- - + +
[[blocking.custom_message_formatters]]
@@ -12826,8 +13178,8 @@ class = "org.apache.axis2.json.JSONBadgerfishMessageFormatter"
- - + +
[message_formatter.options]
@@ -12907,8 +13259,8 @@ preserveMultipartPartContentTransferEncoding = true
         
- - + +
[mediation]
@@ -13245,8 +13597,8 @@ inbound.max_threads = 100
- - + +
enabled_global_handlers= ["custom_logger"]
@@ -13327,8 +13679,8 @@ custom_logger.class= "com.wso2.apim.log.handler.SynapseLogHandler"
         
- - + +
[governance]
@@ -13385,8 +13737,8 @@ life_cycle_checklist_items_enabled = true
- - + +
[qpid.heartbeat]
@@ -13461,8 +13813,8 @@ timeout_factor = 3.0
- - + +
[carbon_health_check]
@@ -13517,8 +13869,8 @@ enable = true
- - + +
[carbon_health_check.health_checker.super_tenant_health_checker]
@@ -13593,8 +13945,8 @@ order = "98"
- - + +
[carbon_health_check.health_checker.super_tenant_health_checker.properties]
@@ -13647,8 +13999,8 @@ monitored.user.stores = "primary,sec"
- - + +
[carbon_health_check.health_checker.data_source_health_checker]
@@ -13723,8 +14075,8 @@ order = "97"
- - + +
[carbon_health_check.health_checker.data_source_health_checker.properties]
@@ -13797,8 +14149,8 @@ monitored.datasources = "jdbc/WSO2AM_DB,jdbc/SHARED_DB,jdbc/WSO2CarbonDB"
         
- - + +
[health_checker]
@@ -13894,8 +14246,8 @@ first_property = "value"
- - + +
[oauth]
@@ -14073,8 +14425,8 @@ token_context_dialect_uri = "http://wso2.org/claims"
         
- - + +
[oauth.token_validation]
@@ -14168,8 +14520,8 @@ refresh_token_validity = "86400"
         
- - + +
[oauth.token_cleanup]
@@ -14246,8 +14598,8 @@ retain_access_tokens_for_auditing = true
- - + +
[oauth.oidc.extensions]
@@ -14475,8 +14827,8 @@ enable_unmapped_user_attributes = true
         
- - + +
[oauth.grant_type.authorization_code]
@@ -14964,8 +15316,8 @@ grant_validator = "org.wso2.carbon.identity.oauth2.grant.kerberos.KerberosGrantV
         
- - + +
[session_data.persistence]
@@ -15018,8 +15370,8 @@ persistence_pool_size = 0
- - + +
[oauth.token_generation]
@@ -15074,8 +15426,8 @@ retry_count_on_persistence_failures = 5
- - + +
[user_store.properties]
@@ -15903,8 +16255,8 @@ UserCoreCacheTimeOut = 5 
- - + +
[custom_keystore.APIKeyKeyStore]
@@ -16039,8 +16391,8 @@ key_password = "wso2carbon"
- - + +
[http_access_log]
@@ -16097,8 +16449,8 @@ enabled = true
- - + +
#### Sample deployment.toml entry
@@ -16445,8 +16797,8 @@ mediaType = "application/vnd.wso2-service+xml"
         
- - + +
[apim.transport_headers]
@@ -16586,8 +16938,8 @@ excludeResponseHeaders = ""
         
- - + +
[synapse_handlers.custom_handler_name]
@@ -16663,8 +17015,8 @@ class="org.wso2.carbon.apimgt.gateway.handlers.custom.customer_handler"
         
- - + +
[apim.governance.scheduler]
@@ -16780,8 +17132,8 @@ task_cleanup_interval_minutes = 30
         
- - + +
[apim.mediator_config.oauth.trust_store]
@@ -16874,8 +17226,8 @@ password = "wso2carbon"
- - + +
[transport.receiver]
@@ -16927,8 +17279,8 @@ max_reconnection_interval = 3600
         
- - + +
[apim.basic_authenticator]
@@ -17044,8 +17396,8 @@ max_wait_millis = 30000
         
- - + +
[apim.synapse_artifact_generator.thread_pool]
@@ -17160,8 +17512,8 @@ queue_capacity = 50
- - + +
[encryption]
@@ -17217,8 +17569,8 @@ key = ""
         
- - + +
[web_app.cookie_processor]
@@ -17276,8 +17628,8 @@ same_site_cookies = "lax"
         
- - + +
[apim.aws_lambda]
@@ -17366,8 +17718,8 @@ retry_max_attempts = 2
         
- - + +
[synapse_properties]
@@ -17447,8 +17799,8 @@ retry_max_attempts = 2
         
- - + +
[dependency_properties]
@@ -17504,8 +17856,8 @@ retry_max_attempts = 2
         
- - + +
[authentication.authenticator.oidc.parameters]
@@ -17563,8 +17915,8 @@ excludedClaimAttributes="at_hash,iss,iat,exp,aud,azp"
         
- - + +
# API KEY CONFIGS
@@ -17741,8 +18093,8 @@ azure_umi_scope = "https://cognitiveservices.azure.com/.default"
         
- - + +
[apim.ai.vector_db_provider]
@@ -17870,8 +18222,8 @@ ttl = 3600
         
- - + +
[apim.ai.azure_umi]
@@ -17927,8 +18279,8 @@ scope = "https://ai.azure.com/.default"
         
- - + +
[apim.aws_lambda.http_client]
diff --git a/en/mkdocs.yml b/en/mkdocs.yml
index 39250f5475..31a7028297 100644
--- a/en/mkdocs.yml
+++ b/en/mkdocs.yml
@@ -461,6 +461,7 @@ nav:
                 - Classic Gateway with Dedicated Tenants: api-gateway/maintain-seperate-gateways-per-tenants.md
                 - Classic Gateways with Dedicated Backends: api-gateway/api-gateways-with-dedicated-backends.md
                 - Mutual SSL Between Classic Gateway and Backend: api-gateway/mutual-ssl-between-api-gateway-and-backend.md
+                - WebSocket Proxy Profiles: api-gateway/websocket-proxy-profiles.md
                 - Storing Custom Synapse Artifacts in the Gateway: api-gateway/custom-synapse-artifacts.md
             - Gateway Policies:
                 - Adding Dynamic Endpoints: api-gateway/policies/adding-dynamic-endpoints.md
diff --git a/en/tools/config-catalog-generator/data/_ws-proxy-profile.toml b/en/tools/config-catalog-generator/data/_ws-proxy-profile.toml
new file mode 100644
index 0000000000..7edc878d5d
--- /dev/null
+++ b/en/tools/config-catalog-generator/data/_ws-proxy-profile.toml
@@ -0,0 +1,14 @@
+# Example deployment.toml entry
+[[transport.ws.proxy_profile]]
+target_hosts = ["example\\.backend\\.corp"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+proxy_username = ""
+proxy_password = ""
+bypass_hosts = ["localhost", "127\\.0\\.0\\.1"]
+
+[[transport.ws.proxy_profile]]
+target_hosts = ["*"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+bypass_hosts = ["localhost"]
diff --git a/en/tools/config-catalog-generator/data/_wss-proxy-profile.toml b/en/tools/config-catalog-generator/data/_wss-proxy-profile.toml
new file mode 100644
index 0000000000..9b3780c9ff
--- /dev/null
+++ b/en/tools/config-catalog-generator/data/_wss-proxy-profile.toml
@@ -0,0 +1,14 @@
+# Example deployment.toml entry
+[[transport.wss.proxy_profile]]
+target_hosts = ["secure-backend\\.corp"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+proxy_username = ""
+proxy_password = ""
+bypass_hosts = ["localhost", "127\\.0\\.0\\.1"]
+
+[[transport.wss.proxy_profile]]
+target_hosts = ["*"]
+proxy_host = "proxy.corp.internal"
+proxy_port = 3128
+bypass_hosts = ["localhost"]
diff --git a/en/tools/config-catalog-generator/data/configs.json b/en/tools/config-catalog-generator/data/configs.json
index e51ab9bb07..7fed019863 100755
--- a/en/tools/config-catalog-generator/data/configs.json
+++ b/en/tools/config-catalog-generator/data/configs.json
@@ -1583,7 +1583,7 @@
                             "required": false,
                             "default": "If the config is not mentioned, then undefined.default",
                             "possible": "default, saml",
-                            "description": "Use the application_sharing_impl as default implmentationIf it is saml, the group extractor extracts the claims to group the applications from the saml response."
+                            "description": "Use the application_sharing_impl as default implementation. If it is saml, the group extractor extracts the claims to group the applications from the saml response."
                         },
                         {
                             "name": "application_sharing_impl",
@@ -4492,6 +4492,128 @@
             ],
             "exampleFile": "_wss-transport.toml"
         },
+        {
+            "title": "WebSocket Proxy Profile",
+            "options": [
+                {
+                    "name": "[transport.ws.proxy_profile]",
+                    "required": false,
+                    "description": "Configures an HTTP CONNECT proxy profile for outbound WebSocket (ws://) connections from the gateway to the backend. Multiple profiles can be defined; the gateway evaluates them in order and uses the first matching profile. Specific profiles (no wildcard in target_hosts) are evaluated before the catch-all profile (target_hosts = [\"*\"]).",
+                    "params": [
+                        {
+                            "name": "target_hosts",
+                            "type": "string",
+                            "required": true,
+                            "default": "",
+                            "possible": "[\"example\\\\.com\"], [\"*\"]",
+                            "description": "A list of Java regular expression patterns matched against the backend hostname. Use [\"*\"] to create a catch-all profile that applies to all hosts not matched by a specific profile. Escape dots: \"example\\\\.com\"."
+                        },
+                        {
+                            "name": "proxy_host",
+                            "type": "string",
+                            "required": true,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Hostname or IP address of the HTTP CONNECT proxy server."
+                        },
+                        {
+                            "name": "proxy_port",
+                            "type": "integer",
+                            "required": true,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Port number of the HTTP CONNECT proxy server."
+                        },
+                        {
+                            "name": "bypass_hosts",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "[\"localhost\", \"127\\\\.0\\\\.0\\\\.1\"]",
+                            "description": "A list of Java regular expression patterns. Backend hosts matching any pattern connect directly, bypassing the proxy for this profile. Takes precedence over target_hosts."
+                        },
+                        {
+                            "name": "proxy_username",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Username for Proxy-Authorization: Basic authentication. Omit for an unauthenticated proxy."
+                        },
+                        {
+                            "name": "proxy_password",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Password for proxy authentication."
+                        }
+                    ]
+                }
+            ],
+            "exampleFile": "_ws-proxy-profile.toml"
+        },
+        {
+            "title": "Secure WebSocket Proxy Profile",
+            "options": [
+                {
+                    "name": "[transport.wss.proxy_profile]",
+                    "required": false,
+                    "description": "Configures an HTTP CONNECT proxy profile for outbound secure WebSocket (wss://) connections from the gateway to the backend. The gateway opens a raw TCP tunnel through the proxy via HTTP CONNECT, then performs TLS with the backend inside that tunnel. Multiple profiles can be defined; evaluation rules are the same as for ws proxy profiles.",
+                    "params": [
+                        {
+                            "name": "target_hosts",
+                            "type": "string",
+                            "required": true,
+                            "default": "",
+                            "possible": "[\"example\\\\.com\"], [\"*\"]",
+                            "description": "A list of Java regular expression patterns matched against the backend hostname. Use [\"*\"] to create a catch-all profile that applies to all hosts not matched by a specific profile. Escape dots: \"example\\\\.com\"."
+                        },
+                        {
+                            "name": "proxy_host",
+                            "type": "string",
+                            "required": true,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Hostname or IP address of the HTTP CONNECT proxy server."
+                        },
+                        {
+                            "name": "proxy_port",
+                            "type": "integer",
+                            "required": true,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Port number of the HTTP CONNECT proxy server."
+                        },
+                        {
+                            "name": "bypass_hosts",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "[\"localhost\", \"127\\\\.0\\\\.0\\\\.1\"]",
+                            "description": "A list of Java regular expression patterns. Backend hosts matching any pattern connect directly, bypassing the proxy for this profile. Takes precedence over target_hosts."
+                        },
+                        {
+                            "name": "proxy_username",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Username for Proxy-Authorization: Basic authentication. Omit for an unauthenticated proxy."
+                        },
+                        {
+                            "name": "proxy_password",
+                            "type": "string",
+                            "required": false,
+                            "default": "",
+                            "possible": "-",
+                            "description": "Password for proxy authentication."
+                        }
+                    ]
+                }
+            ],
+            "exampleFile": "_wss-proxy-profile.toml"
+        },
         {
             "title": "Message Builders (non-blocking mode)",
             "options": [
@@ -4602,7 +4724,7 @@
                             "required": false,
                             "default": "org.apache.axis2.transport.http.ApplicationXMLFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'application_xml' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'application_xml' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "form_urlencoded",
@@ -4610,7 +4732,7 @@
                             "required": false,
                             "default": "-",
                             "possible": "org.apache.synapse.commons.formatters.XFormURLEncodedFormatter",
-                            "description": "The message formatting implementation that formats messages with the 'form_urlencoded' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'form_urlencoded' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "multipart_form_data",
@@ -4618,7 +4740,7 @@
                             "required": false,
                             "default": "org.apache.axis2.transport.http.MultipartFormDataFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'multipart_form_data' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'multipart_form_data' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "text_plain",
@@ -4626,7 +4748,7 @@
                             "required": false,
                             "default": "org.apache.axis2.format.PlainTextFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'text_plain' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'text_plain' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "application_json",
@@ -4634,7 +4756,7 @@
                             "required": false,
                             "default": "org.wso2.micro.integrator.core.json.JsonStreamFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'application_json' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'application_json' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "json_badgerfish",
@@ -4642,7 +4764,7 @@
                             "required": false,
                             "default": "org.apache.axis2.json.JSONBadgerfishMessageFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'json_badgerfish' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'json_badgerfish' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "text_javascript",
@@ -4650,7 +4772,7 @@
                             "required": false,
                             "default": "org.apache.axis2.json.JSONMessageFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'text_javascript' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'text_javascript' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "octet_stream",
@@ -4658,7 +4780,7 @@
                             "required": false,
                             "default": "org.wso2.carbon.relay.ExpandingMessageFormatter",
                             "possible": "-",
-                            "description": "The message formatting implementation that formats messages with the 'octet_stream' content type before they are sent out of the Micro Integrator. If required, you can change the default formating class."
+                            "description": "The message formatting implementation that formats messages with the 'octet_stream' content type before they are sent out of the Micro Integrator. If required, you can change the default formatting class."
                         },
                         {
                             "name": "application_binary",