> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qredence.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# fleet-rlm security model

> Threat model, secret hygiene, bind safety, filesystem and upload protections, SSRF defenses, and sandbox containment for the fleet-rlm backend.

`fleet-rlm` is a single-operator, bring-your-own-key (BYOK) backend with no authentication surface of its own. The design keeps secrets out of every API response, binds the service to loopback by default, runs all model-generated code inside a Daytona Sandbox, and bounds or validates everything that crosses the host boundary.

Report vulnerabilities by email to `contact@qredence.ai`, following the process in the repository's `SECURITY.md`. Do not open public issues for vulnerabilities.

## Threat model

The assumed attacker is whoever or whatever can reach an exposed Fleet process or feed content into it: a malicious URL fetched by a Tool, a crafted filename in an upload, or model-generated code that tries to touch the host. The defender boundary is the host process plus your own Daytona account.

Multi-tenant isolation is out of scope by design: one process, one operator, one Workspace namespace. If you expose Fleet beyond loopback, put your own auth layer in front of it. See [Deployment](/fleet-rlm/guides/deployment) for the reverse-proxy pattern.

## Secrets and error hygiene

* `config/fleet.toml` profiles name environment variables. Fleet resolves only the variables the selected profile explicitly references. Unreferenced ambient variables never reach provider clients, and ambient selectors (`FLEET_CONFIG_PROFILE`, `FLEET_RUN_ENVIRONMENT`) are ignored.
* Fleet sanitizes public API errors. Run preparation, startup, and provider failures return closed public messages, never raw exception text, stack traces, or credentials. Typed validation errors carry fixed public strings; unknown failures collapse to generic `503` responses such as "Attachment storage is unavailable".
* Tool event views are fail-closed allowlists. Fleet projects only declared bounded metadata onto SSE, traces, and the pi-tui timeline; structural values are capped at 256 characters, and a Tool without a declared view exposes no arguments or results at all.

## No-auth local API and bind safety

The local API accepts no `Authorization` header and no synthetic identity headers. Fleet installs one deterministic process-local scope with fixed user and workspace ids, and the settings API rejects non-loopback clients.

Because there is no auth, binding matters. Every launcher rejects a non-loopback bind host unless you pass `--allow-non-loopback-bind` deliberately. Fleet raises the error at bind time, which prevents casually exposing Sessions, Workspace operations, and BYOK model execution on a network interface.

## Filesystem and upload protections

* Attachment filenames are sanitized before storage: Fleet rejects path-shaped input (`/`, `\`, `..`) before basename extraction, requires names to match a 255-character allowlist, and refuses hidden dotfiles. Fleet caps uploads at 10 MiB and rejects empty or negative sizes.
* Session Workspace paths must be relative POSIX paths with no `\`, NUL, or relative components. A reserved `.fleet` segment is refused, and paths are bounded at 8 segments, 255 bytes per segment, and 1,024 bytes total. Validation is lexical, without filesystem normalization, so no symlink or canonicalization trick can widen a path.
* Mutating Workspace Tools (`delete_workspace_path`, `edit_workspace_text`, and the project-scoped pairs) target regular files and empty directories only, never follow symlinks, and fail closed on FIFOs and other non-regular nodes. Optional `expected_sha256` preconditions guard writes, edits, and deletes against clobbering content that changed since it was read. The compare-and-mutate happens inside one mounted Workspace Agent operation with inode revalidation, which closes the cross-sandbox time-of-check/time-of-use (TOCTOU) window.

## URL fetch SSRF defenses

The public-URL source Tool stays behind the host with layered bounds against server-side request forgery (SSRF):

* Before any bytes move, Fleet resolves the host and requires every resolved address to be globally routable, rejecting loopback, private, and link-local targets.
* Fleet caps redirects at 3 and re-canonicalizes the URL on each hop.
* Fleet bounds fetches with a 10-second timeout, 64 KiB read chunks, an allowlist of text media types, and per-response byte caps.
* The session source cache is bounded at 64 entries and 64 MiB total, and the HTTP client does not inherit ambient proxy settings.

## Memory and Skill injection guardrails

Each Workspace Memory record in `memory/MEMORIES.md` gets one addressable id. Duplicates fail closed, and `remember` is idempotent for the same record, so a model cannot corrupt the log by replaying appends. Each Turn receives only a bounded 4 KiB memory digest.

Bundled Skills can supply the model instructions and manifest-declared UTF-8 resources through `load_skill` and `read_skill_resource` only. Skills can never register executable Tools, so a Skill document is not a code-execution vector. See the [agent model](/fleet-rlm/concepts/agent-model) for the Skill catalog.

## Sandbox and dependency containment

All `dspy.RLM`-generated code executes inside a Daytona Sandbox interpreter, not on the host. The host only wraps bounded Tools and observes the interpreter boundary.

On the dependency side, `pyproject.toml` pins `litellm>=1.87.0` above releases affected by known CVEs, floors `aiohttp` and `urllib3` at patched releases, and `make check-security` runs `pip-audit` plus `bandit -lll`. Application code reaches LLMs only through `dspy.LM`, never through litellm directly.

## What fleet-rlm does not do

* No user authentication or authorization model anywhere in the API. Identity is the single local scope, and remote access is explicitly not provided.
* Secrets live in environment variables only. There is no secret store and no encrypted config. The settings API can edit non-secret policy but can never read back or inject a referenced secret value.
* No multi-tenant network defense. Everything above assumes loopback plus an operator-provided auth layer if the bind is widened.

## Related pages

* [Deployment](/fleet-rlm/guides/deployment)
* [Configuration reference](/fleet-rlm/reference/configuration)
* [HTTP API reference](/fleet-rlm/reference/http-api)
