Skip to content

feat: two auth modes — local (auto-key) and public (paste-key)#790

Draft
malhotra5 wants to merge 1 commit into
mainfrom
feat/auth-modes
Draft

feat: two auth modes — local (auto-key) and public (paste-key)#790
malhotra5 wants to merge 1 commit into
mainfrom
feat/auth-modes

Conversation

@malhotra5
Copy link
Copy Markdown
Member

@malhotra5 malhotra5 commented May 26, 2026

  • A human has tested these changes.

Why

Right now agent-canvas always auto-generates a session API key and bakes it into VITE_SESSION_API_KEY at build time. This is fine for localhost, but dangerous for VM deployments — anyone who can reach the frontend controls the computer, and the key is visible in the JS bundle.

We need two distinct auth modes:

  • Fast (localhost): zero-setup, key auto-bundled via /backends.json
  • Secure (public/VM): user must provide LOCAL_BACKEND_API_KEY and paste it into the frontend

Summary

  • Local mode (agent-canvas, no flags): ingress binds to 127.0.0.1, auto-generates a session API key, writes it to /backends.json so the frontend auto-authenticates — zero setup.
  • Public mode (agent-canvas --public): ingress binds to 0.0.0.0, requires LOCAL_BACKEND_API_KEY env var, does NOT write /backends.json. Frontend shows a full-screen API key entry screen when /server_info returns 401.
  • Static builds no longer bake VITE_SESSION_API_KEY — keys are injected at runtime via /backends.json.

How to Test

Local mode:

npx @openhands/agent-canvas
# → Should open on http://localhost:8000 with no auth prompt
# → /backends.json should be served with the auto-generated key

Public mode:

LOCAL_BACKEND_API_KEY=my-secret npx @openhands/agent-canvas --public
# → Should listen on 0.0.0.0:8000
# → Frontend should show API key entry screen
# → Pasting "my-secret" should connect successfully

Missing key in public mode:

npx @openhands/agent-canvas --public
# → Should fail immediately with a clear error message

Help text:

npx @openhands/agent-canvas --help
# → Should show both modes documented

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

  • Session API key resolution in the frontend is now 3-tier: (1) localStorage override → (2) runtime /backends.json → (3) build-time VITE_SESSION_API_KEY
  • Docker entrypoint also writes /backends.json for auto-auth (Docker always auto-generates keys)
  • The API key entry screen uses isAuthenticationError() to detect 401s, so it only shows when the server actually requires auth — standalone agent-servers without auth still work fine
  • i18n: 4 new keys (AUTH$API_KEY_REQUIRED_TITLE, AUTH$API_KEY_REQUIRED_DESCRIPTION, AUTH$API_KEY_PLACEHOLDER, AUTH$CONNECT) with all 15 languages
  • All 2619 tests pass, TypeScript compiles clean, ESLint + Prettier pass

This PR was created by an AI agent (OpenHands) on behalf of the user.

@malhotra5 can click here to continue refining the PR


🐳 Docker images for this PR

GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.23.1-python
Automation openhands-automation==1.0.0a5
Commit 092e0bf9d1305839d57b965c5ce83d55408d1318

Pull (multi-arch manifest)

# Multi-arch manifest — Docker automatically pulls the correct architecture
docker pull ghcr.io/openhands/agent-canvas:sha-092e0bf

Run

docker run -it --rm \
  -p 8000:8000 \
  ghcr.io/openhands/agent-canvas:sha-092e0bf

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-092e0bf-amd64
ghcr.io/openhands/agent-canvas:feat-auth-modes-amd64
ghcr.io/openhands/agent-canvas:pr-790-amd64
ghcr.io/openhands/agent-canvas:sha-092e0bf-arm64
ghcr.io/openhands/agent-canvas:feat-auth-modes-arm64
ghcr.io/openhands/agent-canvas:pr-790-arm64
ghcr.io/openhands/agent-canvas:sha-092e0bf
ghcr.io/openhands/agent-canvas:feat-auth-modes
ghcr.io/openhands/agent-canvas:pr-790

About Multi-Architecture Support

  • Each tag (e.g., sha-092e0bf) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., sha-092e0bf-amd64) are also available if needed

@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-canvas Ready Ready Preview, Comment May 26, 2026 11:42pm

Request Review

@malhotra5
Copy link
Copy Markdown
Member Author

malhotra5 commented May 26, 2026

Public login page

image

Local mode (agent-canvas, no flags):
- Ingress binds to 127.0.0.1 only
- Auto-generates session API key
- Writes /backends.json to static dir so frontend auto-authenticates
- Zero setup for localhost use

Public mode (agent-canvas --public):
- Ingress binds to 0.0.0.0 (all interfaces)
- Requires LOCAL_BACKEND_API_KEY env var
- Does NOT write /backends.json
- Frontend shows API key entry screen on 401

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions
Copy link
Copy Markdown
Contributor

📸 Snapshot Test Report

Warning

Snapshot comparison step crashed (timeout, OOM, or runner error) — diff results below may be incomplete or absent.
Check the CI logs for the full error output (look for the "Run snapshot comparison" step).

❌ 1 snapshot differ from the main branch baseline. Add the update-snapshots label to acknowledge intentional changes.

Category Count
🔴 Changed 1
🆕 New 0
✅ Unchanged 72
Total 73

How to resolve:

  • Unintentional diffs — the baselines on main may have moved since this branch was created. Merge the latest main into this branch and re-run CI.
  • Intentional changes — add the update-snapshots label. CI will pass and the new screenshots become the baseline when this PR merges.
🔴 Changed snapshots (1)

changes-tab

changes-diff-viewer

Expected (main) Actual (PR) Diff
expected actual diff
✅ Unchanged snapshots (72)

archived-conversation

  • conversation-panel-with-archived-badges
  • conversation-view-archived
  • conversation-view-sandbox-error

automations

  • automations-delete-modal
  • automations-list-active-inactive
  • automations-no-automations
  • automations-search-no-results

backends-extended

  • backend-add-blank-disabled
  • backend-add-cloud-advanced-open
  • backend-add-cloud-no-key-disabled
  • backend-add-cloud-with-key-enabled
  • backend-add-form-partially-filled
  • backend-add-invalid-url-disabled
  • backend-add-local-ready
  • backend-add-name-only-disabled
  • backend-add-two-column-layout
  • backend-add-whitespace-host-disabled
  • backend-after-switch
  • backend-cancel-nothing-saved
  • backend-dropdown-two-backends
  • backend-edit-prefilled
  • backend-manage-after-removal
  • backend-manage-two-listed
  • backend-remove-cancelled
  • backend-remove-confirmation
  • backend-switch-overlay

backends

  • backend-add-modal
  • backend-manage-modal
  • backend-selector-open

changes-tab

  • changes-deleted-file
  • changes-empty

collapsible-thinking

  • reasoning-content-collapsed
  • reasoning-content-expanded
  • think-action-collapsed
  • think-action-expanded

mcp-page

  • mcp-custom-server-1-editor-open
  • mcp-custom-server-2-url-filled
  • mcp-custom-server-3-all-filled
  • mcp-custom-server-4-installed
  • mcp-custom-server-editor
  • mcp-empty-installed
  • mcp-search-filtered
  • mcp-slack-install-1-marketplace
  • mcp-slack-install-2-modal
  • mcp-slack-install-3-filled
  • mcp-slack-install-4-installed

onboarding

  • onboarding-step-0-choose-agent
  • onboarding-step-1-check-backend
  • onboarding-step-2-setup-llm
  • onboarding-step-3-say-hello

projects-workspace-browser

  • projects-workspace-browser

settings-page

  • add-backend-modal
  • analytics-consent-modal
  • home-screen
  • settings-app-page
  • settings-page

settings-secrets

  • secrets-add-form-filled
  • secrets-add-form
  • secrets-after-save
  • secrets-delete-confirm
  • secrets-list

settings-verification

  • condenser-settings
  • verification-settings-off
  • verification-settings-on

sidebar

  • sidebar-collapsed
  • sidebar-conversation-panel
  • sidebar-filter-menu

skills-page

  • skills-empty
  • skills-loaded
  • skills-no-match
  • skills-search-filtered
  • skills-type-filter

Generated by the Snapshot Tests workflow. This comment was created by an AI agent (OpenHands) on behalf of the repo maintainers.

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