Skip to content

feat: keep the master key in a file llmr makes on first start - #88

Closed
recepkizilarslan wants to merge 1 commit into
mainfrom
feat/master-key-file
Closed

recepkizilarslan wants to merge 1 commit into
mainfrom
feat/master-key-file

Conversation

@recepkizilarslan

Copy link
Copy Markdown
Collaborator

Why

A stack that runs llmr beside its own services (Korkut installs with a single docker compose up) could not start llmr without someone first generating a key and pasting it into the environment. Compose cannot generate a secret, and the image has no shell to do it in an entrypoint.

What

  • LLMR_MASTER_KEY_FILE
    • Names a file that holds the key. When the file is absent, llmr makes a new key there on first start (MasterKey::load_or_create) and reads it on every later start.
    • Created with create_new and never replaced: processes starting together agree on one key, and readers wait briefly for a key still being written. On Unix the file is mode 0600.
    • A file that holds something other than a key is an error, never silently replaced: a new key would orphan every stored credential.
  • Precedence: LLMR_MASTER_KEY still wins when both are set. With neither set, the error names both options.
  • Image: prepares /var/lib/llmr-key, owned by uid 65532, so a named volume mounted there can hold the key apart from the database. This keeps "a copy of the database alone opens nothing" true.
  • Docs: README, DEPLOYMENT and CHANGELOG (Unreleased → Added).

Verified

  • All six local gates are clean: fmt --check, the three clippy variants with -D warnings, and cargo test with and without all features.
  • New tests in crypto::tests:
    • A missing file is made and read back.
    • 16 concurrent loads agree on one key.
    • The file mode is 0600.
    • A file with junk is an error and stays untouched.
  • Image check: built locally and run with only LLMR_MASTER_KEY_FILE=/var/lib/llmr-key/master_key on a named volume.
    • /healthz returns 200, and the key file is -rw------- 65532.
    • After adding a provider (credential sealed) and restarting, the same key is read and the provider opens (problems: []).

A stack that runs llmr next to its own services had no way to start
without someone generating a key and pasting it into the environment
first. LLMR_MASTER_KEY_FILE names a file instead. When the file is
absent, llmr makes a new key there and reads it back on every later
start.

- The file is created with create_new and never replaced, so processes
  starting together agree on one key. On Unix it is readable by its
  owner only.
- A file holding something that is not a key is an error. llmr never
  replaces it with a fresh key, which would orphan every stored
  credential.
- LLMR_MASTER_KEY still wins when both are set.
- The image prepares /var/lib/llmr-key, owned by its user, so a named
  volume mounted there keeps the key apart from the database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@recepkizilarslan

Copy link
Copy Markdown
Collaborator Author

Not needed: Korkut's installer generates LLMR_MASTER_KEY, so llmr stays as it is.

@recepkizilarslan
recepkizilarslan deleted the feat/master-key-file branch October 10, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants