feat(self-host): local console sign-in without Cloudflare Access - #113
Merged
Conversation
…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.
…auth # Conflicts: # admin/src/ui-helpers.ts
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
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. |
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.
Supersedes #106 while preserving @b3nw's two contributor commits and credit.
Summary
CLAWROUTER_PUBLIC_ORIGIN, validated at container startup, and require forwarded host/protocol to reconstruct that exact origin before trusting the proxy boundaryVerification
pnpm worker:check— 145 tests passedpnpm --dir admin check— passedpnpm --dir admin test— 29 tests passedpnpm test:scripts— 78 tests passedorigin/main— cleanLive Docker proof used the built self-host image behind a separate Caddy 2.10.2 container with a self-signed certificate:
Secure,HttpOnly,SameSite=LaxOrigin: https://evil.examplelogin returned 403 /access_csrf_requiredDeployment 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.