Skip to content

Use saved hx OAuth session when no API key is provided - #113

Open
shrisukhani wants to merge 4 commits into
mainfrom
use_hx_creds
Open

Use saved hx OAuth session when no API key is provided#113
shrisukhani wants to merge 4 commits into
mainfrom
use_hx_creds

Conversation

@shrisukhani

@shrisukhani shrisukhani commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

If no API key is set, the client now falls back to a saved hx auth login session so local/dev usage can authenticate without embedding HYPERBROWSER_API_KEY. API-key auth is unchanged and still wins when provided.

Changes

  • Resolve control-plane auth from api_key / HYPERBROWSER_API_KEY, or ~/.hx_config/auth/<profile>.json
  • Refresh OAuth tokens against the frontend host (https://app.hyperbrowser.ai or HYPERBROWSER_FRONTEND_URL), with 401 retry for replayable requests
  • Keep per-request timeout= and the 1.0 TypedDict managers
  • Profile selection via profile=, HYPERBROWSER_PROFILE, or ClientConfig(profile=...)
  • Empty HYPERBROWSER_API_KEY is treated as unset; explicit api_key="" still errors
  • ClientConfig.from_env() still requires an API key

Validation

  • ruff check .
  • pytest tests --ignore=tests/sandbox/e2e --ignore=tests/test_typing_contract.py (176 passed)
  • pytest tests/integration (10 passed)
  • Rebased onto current main

Note

High Risk
This changes how every control-plane request is authenticated (new OAuth refresh, locks, and 401 retry paths) and relaxes the previous hard requirement for an API key at client construction.

Overview
When no API key is provided, the client can authenticate from a saved hx auth login session at ~/.hx_config/auth/<profile>.json, with profile / HYPERBROWSER_PROFILE / ClientConfig(profile=...). API keys still take precedence; ClientConfig.from_env() still requires HYPERBROWSER_API_KEY.

A new control_auth layer resolves API key vs OAuth, refreshes tokens against the frontend host (HYPERBROWSER_FRONTEND_URL / ClientConfig(frontend_url=...)), uses file locks for concurrent refresh, and persists updated sessions atomically. Sync/async transports attach auth per request (x-api-key or Bearer), retry 401 with refresh for replayable calls, and route sandbox control HTTP through send_authenticated. Path-based session uploads read bytes up front so OAuth retries can replay the body.

Reviewed by Cursor Bugbot for commit 0d60c10. Bugbot is set up for automated code reviews on this repo. Configure here.

Fall back to a saved hx OAuth session when no API key is set, refresh tokens against the frontend host, and retry replayable 401s.
Route sandbox control-plane calls through authenticated transport, stop re-reading env after config is resolved, and harden session refresh, lock handling, and ClientConfig compatibility.
Always refresh on 401, cache tokens in memory, run async auth off the event loop, and stop deleting sessions or locks owned by another process.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fa10ca2. Configure here.

Comment thread hyperbrowser/control_auth.py Outdated
A refresh response that issues a new refresh_token without
refresh_token_expires_in no longer inherits the previous token's
lifetime. That leftover expiry could make a still-valid session look
expired and force another hx auth login.

Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
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.

2 participants