OpenHands / OpenHands/software-agent-sdk
[Bug]: workspace files return 401 on private-LAN HTTP because the session cookie is rejected
Nobody has claimed this yet.
- 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
- Run
openhands-agent-serverwith a session API key and expose it over plain HTTP on a private-LAN address, for examplehttp://192.168.1.10:8000. - Serve or proxy the client UI from that same origin.
- Call
POST /api/auth/workspace-sessionwith a validX-Session-API-Keyheader and credentials enabled. - Inspect the
Set-Cookieresponse in browser developer tools. - Request
/api/conversations/{conversation_id}/workspace/README.mdwithout the custom header, as an iframe/image/navigation would. - 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=LaxwithoutSecureorPartitioned. - 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
mainbranch.
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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