C.W.K.
Stream
Lesson 03 of 04 · published

The Locked Door

~12 min · auth, delegation, cookies, gating

Level 0Open Gate
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Keep doesn't hold the key to itself. It asks the brain to check you in, then hands you a wristband that only works on this machine, for a week."

Keep stores no PIN

The front door is a PIN, but here's the twist: Keep stores no PIN of its own. It delegates PIN verification to cwkPippa over loopback. When you enter the PIN, Keep asks cwkPippa "is this right?" on the local machine, and cwkPippa answers. Keep never holds the secret. That's a deliberate boundary — the one system that owns identity (cwkPippa) also owns the credential check, and Keep, the finance surface, is kept out of the secret-storage business entirely. One fewer place the PIN lives is one fewer place it can leak.

The wristband: an IP-bound, time-bound cookie

A successful check mints a session cookie with several deliberate properties. It's HMAC-signed (tamper-evident — you can't forge or edit it), IP-bound (it only works from the address it was issued to, so a stolen cookie is useless elsewhere), seven-day (it expires, so access isn't permanent), HttpOnly (JavaScript can't read it, blunting theft via script injection), and SameSite=Strict (it won't ride along on cross-site requests, blocking a class of CSRF). Each attribute closes a specific attack; together they make the wristband hard to steal and useless if stolen.

Delegate secret-checking to the system that owns the secret; hand back a narrowly-scoped token. The surface that needs a gate shouldn't also store the credential — let the identity owner verify, and issue the requesting surface a token bounded in time, in binding, and in reach. Fewer copies of the secret and a tightly-scoped session beat a credential stored in every app that needs one.

The HTTP/HTTPS split most people miss

Keep is reachable two ways: plain HTTP on the LAN/tailnet, and HTTPS via Tailscale Serve. Here's a subtle trap the design handles: browser cookies are scoped by hostname, not by port. So a naive cookie for the HTTP port and one for the HTTPS port would share a name and silently overwrite each other, letting a less-secure session replace a more-secure one. Keep uses separate cookie names for HTTP and HTTPS precisely so the two sessions can't clobber each other. And the HTTPS session gets the Secure flag (via the trusted loopback proxy header) while HTTP can't — so the more-secure path is genuinely more secure, not accidentally downgraded.

The shell is public; the data is gated. The static PWA shell stays reachable so it can render the lock screen — you need to load the app to log into it. But every financial API, compatibility alias, and WebSocket is gated behind the session. Only health, session status, PIN verification, and non-data-bearing static assets are public. The walls let you walk up to the door and see it's locked; they don't let you see inside.

Code

Delegate the check; issue a tightly-scoped cookie (illustrative)·python
def login(pin, request):
    # Keep stores NO pin — it asks cwkPippa on loopback to verify.
    if not cwkpippa_verify_pin_loopback(pin):
        raise HTTPException(401)

    # Mint a session wristband, scoped every way that matters.
    token = hmac_sign({"ip": client_ip(request), "exp": now() + days(7)})
    is_https = request_is_https(request)   # via trusted loopback proxy header
    set_cookie(
        # Separate names: cookies are HOST-scoped, not port-scoped, so
        # the HTTP and HTTPS sessions must not share a name and clobber.
        name="keep_sess_https" if is_https else "keep_sess_http",
        value=token,
        http_only=True, same_site="Strict",
        secure=is_https,                   # only the HTTPS path is Secure
    )

External links

Exercise

For an app you know, sketch a session cookie and annotate each attribute (HttpOnly, SameSite, Secure, expiry, any binding) with the specific attack it defends against. Then handle the subtle case: if the app is reachable on two ports of the same host, why might the cookies collide, and how do you prevent one session from silently replacing the other? Finally, decide what stays public (so the login screen loads) versus what must be gated.
Hint
Each cookie attribute maps to a threat: HttpOnly vs script theft, SameSite vs CSRF, Secure vs plaintext interception, expiry vs permanent access, IP-binding vs cookie replay elsewhere. The port gotcha: cookies key on hostname, not port, so same-host different-port sessions need distinct names or they overwrite. And the shell must be public enough to render 'please log in' while every data path stays locked.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.