From fbb4e592744c9d1047b0afef8ddb893cf31be987 Mon Sep 17 00:00:00 2001 From: lila Date: Sun, 26 Apr 2026 10:51:45 +0200 Subject: [PATCH] adding ticket structure, finishing docker credential helper setup --- documentation/backlog.md | 8 +-- documentation/notes.md | 1 + documentation/tickets/blueprint.md | 77 ++++++++++++++++++++++++ documentation/tickets/t00001.md | 95 ++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 documentation/tickets/blueprint.md create mode 100644 documentation/tickets/t00001.md diff --git a/documentation/backlog.md b/documentation/backlog.md index 865c9f2..4e6af84 100644 --- a/documentation/backlog.md +++ b/documentation/backlog.md @@ -8,12 +8,6 @@ Labels: `[feature]` `[infra]` `[security]` `[ux]` `[debt]` Things that are actively in progress or should be picked up immediately. Mostly operational risk and the remaining phase 7 hardening work. -- **Pin dependencies in package.json** `[debt]` `[infra]` - Unpinned deps in a CI/CD pipeline are a real risk. Pin all versions to exact values to prevent unexpected breakage on build. - -- **Docker credential helper** `[debt]` `[infra]` - Credentials are stored unencrypted in `~/.docker/config.json`. Set up a credential helper. See https://docs.docker.com/go/credential-store/ - - **Google OAuth publishing** `[infra]` Only test users can currently log in via Google. Publish the OAuth consent screen so any Google user can sign in — requires branding verification in Google Cloud Console. @@ -108,6 +102,8 @@ Directionally right, timing is unclear. Revisit when the next/now work is done. Shipped milestones, newest first. +- **04 - 2026 - t00001 - Docker credential helper** +- **04 - 2026 - Pin dependencies in package.json** - Unpinned deps in a CI/CD pipeline are a real risk. - **04 - 2026 - React error boundaries** - Catch and display runtime errors gracefully instead of crashing the entire app. - **04 - 2026 - 404 and redirect handling** - Unknown routes return raw errors. Add a catch-all route on the frontend for client-side 404s. - **04 - 2026 - Multiplayer GameService unit tests** - round evaluation, scoring, tie-breaking, timeout handling diff --git a/documentation/notes.md b/documentation/notes.md index eb25e7a..8a8d414 100644 --- a/documentation/notes.md +++ b/documentation/notes.md @@ -13,6 +13,7 @@ task description. 4. if we go through a file, we'll do it slowly section by section, no matter how many sections 5. how to name the current feature branch? also tell me when its time to git commit and provide a commit message 6. if we have multiple options to do something, also always provide options that reflect current industry standards and best practices +7. For every completed task, produce a ticket file in documentation/tickets/. Use ADR format (adr-) for decisions between options with long-term consequences. Use feat-/fix-/chore- for routine tasks. Always include a setup guide or summary of what was done. Suggest the filename. ## tasks diff --git a/documentation/tickets/blueprint.md b/documentation/tickets/blueprint.md new file mode 100644 index 0000000..7e612bb --- /dev/null +++ b/documentation/tickets/blueprint.md @@ -0,0 +1,77 @@ +# Ticket Blueprint + +Two formats depending on task type. Choose based on whether a meaningful +decision between options was made. + +--- + +## Format A — ADR (architectural/infrastructural decisions) +Use when: you chose between options with long-term consequences. +Prefix: `adr-` + +--- + +# ADR: + +## Status +Accepted | Superseded by | Deprecated + +## Date +YYYY-MM-DD + +## Context +What is the problem? Why does it need to be solved? + +## Decision +What was chosen and why in one or two sentences. + +## Options considered + +### Option A — <name> ✅ +Description. Why it was chosen. + +### Option B — <name> +Description. Why it was rejected. + +## Consequences +- What gets better +- What gets worse or more complex +- Operational implications +- What breaks if this needs to be redone + +## Affected files / machines +- List files, servers, or systems touched + +## References +- Links to relevant docs + +--- + +## Setup guide / implementation notes +Step-by-step of what was actually done. + +--- + +## Format B — Task (features, fixes, chores) +Use when: routine task with a clear solution. +Prefix: `feat-` / `fix-` / `chore-` + +--- + +# <prefix>: <title> + +## Problem +What was wrong or missing? + +## Options considered +### Option A — <name> ✅ +### Option B — <name> + +## Solution +What was done and why. + +## Files changed +- `path/to/file.ts` + +## Commit +`<type>: <message>` diff --git a/documentation/tickets/t00001.md b/documentation/tickets/t00001.md new file mode 100644 index 0000000..d15f242 --- /dev/null +++ b/documentation/tickets/t00001.md @@ -0,0 +1,95 @@ +# ADR: Docker Credential Helper Setup + +## Status +Accepted + +## Date +2026-04-26 + +## Context +Docker credentials for `git.lilastudy.com` and `dhi.io` were stored as +base64-encoded strings in `~/.docker/config.json` on both the dev laptop +and the VPS. Base64 is not encryption — anyone with read access to the +file can decode the credentials instantly. + +## Decision +Use `pass` (GPG-backed password store) as the Docker credential helper +on both machines. + +## Options considered + +### Option A — `pass` (GPG-backed) ✅ +Stores credentials encrypted with a GPG key. Works on headless servers +and desktops without GNOME. Industry standard for Linux servers. + +### Option B — `secretservice` (GNOME keyring) +Uses the desktop keyring daemon. Not suitable for a headless VPS, and +not suitable for an i3 desktop without running `gnome-keyring-daemon` +manually. + +### Option C — `gnome-libsecret` +Same limitations as Option B. + +## Consequences +- Credentials are now GPG-encrypted at rest on both machines +- Requires GPG passphrase entry when Docker needs to pull credentials + in a new session +- Must be set up manually on each machine — not reproducible via the repo +- VPS setup must be repeated if the server is reprovisioned + +## Affected machines +- Dev laptop (Debian 13, i3) +- VPS (Debian 13, ARM64, headless) + +## References +- https://docs.docker.com/reference/cli/docker/login/#credential-stores +- https://www.passwordstore.org/ + +--- + +## Setup guide + +Repeat these steps on each machine. + +### 1. Install dependencies +```bash +sudo apt-get install -y pass gnupg2 golang-docker-credential-helpers +``` + +### 2. Generate a GPG key +```bash +gpg --full-generate-key +``` +Choose RSA, 4096 bits, no expiry. Set a strong passphrase. + +### 3. Get the key ID +```bash +gpg --list-secret-keys --keyid-format LONG +``` +Copy the hex string after the `/` on the `sec` line. + +### 4. Initialise pass +```bash +pass init <your-key-id> +``` + +### 5. Update `~/.docker/config.json` +Replace the entire file contents with: +```json +{ + "credsStore": "pass" +} +``` + +### 6. Re-login to registries +```bash +docker login git.lilastudy.com +# dev laptop only: +docker login dhi.io +``` + +### 7. Verify +```bash +cat ~/.docker/config.json +``` +Should show only `"credsStore": "pass"` with no `auths` block.