Skip to content

BUG: RealtimeTarget doesn't send its configured headers #4254

Open

Description

@nniiovoo

Describe the bug

RealtimeTarget takes headers (and reads OPENAI_ADDITIONAL_REQUEST_HEADERS like the other OpenAI targets), but they never reach the realtime websocket. Neither the client built in _get_openai_client nor the client.realtime.connect(...) call in _connect_async gets them, so the configured headers are left out of the websocket handshake. A realtime endpoint behind a gateway that needs its own header, like an API Management key or a routing header, can't be reached.

The other OpenAI targets pass the same headers to their client as default_headers.

Steps/Code to Reproduce

A local websocket server records the handshake headers:

import asyncio

import websockets

from pyrit.prompt_target import RealtimeTarget
from pyrit.setup import IN_MEMORY, initialize_pyrit_async

handshake_headers = {}


async def record_headers(websocket):
    handshake_headers.update({name.lower(): value for name, value in websocket.request.headers.raw_items()})
    await websocket.close()


async def main():
    await initialize_pyrit_async(memory_db_type=IN_MEMORY)
    async with websockets.serve(record_headers, "127.0.0.1", 0) as server:
        port = server.sockets[0].getsockname()[1]
        target = RealtimeTarget(
            endpoint=f"ws://127.0.0.1:{port}/v1",
            api_key="key",
            model_name="gpt-realtime",
            headers='{"X-Gateway-Key": "gateway-key"}',
        )
        connection = await target._connect_async(conversation_id="c1")
        await asyncio.sleep(0.2)
        await connection.close()

    print("authorization sent:", "authorization" in handshake_headers)
    print("x-gateway-key sent:", "x-gateway-key" in handshake_headers)


asyncio.run(main())

Expected Results

authorization sent: True
x-gateway-key sent: True

Actual Results

authorization sent: True
x-gateway-key sent: False

The client has been built this way since the move to the openai SDK in #1194. A fix is to pass them to client.realtime.connect as extra_headers, which every openai 3.x release adds to the handshake (the client's default_headers only get there in later 3.x releases, not in 3.0.0). I have it ready with a test and will open a PR.

Versions

  • OS: macOS 26.4.1 (arm64)
  • Python 3.13.16
  • openai 3.46.0
  • PyRIT main (5abca11)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions