Skip to content

labapp

labapp is a Go web service I build against my own Kubernetes lab. Its first feature is authentication, written by hand rather than delegated to an identity provider — not because rolling your own auth is good advice, but because the point of the project is to understand the parts you normally outsource: how a password is stored, what a session actually is, and which of the defences around them matter.

These pages are the design notes. They cover what the service does, how it is put together, and — more usefully — why each security decision went the way it did and what it costs.

LanguageGo 1.27, standard library first
Statusactive — credentials, sessions, and the HTTP surface are complete and deployed
StoragePostgreSQL 17, schema applied by embedded migrations at startup
Runtimea three-node k3s cluster, behind an ingress that terminates TLS
Dependenciesgolang.org/x/crypto (argon2), jackc/pgx, pressly/goose — and nothing else

Signup, login, logout, and a “who am I” endpoint. Passwords are hashed with argon2id. Sessions are opaque random tokens stored server-side as hashes, and work as either an HttpOnly cookie or an Authorization: Bearer header, so a browser and a curl script are equally first-class. Login is rate limited per client address and per account.

Terminal window
curl -s -X POST https://labapp.example/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"a-long-password"}'
# {"token":"J4h2…","expires_at":"2026-09-09T14:27:03Z"}

Deploying Keycloak or Ory would have been the correct engineering call and the wrong learning one. Every interesting decision — how expensive to make a hash, whether a failed login should admit that the account exists, what happens to a session when a laptop is stolen — lives inside the thing an identity provider hands you finished. Writing it means those decisions have to be made explicitly, which is what these notes record.

The trade is real and worth stating plainly: this code has one reviewer and no production users. It is a study, not a recommendation.

Roughly in order of altitude — how to run it, how it is shaped, then the parts worth reading closely.

  • Getting started — toolchain, the local development loop, and the checks that gate a commit.
  • Architecture — the four packages, the path a request takes, and why the domain logic is kept away from HTTP and SQL.
  • Authentication — the substance: password hashing, session lifecycle, and the attacks each choice is meant to frustrate.
  • Reference — endpoints, error codes, configuration, and the schema.
  • Design decisions — the record of what was chosen over what, and the conditions that would reverse each call.