Support username/password auth; test against containerised Hermes on hermternal-dev #1
Labels
No labels
delivered
outstanding
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
kayg/hermternal-apple#1
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The client only supports SSO today (
native_pkce). Username/password sign-inis unimplemented and, more importantly, cannot be tested against the live
instance at all.
GET https://hermes-dashboard.kayg.org/api/auth/providersreturns:POST /auth/password-loginchecksgetattr(p, "supports_password", False)andreturns 404 Unknown provider when it is false
(
hermes_cli/dashboard_auth/routes.py:680-690). So there is no way to exercisethe password path against the production gateway.
Plan
1. Stand up a password-capable Hermes
Do not rebuild from the official container docs. A launcher already exists:
~/Developer/hermternal/.claude/skills/deploy-hermes-agent/SKILL.mdIt runs the official immutable image under rootless Podman as
hermternal-test@hermternal-dev, preserves the upstream entrypoint, runsgateway run, and enables a synthetic Basic provider — precisely thepassword path we need. Expose it over Netbird so the macOS client can reach it.
2. Implement the client side
AuthClient: addPOST /auth/password-loginwith body{provider, username, password}.SignInView: add a credentials form, shown only when/api/auth/providersadvertises a provider withsupports_password: true.Keep the SSO button as the only option otherwise.
The real work: cookies vs bearer
/auth/password-logindoes not return bearer tokens. It callsset_session_cookies(...)and returns{"ok": true, "next": "/"}(
routes.py:729-739), whereas/auth/native/tokenreturns{access_token, refresh_token, expires_at, ...}in the JSON body.That asymmetry is the bulk of the effort, not the form:
CredentialStorecurrently persists a bearer pair. It needs a cookie-sessionbranch, or a common abstraction over both.
POST /api/auth/ws-ticketis authenticated by the gate; it accepts thesession cookie as well as a bearer, but the client must actually send the
cookie jar (
URLSessioncookie storage) instead of anAuthorizationheader.
/auth/native/refreshtakes a refresh token, whilecookie sessions are rotated transparently by the gate middleware. The
refresh path must not run for cookie sessions.
Acceptance
/api/auth/providersshows a providerwith
supports_password: true./api/wsreachesgateway.ready,and a chat turn streams end to end.
hermes-dashboard.kayg.orgstill works unchanged.