Skip to content

[oh-tab-h3g] Security: drop session_api_key from RemoteConversation WS URL#873

Open
enyst wants to merge 2 commits intodevelopfrom
blackcat/oh-tab-h3g-remove-ws-url-secret
Open

[oh-tab-h3g] Security: drop session_api_key from RemoteConversation WS URL#873
enyst wants to merge 2 commits intodevelopfrom
blackcat/oh-tab-h3g-remove-ws-url-secret

Conversation

@enyst
Copy link
Copy Markdown
Owner

@enyst enyst commented Jan 22, 2026

Fixes oh-tab-h3g.

  • Removes session_api_key from the RemoteConversation WebSocket URL query string (prevents URL secret leakage).
  • Removes the legacy 401/403 retry path that reintroduced session_api_key into the WS URL.
  • Adds unit test coverage asserting the WS URL contains no session_api_key or key material.

Notes

  • Runtime-key agent servers must support WS auth via headers (for example X-Session-API-Key or Authorization: Bearer ...).
  • This change intentionally keeps session secrets out of WS URLs; there is no query-string fallback.

Open with Devin

Summary by CodeRabbit

  • Refactor

    • WebSocket authentication now uses headers exclusively; legacy URL query parameter fallback and retry behavior removed.
  • Tests

    • Tests updated to assert header-based WS auth, to ensure no session key appears in WS URLs, and to capture error emission on failed handshakes.
  • Documentation

    • Quickstart/WS docs updated to reflect header-only authentication (X-Session-API-Key or Bearer).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b133ea78-1358-4f80-84da-bc7b6617834f

📥 Commits

Reviewing files that changed from the base of the PR and between a21260b and 04137c2.

📒 Files selected for processing (2)
  • packages/agent-sdk/src/sdk/__tests__/remoteConversation.test.ts
  • packages/agent-sdk/src/sdk/conversation/RemoteConversation.ts
💤 Files with no reviewable changes (1)
  • packages/agent-sdk/src/sdk/conversation/RemoteConversation.ts

📝 Walkthrough

Walkthrough

This PR removes legacy WebSocket query-parameter authentication (session_api_key) and enforces header-based WebSocket authentication (X-Session-API-Key or Bearer). Tests and docs were updated to validate header-only WS auth and to stop retrying with session_api_key on 403 errors.

Changes

Cohort / File(s) Summary
WebSocket Authentication Refactor
packages/agent-sdk/src/sdk/conversation/RemoteConversation.ts
Removed legacy session_api_key-in-URL auth and all related helpers/flags; WS connections now always use header-based auth (runtimeSessionApiKey or cloudApiKey). Removed retry/fallback that attempted query-based auth on WS errors.
Tests (WS auth expectations & error handling)
packages/agent-sdk/src/sdk/__tests__/remoteConversation.test.ts
Added helper to extract WS headers (getEventWSHeaders); updated assertions to require X-Session-API-Key header and to assert absence of session_api_key in URL; reworked 403-handshake test to expect an error emission and no fallback WS with session_api_key.
Documentation
tests/e2e/AGENT_SERVER_QUICKSTART.md
Updated quickstart to reflect header-only WebSocket authentication (X-Session-API-Key or Bearer) instead of appending ?session_api_key= to the WS URL.

Sequence Diagram(s)

sequenceDiagram
    participant Client as RemoteConversation
    participant WS as WebSocket
    participant Server as Agent Server
    rect rgba(200,200,255,0.5)
    Client->>WS: Open WS connection (no session_api_key in URL)\nInclude header: X-Session-API-Key or Authorization: Bearer
    WS->>Server: WS handshake with headers
    Server-->>WS: 101 / 403 (handshake)
    note right of WS: On 403 -> propagate error to Client\n(no retry with session_api_key-in-URL)
    WS-->>Client: handshake result / error event
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

codex

Poem

🐰 I hopped through headers, left query strings behind,
No more trailing keys in URLs to find.
A tidy handshake, clean and bright,
Errors reported, no secret flight.
Hop on, new auth — headers take the night! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main security change: removing session_api_key from the WebSocket URL in RemoteConversation, which aligns with the primary objective of preventing URL secret leakage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch blackcat/oh-tab-h3g-remove-ws-url-secret
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @enyst, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a critical security improvement by refactoring how the session_api_key is transmitted during WebSocket connections. By removing the key from the URL query string and shifting its handling to request headers, the change significantly reduces the risk of sensitive information exposure. This update is accompanied by new test cases to ensure the integrity of the new authentication mechanism and has a dependency on a related backend change for full functionality.

