Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a401113
Add WebSocket generator for real-time LLM security testing
dyrtyData Sep 18, 2025
b356b68
Apply suggestions from code review
dyrtyData Sep 25, 2025
976869f
Merge branch 'NVIDIA:main' into websocket-generator-feature
dyrtyData Sep 25, 2025
e220924
Implement improved WebSocket generator with websockets library
dyrtyData Sep 25, 2025
0639bb9
Remove old markdown documentation
dyrtyData Sep 25, 2025
012e960
Add websockets library as dependency
dyrtyData Oct 9, 2025
3efda30
Fix WebSocket generator test failures
dyrtyData Oct 9, 2025
7690301
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
e19892c
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
27e9130
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
c63a409
Remove PRtests/ from .gitignore
dyrtyData Oct 10, 2025
26a7924
Re-apply critical test fixes after architectural changes
dyrtyData Oct 10, 2025
68d4fda
Fix documentation security: Use environment variables for passwords
dyrtyData Oct 10, 2025
d074a25
Address security and logging concerns from code review
dyrtyData Oct 10, 2025
2c6ca51
Update garak/generators/websocket.py
dyrtyData Oct 10, 2025
65bf1e8
Update garak/generators/websocket.py
dyrtyData Oct 10, 2025
7c53a7f
Update garak/generators/websocket.py
dyrtyData Oct 10, 2025
0f272e7
Move environment variable access to _validate_env_var
dyrtyData Oct 10, 2025
79d7670
Improve test robustness with dynamic values
dyrtyData Oct 10, 2025
e7c0346
Move DEFAULT_PARAMS from module level to class level
dyrtyData Oct 10, 2025
5f6b8de
Add ENV_VAR class constant for environment variable name
dyrtyData Oct 10, 2025
bc864de
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
0fbb0a4
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
0de7c07
Apply suggestion from @jmartin-tech
dyrtyData Oct 10, 2025
72a576f
Fix syntax error in test configuration
dyrtyData Oct 10, 2025
05c3d53
Fix environment variable access initialization order bug
dyrtyData Oct 11, 2025
f26358f
Fix remaining WebSocket generator test failures
dyrtyData Oct 11, 2025
39cf785
Fix AsyncMock test failure in WebSocket generator
dyrtyData Oct 13, 2025
06ac326
Update docs/source/garak.generators.websocket.rst
dyrtyData Oct 13, 2025
365ce09
Update docs/source/garak.generators.websocket.rst
dyrtyData Oct 13, 2025
7ff3f5b
Update garak/generators/websocket.py
dyrtyData Oct 13, 2025
810f7d7
Refactor WebSocket generator to use framework-compliant initialization
dyrtyData Oct 13, 2025
e9c65cd
Add smart detection for unsupported WebSocket scenarios
dyrtyData Oct 13, 2025
5065027
Fix security vulnerability in WebSocket URI handling
dyrtyData Oct 14, 2025
af36310
Update garak/generators/websocket.py
dyrtyData Oct 14, 2025
b5f62ca
Update garak/generators/websocket.py
dyrtyData Oct 14, 2025
b2824da
Update garak/generators/websocket.py
dyrtyData Oct 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,4 @@ hitlog.*.jsonl
garak_runs/
runs/
logs/
.DS_Store

.DS_Store
225 changes: 225 additions & 0 deletions docs/source/garak.generators.websocket.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
garak.generators.websocket
==========================

WebSocket connector for real-time LLM services.

This generator enables garak to test WebSocket-based LLM services that use
real-time bidirectional communication, similar to modern chat applications.

Uses the following options from ``_config.plugins.generators["websocket"]["WebSocketGenerator"]``:

