llm-runtime-dock 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +49 -12
  2. package/dist/index.js +6937 -6663
  3. package/package.json +12 -12
package/README.md CHANGED
@@ -294,10 +294,11 @@ Clients send the logical id and never see the backend model:
294
294
 
295
295
  On the gateway itself:
296
296
 
297
- | field | meaning |
298
- | --------------- | ------------------------------------------------------------------ |
299
- | `host` / `port` | where `lrd` listens. Defaults to `127.0.0.1:8787` |
300
- | `idle_unload` | unload the loaded model after this long with nothing to do (below) |
297
+ | field | meaning |
298
+ | --------------- | ------------------------------------------------------------------------- |
299
+ | `host` / `port` | where `lrd` listens. Defaults to `127.0.0.1:8787` |
300
+ | `idle_unload` | unload the loaded model after this long with nothing to do (below) |
301
+ | `auth` | require an API key of clients, as `api_key_env` or `api_key_file` (below) |
301
302
 
302
303
  On a runtime:
303
304
 
@@ -612,9 +613,11 @@ work because nothing rewrites them.
612
613
  Request bodies are touched in exactly one place: the `model` field, swapped from
613
614
  your logical id to the one the backend answers to. Not `tools`, not
614
615
  `tool_choice`, not `messages`. `GET /v1/models` returns your configured logical
615
- ids whether or not they are loaded, and your `Authorization` header goes
616
- upstream verbatim — a per-model `auth:` block fills in only when you sent none,
617
- and the gateway never generates a key.
616
+ ids whether or not they are loaded, and — when the gateway itself requires no
617
+ key — your `Authorization` header goes upstream verbatim; a per-model `auth:`
618
+ block fills in only when you sent none. If `server.auth` is set (below), that
619
+ header authenticates to the gateway instead and is not forwarded; the runtime's
620
+ own `auth:` block is what reaches it, resolved server-side.
618
621
 
619
622
  The full surface, both protocols, response-header handling and `/switch`
620
623
  semantics are in [§14](docs/06-gateway-api.md#gateway-api).
@@ -678,9 +681,41 @@ the file it read.
678
681
 
679
682
  ## Security notes
680
683
 
681
- The gateway binds to `127.0.0.1` and has no authentication. `/status` and
682
- `/switch` are lifecycle controls: loopback-only, and refused outright when the
683
- gateway is bound to a non-loopback address.
684
+ The gateway binds to `127.0.0.1` and requires no authentication by default.
685
+ `/status` and `/switch` are lifecycle controls: loopback-only, refused outright
686
+ when the gateway is bound to a non-loopback address, and that rule holds
687
+ regardless of whether an API key is configured — a leaked key must not hand out
688
+ remote process control on top of remote inference.
689
+
690
+ **Requiring an API key.** Generate one and wire it into `server.auth`:
691
+
692
+ ```bash
693
+ lrd key generate # writes server.auth.api_key_file, plus a secret file next to the config
694
+ lrd key generate --env # prints the key once; writes server.auth.api_key_env: LRD_API_KEY instead
695
+ ```
696
+
697
+ or set it by hand:
698
+
699
+ ```yaml
700
+ server:
701
+ auth:
702
+ api_key_env: LRD_API_KEY # or: api_key_file: ~/.config/llm-runtime-dock/api_key
703
+ ```
704
+
705
+ With no `server.auth` at all, the `LRD_API_KEY` environment variable is checked
706
+ automatically — useful for a Docker or systemd deployment that already injects
707
+ secrets that way, with no YAML edit needed. Once a key resolves, every route but
708
+ `/health` requires it (`Authorization: Bearer <key>` or `x-api-key: <key>`);
709
+ `lrd status`/`lrd switch` send it automatically, and `lrd apply` wires it into
710
+ whichever agent you configure — Claude Code's `settings.json` gets the literal
711
+ value (it has no reference syntax), OpenCode and Codex get an environment
712
+ variable reference instead.
713
+
714
+ An `api_key_env`/`api_key_file` that is set but resolves to nothing is a hard
715
+ failure at `lrd serve`: an admin who configured a key source must never end up
716
+ with a gateway that silently started unauthenticated. Binding to a non-loopback
717
+ address with no key at all is only a warning, from `doctor` and the `serve`
718
+ startup banner — not a hard stop.
684
719
 
685
720
  Lifecycle commands are **trusted configuration only**. Nothing derived from an
686
721
  HTTP request is ever interpolated into a command — a request selects which
@@ -706,8 +741,10 @@ metacharacter in it is live — quoting, globbing, redirection, command
706
741
  substitution. Use it only for a command you wrote yourself, and prefer the argv
707
742
  form, which cannot be reinterpreted.
708
743
 
709
- `lrd apply` never writes a credential into a coding agent's configuration, only
710
- an environment-variable reference.
744
+ `lrd apply` never writes an _upstream_ credential into a coding agent's
745
+ configuration, only an environment-variable reference — except the gateway's
746
+ own key, which some agent formats (Claude Code) can only receive as a literal
747
+ value, since that agent must present it to reach the gateway at all.
711
748
 
712
749
  The normative rules are in [§28](docs/01-overview.md#security).
713
750