LlamaStash is pre-1.0. Only the main branch is supported. Security fixes will land on main and ship in the next tagged release.
Please do not open a public GitHub issue for security reports. Instead, email the maintainer at d4udts@gmail.com with:
- a description of the issue,
- reproduction steps,
- the version (
llamastash --version) and platform, - any proof-of-concept code or scripts.
You can expect an acknowledgement within a few business days. If you don't hear back, please follow up — email gets dropped.
LlamaStash is loopback-only by default, with an opt-in LAN mode for the proxy data plane (behind a bearer key). The daemon binds two TCP listeners, both protected by file-system permissions on the daemon's state directory:
- Control plane (JSON-RPC for the CLI / TUI): bound on
127.0.0.1:48134(with a small port-scan window if the slot is taken; deliberately above IANA's registered range and outside the1143xproxy family). Always loopback — there is no host knob. Every request exceptGET /healthcarries aBearertoken validated in constant time. The token is 32 bytes of OS randomness, generated fresh on each daemon start, and written to$XDG_STATE_HOME/llamastash/runtime.json(mode0600). Same-UID trust: any process with read access toruntime.jsoncan attach. - OpenAI-compat proxy (data plane for OpenCode / Pi / OpenAI
clients): bound on
127.0.0.1:11434or11435by default. This is the only listener that can be exposed to the LAN, viaproxy.host/--proxy-host(e.g.0.0.0.0). A non-loopback bind requires a bearer key (proxy.api_key, sent asAuthorization: Bearer): llamastash auto-generates and persists one on first use, and the daemon refuses to bind a routable address with no key unless the operator passes--insecure-no-auth. The key is validated in constant time and never logged. TLS is not yet implemented, so LAN mode is plaintext HTTP — keep it on a trusted network or front it with a TLS-terminating reverse proxy. - Backend children (
llama-server,ds4-server) always listen on127.0.0.1only. The proxy reaches them over loopback; theextrasdenylist (--host,--listen,--bind,--api-key,--ssl-*, plus ds4's--corsand--dist-) blocks any attempt to rebind them or weaken the browser same-origin posture. LAN exposure is the proxy's job alone — models are never put on the network. - The daemon does not persist or transmit telemetry.
Issues we treat as in scope:
- Any path that lets a non-owner (different UID) read
runtime.jsonor otherwise attach to the control plane. - Any path that lets a remote attacker reach the control plane or a
backend child LlamaStash launched (
llama-server,ds4-server) (e.g., accidentally binding either to0.0.0.0) — both must stay loopback always. - Any auth bypass on the LAN-exposed proxy: reaching the proxy's
data routes without a valid bearer key when one is configured, or the
daemon binding a non-loopback proxy without a key when
--insecure-no-authwas not set. (A reachable proxy is expected once the operator opts into LAN mode with auth — that is not a vulnerability; an auth bypass is.) - Token / key leakage via logs, env-var dumps, or error messages.
- Memory-safety, deserialization, or path-traversal bugs in the daemon, CLI, or HTTP handlers.
- Lockfile / state-file races that allow privilege confusion between users.
Out of scope:
- Backend-engine upstream behaviour —
llama.cpp/llama-server,ds4/ds4-server, Lemonade /lemond(please report there). - Local denial-of-service by a malicious user against their own daemon.
- Issues that require the attacker to already have shell access as the daemon owner.