OpenHands / OpenHands/software-agent-sdk

[Bug]: workspace files return 401 on private-LAN HTTP because the session cookie is rejected

Open Beginner friendly
#4,562 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug priority:medium ready-for-dev release-note-required security-related session
Dominant language
Python
Stars
1.1k
Forks
539
Avg merge
1d 19h
Merged PRs (30d)
137

Description

Is there an existing issue for the same bug?
  • I have searched existing issues and this is not a duplicate.
Bug Description

The workspace-session endpoint emits a cookie with SameSite=None but without Secure when the Agent Server is accessed over plain HTTP through a non-loopback host, such as a private LAN IP.

Browsers reject SameSite=None cookies unless Secure is also present. Because Secure cookies cannot be used over plain HTTP on a non-loopback host, the browser drops the workspace cookie. Embedded and direct workspace file requests then return 401 even after POST /api/auth/workspace-session succeeds.

This affects same-origin deployments where the UI and Agent Server are served from the same private-LAN HTTP origin. Cross-site embedding should continue to require HTTPS.

Expected Behavior

For a non-loopback plain-HTTP request, the Agent Server should emit a browser-compatible same-site cookie using SameSite=Lax, without Secure or Partitioned. HTTPS and loopback secure contexts should continue to emit SameSite=None; Secure; Partitioned for cross-site iframe support.

Actual Behavior

The response currently contains a cookie equivalent to:

oh_workspace_session_key=...; HttpOnly; Path=/api/conversations; SameSite=none

The browser rejects it. A later request to /api/conversations/{conversation_id}/workspace/README.md has no workspace cookie and returns 401.

On current main, uv run pytest -q tests/agent_server/test_workspace_cookie_auth.py::test_mint_session_over_remote_plain_http_uses_lax_cookie fails because the response contains SameSite=none instead of SameSite=lax.

Steps to Reproduce
  1. Run openhands-agent-server with a session API key and expose it over plain HTTP on a private-LAN address, for example http://192.168.1.10:8000.
  2. Serve or proxy the client UI from that same origin.
  3. Call POST /api/auth/workspace-session with a valid X-Session-API-Key header and credentials enabled.
  4. Inspect the Set-Cookie response in browser developer tools.
  5. Request /api/conversations/{conversation_id}/workspace/README.md without the custom header, as an iframe/image/navigation would.
  6. Observe that the browser discarded the cookie and the workspace request returns 401.

A focused regression test on current main also demonstrates the server-side defect:

assert "SameSite=lax" in set_cookie
AssertionError: assert 'SameSite=lax' in '...; SameSite=none'
Acceptance Criteria
  • Non-loopback plain-HTTP workspace-session responses use SameSite=Lax without Secure or Partitioned.
  • HTTPS workspace-session responses retain SameSite=None; Secure; Partitioned.
  • Plain-HTTP loopback responses retain the existing secure-context behavior.
  • Workspace cookie authentication continues to be scoped to workspace routes.
  • Agent Server workspace-cookie tests pass.
Installation Method

uvx --from openhands-agent-server==1.42.1 (also reproduced from a source checkout)

SDK Version

openhands-agent-server 1.42.1; reproduced on OpenHands/software-agent-sdk main at 1de2e6d1bfcf70c7c3d4eb13616811943f33dd75

Version Confirmation
  • I have confirmed this bug exists on the latest main branch.
Python Version

Python 3.13.5 in the source checkout; originally observed with Python 3.14.

Model Name (if applicable)

Not applicable.

Operating System

Linux

Logs and Error Messages
Failed to read README.md: 401
Minimal Code Sample

The failing test can be added to tests/agent_server/test_workspace_cookie_auth.py by asserting that a mint request with Host: agent.example.com uses SameSite=lax when the request scheme is HTTP.

Screenshots and Additional Context

The existing secure-context logic correctly distinguishes HTTPS/loopback from remote HTTP. The minimal fix is to choose the SameSite attribute from that same decision: none for secure contexts and lax otherwise. This preserves cross-site iframe support where browsers allow it while making same-origin LAN HTTP deployments functional.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tests/agent_server/test_workspace_cookie_auth.py and run test_mint_session_over_remote_plain_http_uses_lax_cookie to reproduce the failure. Trace the workspace-session cookie logic and its existing secure-context handling. Done means remote plain HTTP uses SameSite=Lax without Secure or Partitioned, while HTTPS and loopback behavior remain unchanged and the workspace-cookie tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, authentication, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.