* ``uri`` - the WebSocket URI (ws:// or wss://); can also be passed in --model_name
* ``name`` - a short name for this service; defaults to "WebSocket LLM"
* ``auth_type`` - authentication method: "none", "basic", "bearer", or "custom"
* ``username`` - username for basic authentication
* ``api_key`` - API key for bearer token auth or password for basic auth
* ``key_env_var`` - environment variable holding API key; default ``WEBSOCKET_API_KEY``
* ``req_template`` - string template where ``$INPUT`` is replaced by prompt, ``$KEY`` by API key, ``$CONVERSATION_ID`` by conversation ID
* ``req_template_json_object`` - request template as Python object, serialized to JSON with placeholder replacements
* ``headers`` - dict of additional WebSocket headers
* ``response_json`` - is the response in JSON format? (bool)
* ``response_json_field`` - which field contains the response text? Supports JSONPath (prefix with ``$``)
* ``response_after_typing`` - wait for typing indicators to complete? (bool)
* ``typing_indicator`` - string that indicates typing status; default "typing"
* ``request_timeout`` - seconds to wait for response; default 20
* ``connection_timeout`` - seconds to wait for connection; default 10
* ``max_response_length`` - maximum response length; default 10000
* ``verify_ssl`` - enforce SSL certificate validation? Default ``True``

Templates work similarly to the REST generator. The ``$INPUT``, ``$KEY``, and
``$CONVERSATION_ID`` placeholders are replaced in both string templates and
JSON object templates.

JSON Response Extraction
------------------------

The ``response_json_field`` parameter supports JSONPath-style extraction:

* Simple field: ``"text"`` extracts ``response.text``
* Nested field: ``"$.data.message"`` extracts ``response.data.message``
* Array access: ``"$.messages[0].content"`` extracts first message content

Authentication Methods
----------------------

**No Authentication:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "ws://localhost:3000/chat",
"auth_type": "none"
}
}
}

**Basic Authentication:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "ws://localhost:3000/chat",
"auth_type": "basic",
"username": "user"
}
}
}

Set the password via environment variable:

.. code-block:: bash

export WEBSOCKET_API_KEY="your_secure_password"

**Bearer Token:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "wss://api.example.com/llm",
"auth_type": "bearer",
"api_key": "your_api_key_here"
}
}
}

**Environment Variable API Key:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "wss://api.example.com/llm",
"auth_type": "bearer",
"key_env_var": "MY_LLM_API_KEY"
}
}
}

Message Templates
-----------------

**Simple Text Template:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "ws://localhost:3000/chat",
"req_template": "User: $INPUT"
}
}
}

**JSON Object Template:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "ws://localhost:3000/chat",
"req_template_json_object": {
"message": "$INPUT",
"conversation_id": "$CONVERSATION_ID",
"api_key": "$KEY"
},
"response_json": true,
"response_json_field": "text"
}
}
}

**Complex JSON with Nested Response:**

.. code-block:: JSON

{
"websocket": {
"WebSocketGenerator": {
"uri": "wss://api.example.com/llm",
"req_template_json_object": {
"prompt": "$INPUT",
"stream": false,
"model": "gpt-4"
},
"response_json": true,
"response_json_field": "$.choices[0].message.content"
}
}
}

Usage Examples
---------------

**Command Line with JSON Options:**

.. code-block:: bash

# Set password securely via environment variable
export WEBSOCKET_API_KEY="your_secure_password"

garak --model_type websocket.WebSocketGenerator \
--generator_options '{"websocket": {"WebSocketGenerator": {"uri": "ws://localhost:3000", "auth_type": "basic", "username": "user"}}}' \
--probes dan

**Configuration File:**

Save configuration to ``websocket_config.json`` and use:

.. code-block:: bash

garak --model_type websocket.WebSocketGenerator \
-G websocket_config.json \
--probes encoding

**Testing with Public Echo Server:**

.. code-block:: bash

garak --model_type websocket.WebSocketGenerator \
--generator_options '{"websocket": {"WebSocketGenerator": {"uri": "wss://echo.websocket.org", "response_after_typing": false}}}' \
--probes dan --generations 1

SSH Tunnel Support
------------------

The generator works seamlessly with SSH tunnels for secure remote testing:

.. code-block:: bash

# Establish tunnel
ssh -L 3000:target-host:3000 jump-host -N -f

# Test through tunnel
garak --model_type websocket.WebSocketGenerator \
--generator_options '{"websocket": {"WebSocketGenerator": {"uri": "ws://localhost:3000"}}}' \
--probes malwaregen

Typing Indicators
-----------------

Many chat-based LLMs send typing indicators. Configure response handling:

* ``response_after_typing: true`` - Wait for typing to complete (default)
* ``response_after_typing: false`` - Return first substantial response
* ``typing_indicator`` - String to detect typing status (default "typing")

This enables proper testing of streaming/real-time LLM services.

----

.. automodule:: garak.generators.websocket
:members:
:undoc-members:
:show-inheritance:


1 change: 1 addition & 0 deletions docs/source/generators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ For a detailed oversight into how a generator operates, see :doc:`garak.generato
garak.generators.rasa
garak.generators.test
garak.generators.watsonx
garak.generators.websocket
Loading