Highlights

  • Security Enhancement: The session_api_key is no longer included in the WebSocket URL query string, mitigating potential security risks associated with URL secret leakage.
  • Test Coverage: New unit tests have been added to remoteConversation.test.ts to explicitly verify that the WebSocket URL does not contain the session_api_key or any related key material.
  • Authentication Method Shift: The session_api_key is now expected to be handled via headers, requiring corresponding backend support for non-cloud servers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses a security vulnerability by removing the session_api_key from the WebSocket URL's query string and moving it to the X-Session-API-Key header. The changes in RemoteConversation.ts correctly remove the logic that added the key to the URL. The existing getAuthHeaders method already handles adding the key to headers, which is now leveraged by the WebSocket connection logic. The pull request also includes excellent test coverage: the MockWS class in remoteConversation.test.ts is updated to allow inspection of connection options (like headers), and a new test case is added to assert that the session_api_key is absent from the URL and correctly placed in the request headers. The changes are clean, targeted, and effectively mitigate the risk of leaking secrets through URLs. The implementation is solid.

@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Jan 22, 2026

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • E2E (Agent-Server)

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #873 at branch `blackcat/oh-tab-h3g-remove-ws-url-secret`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

@enyst
Copy link
Copy Markdown
Owner Author

enyst commented Jan 24, 2026

✅ PinkCat Review: LGTM

Taste Rating: 🟢 Good taste - Critical security fix

This PR addresses bead oh-tab-h3g - the secret-in-URL security issue.

Security Impact:

  • Before: wss://server/sockets/events/123?session_api_key=SECRET
  • After: wss://server/sockets/events/123?resend_all=true + X-Session-API-Key header

This eliminates URL logging, browser history, and referrer leakage vectors.

Ready to merge (pending upstream #1786 for production use).

@enyst
Copy link
Copy Markdown
Owner Author

enyst commented Mar 15, 2026

@OpenHands Look at this PR diff, understand that we renamed the agent-sdk package, and re-apply the fixes in this PR on clean main so we can review and merge this PR

Mark it ready for review when you verify that it has all we wanted; monitor it then for some 5 mins then use gh to check for AI reviews that will be posted; read both top and inline review threads and address them as you see fit. They are AI so maybe they're wrong, you need to validate first and think if it needs fixed.

@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Mar 15, 2026

I'm on it! enyst can track my progress at all-hands.dev

@enyst enyst force-pushed the blackcat/oh-tab-h3g-remove-ws-url-secret branch from e38540b to b8d7d5a Compare March 15, 2026 20:18
Port the original security fix onto current develop after the agent-sdk package rename. Keep runtime session keys in WebSocket headers only, remove the legacy query-string fallback, and tighten the RemoteConversation tests around URL-secret leakage.

Co-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst force-pushed the blackcat/oh-tab-h3g-remove-ws-url-secret branch from b8d7d5a to a21260b Compare March 15, 2026 20:19
@enyst enyst marked this pull request as ready for review March 15, 2026 20:20
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Mar 15, 2026

Since my last summary, there have been no further code changes or pushes.

Current final state:

Checklist:

  • Re-applied the intended WS URL secret fix on the renamed packages/agent-sdk/... paths
  • Kept the changes concise: only 3 repo files changed in the final commit
  • Removed an extraneous AGENTS.md change before finalizing
  • Updated the PR description to match the current implementation
  • Pushed the final branch state to the remote PR branch
  • Marked the PR ready for review
  • Monitored for AI reviews and validated the feedback

Remaining blocker:

  • agent-server-e2e is still failing in CI
  • Based on the logs, the failure is a POST /api/conversations HTTP 422 from upstream agent-server main, which appears separate from the WS URL secret fix

So: the requested PR-porting/review-readiness work is complete, the diff is concise, and the only unresolved item is the newly surfaced CI incompatibility.

@github-actions
Copy link
Copy Markdown

🔧 VSCode Extension Built Successfully

• File: openhands-tab-0.9.0.vsix (545 KB)
• Download: https://github.com/enyst/OpenHands-Tab/actions/runs/23120227174

To install:

  1. Download the artifact from the run page above
  2. VS Code → Command Palette → "Extensions: Install from VSIX..."
  3. Select the downloaded .vsix

Built with Node 22. Commit 0249bd4.

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.

1 participant