Skip to content

NMichael111/life

Repository files navigation

Life

CI

A zero-knowledge personal life organizer. It stores notes, tasks, projects, friends, events, daily goals, and sleep tracking, all encrypted in the browser before anything reaches the server.

The server stores ciphertext and an OPAQUE registration record. It cannot read the vault, even with full disk access.

Requesting an account

Enrollment is invite-only. To request access, email nmichael111@atomicmail.io with your desired username. You'll receive a single-use enrollment link (24 hour TTL) that lets you set your password directly in the browser.

Features

  • Notes, tasks (with drag-set progress), projects, friends, events, daily goals, sleep tracking. Each entity has its own modal and surfaces on a unified bento-grid dashboard.
  • Per-friend hangout log with photo support and birthday tracking. Friends, projects, and tasks can be cross-linked.
  • Vault-wide JSON export and import for offline backup. The export is plaintext (the user's responsibility to store safely); the import re-encrypts under the current key.
  • Optional weather tile that fetches forecasts directly from Open-Meteo using coarse coordinates (rounded to about 11 km) stored encrypted in the vault. The server is never involved.
  • Strict CSP with hash-pinned inline scripts. No unsafe-inline, no unsafe-eval. All inline scripts are SHA-256 hashed at build time.
  • Atomic deploys. The included bin/deploy.ts typechecks the client and server, rsyncs, builds in place, swaps client/build behind a one-second service stop, and verifies with both a loopback health check and a Playwright smoke test.

How it works

Browser                              Server                  Storage
-------                              ------                  -------
SvelteKit 5 SPA                      Bun HTTP                CouchDB
  OPAQUE client    <- RFC 9807 ->    OPAQUE server
  AES-256-GCM
  CBOR + gzip      ciphertext  ->    couch proxy   ->        single
                                     (allowlisted)           doc per
                                                             user

Authentication uses OPAQUE (RFC 9807) via @cloudflare/opaque-ts. The server never receives the password, not even at registration. The stored record is not a password hash. Cracking it requires the password.

The vault itself is one encrypted blob per user. The pipeline is object -> CBOR -> gzip -> AES-256-GCM -> base64. The AES key is derived from OPAQUE's export_key and never transmitted.

Enrollment is invite only. The operator runs a CLI to mint a single-use token with a 24 hour TTL. The on-disk filename is the SHA-256 of the token, so a directory listing cannot be replayed. The /enroll endpoint is byte-identical to any other unknown path for clients that do not already have a token.

Transport is HTTPS via Caddy. The CSP pins inline scripts by SHA-256 hash. There is no unsafe-inline and no unsafe-eval.

See SECURITY.md for the threat model.

Stack

Development

bun install
bun run dev        # couch + server + client concurrently

Typecheck:

cd server && bunx tsc --noEmit
cd client && bunx svelte-kit sync && bunx svelte-check

Tests:

bun test client/tests

Production build:

bun run build

The build emits a static SvelteKit bundle in client/build/ and a single-file enroll.html for OPAQUE registration. The inline script in enroll.html is hash-pinned in the server CSP.

Deployment

Deploys are atomic. bin/deploy.ts runs typechecks locally, rsyncs the source to the target host, builds in place, swaps client/build behind a service stop, restarts, and runs both a loopback health check and a Playwright smoke test against the public URL. Any failure aborts before the swap.

Performance

bench/results.md has measurements of the full save and load pipelines at four fixture sizes. Reproduce with bun run bench.

Project layout

client/              SvelteKit 5 SPA
  src/lib/
    components/      UI (tiles, modals, dashboard)
    stores/          auth and nav state
    vault/           types, serialize, crypto, sync, photo
    crypto/          OPAQUE client wrappers

server/              Bun API and CouchDB proxy
  src/
    routes/          auth, enroll
    services/        opaque-config, enrollment, user-service,
                     couch-admin, jwt, rate-limit, http
  bin/               operator CLIs (init-opaque, start-enrollment,
                     delete-user, build-enroll)
  enroll-src/        standalone enrollment page source

bin/                 deploy and smoke-test tooling
bench/               vault-pipeline benchmark

About

Zero-knowledge personal life vault. OPAQUE auth, client-side AES-GCM, Bun + SvelteKit 5.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors