Conversation
Add a proper logout path for deployments with HERMES_PASSWORD enabled: - server: DELETE /api/auth revokes the claude-auth session token and returns a Max-Age=0 Set-Cookie with matching attributes. Idempotent (returns ok even without a valid token) and rejects cross-site requests via Sec-Fetch-Site (defense in depth alongside SameSite=Strict). - auth-middleware: clearSessionCookie() helper + revokeSessionToken() only persists when a token was actually removed (avoids needless I/O). - UI: Sign out item in the desktop sidebar user menu and a sign-out button in the mobile hamburger drawer, shown only when auth is required. - tests: clearSessionCookie coverage (Secure default + COOKIE_SECURE=0).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add logout endpoint (DELETE /api/auth) + Sign out button
Problem
Hermes Workspace with
HERMES_PASSWORDenabled has no way to sign out. The only auth route isPOST /api/auth(login); there is no logout endpoint and no UI affordance. Users must manually clear theclaude-authcookie or wait for the 30-day TTL to expire.This matters for shared/borrowed devices and for deployments behind an upstream IdP (e.g. OIDC) where the workspace password is a second factor — after finishing a session there is no clean way to end it.
Changes
src/server/auth-middleware.ts: addclearSessionCookie()— emits aMax-Age=0Set-Cookie with the same attributes ascreateSessionCookie()(HttpOnly, Secure perCOOKIE_SECURE, SameSite=Strict, Path=/), so browsers accept the deletion.src/routes/api/auth.ts: addDELETE /api/authhandler — extracts theclaude-authtoken from the cookie, revokes it viarevokeSessionToken(), and returns the clearing Set-Cookie. Idempotent: returns{ok:true}even when no valid token is present.src/components/workspace-shell.tsx: addhandleLogout(DELETE + reload) and a "Sign out" button in the sidebar footer, shown only whenauthRequired && authenticated.Verification
pnpm buildpasses.pnpm vitest run src/server/auth-middleware.test.ts— 8/8 pass.DELETE /api/auth→ Set-Cookieclaude-auth=; Max-Age=0→ old cookie now 401.Notes
SameSite=Strict; the existing login POST usesrequireJsonContentTypeas an extra guard, but DELETE has no body by design. SameSite=Strict blocks cross-site DELETE from browsers.Fixes #790