Documentation Index
Fetch the complete documentation index at: https://docs.feral.sh/llms.txt
Use this file to discover all available pages before exploring further.
Status: Stable — BlindVault, permission tiers, and execution sandboxing are production-ready.
Security Model
FERAL assumes the LLM is untrusted. Credentials, tool execution, and autonomy are all gated through layered security primitives that prevent prompt injection from escalating into real-world damage.BlindVault
The BlindVault stores all secrets (API keys, OAuth tokens, database passwords) encrypted at rest in~/.feral/credentials.enc (mode 0600). Encryption is ChaCha20-Poly1305 (AEAD) with a key derived from your master passphrase via Argon2id; the derived key is cached in your OS keychain (macOS Keychain / GNOME Keyring / Windows Credential Manager) so the vault unlocks transparently on brain start. The LLM never sees raw credential values — the vault injects them at the HTTP layer right before a request leaves the process.
[CREDENTIAL:weather_api] in tool descriptions. Even if the model tries to exfiltrate it, the raw value is never in its context window.
Vault Storage
Credentials are stored during setup (feral setup) and persisted to ~/.feral/credentials.enc. The vault injects secrets at the HTTP layer — the LLM never sees raw values.
Permission Tiers
Every tool is tagged with a PermissionTier that determines what approval is needed before execution.| Tier | Auto-execute? | Examples |
|---|---|---|
passive | Always | Read memory, search web, get weather |
active | In hybrid/loose | Send a message, create a file |
privileged | Only in loose | Run shell command, install package |
dangerous | Never auto | Delete files, send money, modify system config |
ExecutionSandbox
Tools taggedprivileged or above run inside an ExecutionSandbox that constrains what the subprocess can do.
seccomp on Linux, sandbox-exec on macOS) plus a process timeout. WASM skills get Wasmtime’s capability-based sandbox automatically.
Autonomy Levels
FERAL supports three autonomy modes that control how the PermissionTier system gates execution. See the Autonomy Levels guide for full details.| Mode | Behavior |
|---|---|
strict | Every tool call requires user approval |
hybrid | passive + active auto-execute; privileged + dangerous ask first |
loose | Everything except dangerous auto-executes |
SandboxPolicy Files
For fine-grained control, drop a YAML or JSON policy file in~/.feral/policies/:
Dangerous-Tool Deny Lists
Even inloose mode, certain tools are always gated. The dangerous_tools surface deny list is hard-coded and cannot be overridden by policy files:
enforce_safety
Theenforce_safety() function runs before every tool execution. It checks:
- The tool’s PermissionTier against the current autonomy level.
- Whether the tool is on the deny list.
- Whether a SandboxPolicy restricts the action.
- Whether a standing approval exists (see Autonomy Levels).
Hardening (v1.2.1)
The v1.2.1 release addressed a comprehensive security audit. All fixes are defense-in-depth measures that apply by default — no configuration required.Path Traversal Protection
The catch-all route serving the WebUI static files now usesPath.resolve() followed by is_relative_to() to reject any request that escapes the static directory (e.g. ../../etc/passwd).
SQL Injection Whitelist on Sync
The P2P sync engine only accepts operations targeting a hardcoded whitelist of table names:notes, episodes, conversations, knowledge, wiki_pages. Any other table name is rejected before query construction.
CORS Restricted to Localhost
The default CORSallow_origins was changed from wildcard * to localhost:5173,localhost:9090. Production deployments should set explicit origins via configuration.
XSS Sanitization via DOMPurify
The server-driven UI (SDUI) renderer in the React client now passes all HTML content through DOMPurify before rendering. This prevents any LLM-generated or server-pushed markup from executing scripts.Docker Sandbox Host Fallback Disabled
When the Docker sandbox cannot connect to the Docker daemon, it now raises an error instead of falling back to direct host execution. This prevents a missing Docker installation from silently bypassing container isolation.Docker Sandbox Runtime Hardening
Every container started bysecurity/docker_sandbox.py is launched with these defaults — no configuration needed:
--cap-drop ALL— every Linux capability is dropped.--security-opt no-new-privileges— execve cannot raise privileges (blocks setuid escapes).--pids-limit 128— caps process fan-out so a fork-bomb cannot exhaust the host PID namespace.--read-onlyroot filesystem with a tmpfs mount at/tmp(nosuid, 128 MB).--network noneunless the caller explicitly requests network access.- Runs as the unprivileged
sandboxuser inside the image. - Optional seccomp profile via
FERAL_SANDBOX_SECCOMP_PROFILE(the literal valueunconfinedis rejected — supply a JSON profile path or leave unset).
pids-limit is 16 regardless of what you set.
Command Injection Blocked in Direct Execution
The daemon’s direct execution path no longer passes raw strings to a shell. Shell metacharacters and injection patterns are rejected by a safety filter before any command is executed.Default Bind Address: 127.0.0.1
TheFERAL_HOST default was changed from 0.0.0.0 (all interfaces) to 127.0.0.1 (loopback only). This prevents accidental exposure on public networks. Set FERAL_HOST=0.0.0.0 explicitly if you need LAN/remote access.
NODE_API_KEY Requires Explicit Configuration
The WebSocket authentication token (NODE_API_KEY) no longer ships with a default value. If unset, daemon-to-brain authentication is effectively disabled — you must configure it explicitly for any multi-node deployment.
API Keys in Headers, Not URL Parameters
The Gemini API key is now sent via thex-goog-api-key request header instead of as a URL query parameter. This prevents key leakage in server logs, browser history, and referrer headers.
Tool Safety: CONFIRM Before AUTO
The tool safety classifier now checks CONFIRM patterns before AUTO patterns. Previously, a tool matching both lists would be auto-executed; now it requires user confirmation first.Limitations and Caveats
What FERAL Does NOT Protect Against
- Physical access attacks: If someone has physical access to the machine running the Brain, they have access to all data.
- Supply chain attacks: Third-party LLM providers can see your prompts (use Ollama for full local processing).
- Side-channel attacks: The timing and size of WebSocket messages may reveal information about your activity.
- Compromised LLM: If the LLM provider is compromised, tool calls may be manipulated.
Platform Differences
- macOS: Full Accessibility permissions required for desktop automation. Gatekeeper may block unsigned daemons.
- Linux: Docker required for code interpreter sandboxing. X11/Wayland differences affect screen capture.
- Windows: Limited support. No systemd daemon management.
Qualified Claims
- Voice latency depends on the provider (OpenAI Realtime ~200ms, Gemini Live ~300ms, local Whisper+Piper ~500ms). FERAL adds ~50ms of WebSocket relay overhead.
- “Local-first” means the Brain runs locally, but cloud LLM providers are used by default. For fully local operation, configure Ollama.
