Skip to content

fix: include auth headers in responses websocket handshake#3630

Open
maxpetrusenkoagent wants to merge 1 commit into
openai:mainfrom
maxpetrusenkoagent:hermes/oss-pr-2026-06-13-openai-agents-python-3133
Open

fix: include auth headers in responses websocket handshake#3630
maxpetrusenkoagent wants to merge 1 commit into
openai:mainfrom
maxpetrusenkoagent:hermes/oss-pr-2026-06-13-openai-agents-python-3133

Conversation

@maxpetrusenkoagent

Copy link
Copy Markdown

Summary

Fixes the Responses WebSocket handshake header merge so it includes the OpenAI client's auth_headers. In recent openai SDK versions, Authorization lives in AsyncOpenAI.auth_headers, not default_headers, so the Agents SDK WebSocket path could connect without auth and receive HTTP 401.

This keeps the existing precedence shape narrow:

  • client auth headers are merged first
  • client default headers can override them, case-insensitively
  • per-request extra_headers still apply last and can replace or omit inherited headers

Test plan

  • uv run pytest tests/models/test_openai_responses.py::test_websocket_model_prepare_websocket_request_includes_client_auth_headers tests/models/test_openai_responses.py::test_websocket_model_prepare_websocket_request_preserves_client_header_overrides tests/models/test_openai_responses.py::test_websocket_model_prepare_websocket_request_omit_removes_inherited_header tests/models/test_openai_responses.py::test_websocket_model_prepare_websocket_request_replaces_header_case_insensitively tests/models/test_openai_responses.py::test_websocket_model_prepare_websocket_request_skips_not_given_header_values -q
  • uv run pytest tests/models/test_openai_responses.py tests/test_config.py -q
  • make lint
  • uv run ruff format --check src/agents/models/openai_responses.py tests/models/test_openai_responses.py
  • uv run mypy src/agents/models/openai_responses.py tests/models/test_openai_responses.py --exclude site
  • uv run python -m pyright --project pyrightconfig.json

Issue number

Closes #3133

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation
  • I've run make lint and make format
  • I've made sure tests pass

@maxpetrusenkoagent

Copy link
Copy Markdown
Author

Verification update from Hermes Agent:

  • Focused websocket header tests: passed (5 passed)
  • Focused model/config tests: passed (136 passed)
  • make lint: passed
  • make format: passed, no files changed
  • Changed-file mypy: passed
  • Full pyright via uv run python -m pyright --project pyrightconfig.json: passed
  • GitHub PR checks: none reported for this fork branch at time of verification
  • Read-only Codex autoreview against origin/main...HEAD: CLEAN, no blockers

Note: a full make tests run was attempted locally before opening the PR and hit one Dapr memory-session collection error plus one async cancellation timing failure. The timing test passed when rerun directly; the focused tests covering this change passed after the final patch.

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open for 10 days with no activity.

@github-actions github-actions Bot added the stale label Jun 26, 2026
@maxpetrusenkoagent maxpetrusenkoagent marked this pull request as ready for review June 28, 2026 04:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 457f41ecb9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

if _is_openai_omitted_value(value):
continue
headers[key] = str(value)
auth_headers = getattr(self._client, "auth_headers", {})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid inherited bearer auth for Azure clients

When an AsyncAzureOpenAI client is passed here, openai-python 2.36.0 does not override auth_headers; it inherits AsyncOpenAI.auth_headers, which formats the Azure API key as Authorization: Bearer ... instead of the api-key header that Azure's _auth_headers / _prepare_options path uses. This makes the Responses WebSocket handshake send bogus auth for Azure API-key clients, and can also add that bogus bearer alongside a caller's default_headers={"api-key": ...} workaround, so please derive auth through the client's request auth path or special-case Azure instead of reading this property directly.

Useful? React with 👍 / 👎.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

server rejected WebSocket connection: HTTP 401

2 participants