Skip to content

feat(self-host): local console sign-in without Cloudflare Access - #113

Merged
steipete merged 4 commits into
mainfrom
feat/self-host-local-auth
Aug 16, 2026
Merged

feat(self-host): local console sign-in without Cloudflare Access#113
steipete merged 4 commits into
mainfrom
feat/self-host-local-auth

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Supersedes #106 while preserving @b3nw's two contributor commits and credit.

Summary

  • add opt-in local admin-token sessions and the self-host console sign-in screen from feat(self-host): local console sign-in without Cloudflare Access #106
  • add an operator-declared CLAWROUTER_PUBLIC_ORIGIN, validated at container startup, and require forwarded host/protocol to reconstruct that exact origin before trusting the proxy boundary
  • centralize browser origin validation across login, logout, admin, playground, and self-service credential writes
  • reserve per-client and global login capacity synchronously before request parsing or hashing so concurrent attempts cannot bypass either cap
  • document the reverse-proxy contract and credit @b3nw in the changelog

Verification

  • pnpm worker:check — 145 tests passed
  • pnpm --dir admin check — passed
  • pnpm --dir admin test — 29 tests passed
  • pnpm test:scripts — 78 tests passed
  • autoreview of the improvement patch — clean
  • autoreview of the complete branch against origin/main — clean

Live Docker proof used the built self-host image behind a separate Caddy 2.10.2 container with a self-signed certificate:

  • TLS 1.3 negotiated and the dashboard returned 200 over HTTPS
  • correct-token sign-in returned 200 and set Secure, HttpOnly, SameSite=Lax
  • the authenticated session reported local admin access
  • logout returned 200, cleared the cookie, and the prior cookie then returned 401
  • a forged Origin: https://evil.example login returned 403 / access_csrf_required
  • 100 concurrent wrong-token attempts with distinct spoofed client addresses produced exactly 50×401 and 50×429
  • a container started with a path-bearing public origin exited 1 with the fail-closed validation error

Deployment status

Not deployed. This PR changes the Docker/workerd self-host profile and remains opt-in; Cloudflare Access configuration continues to take precedence and disables local auth.

Remaining risk

The login counters are process-local by design for the documented single-workerd self-host profile. A future multi-process self-host topology would need a shared limiter authority before it could claim the same global cap across processes.

b3nw and others added 4 commits July 18, 2026 22:53
…e Access

Add an opt-in local-auth mode for the Docker/workerd profile: POST
/v1/session/login exchanges the admin token for a rate-limited, KV-backed
12-hour session cookie (HttpOnly, SameSite=Lax) that verifiedAccessSession
resolves alongside Cloudflare Access. Sessions honor live user-record state
(disable, delete, or demote revokes); sign-in failures are capped per client
and globally since client addresses are spoofable on a bare workerd host; the
Secure cookie flag follows x-forwarded-proto for TLS-terminating proxies. The
dashboard shell serves unauthenticated in local mode; logout revokes the
stored session. Off by default: the self-host entrypoint validates
CLAWROUTER_LOCAL_AUTH at startup and only activates on an explicit
"enabled", and the Worker refuses local auth whenever Cloudflare Access
variables are configured. The bearer-token admin fallback session is now
labeled admin_token instead of cloudflare_access.
When the session bootstrap fails with access_session_required and the
service index advertises /v1/session/login, the console renders a sign-in
form instead of falling back to localhost demo data. Successful sign-in
re-runs the normal refresh; the session cookie itself stays HttpOnly and
invisible to the SPA.
@clawsweeper

clawsweeper Bot commented Aug 16, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper

clawsweeper Bot commented Aug 16, 2026

Copy link
Copy Markdown

ClawSweeper status: review started.

I am starting a fresh review of this pull request: feat(self-host): local console sign-in without Cloudflare Access This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@steipete
steipete merged commit 31644e1 into main Aug 16, 2026
8 checks passed
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