Security defaults, in plain English.
Ringlet runs on your laptop and talks to provider APIs on your behalf. Here's exactly where the keys live,
how the daemon authenticates, and what stops an agent from rm -rf'ing you.
Credentials
API keys are stored in the OS-native credential store via the Rust keyring crate. Nothing is
ever written to a plain-text config file unless you ask for it.
- macOS: Keychain Services via
Security.framework. Items stored asringlet/<provider>/<alias>in the user's login keychain. - Linux: Secret Service API (GNOME Keyring, KWallet). Falls back to
~/.config/ringlet/credentials.tomlwith mode0600on headless systems. - Windows: Credential Manager (
wincred). Generic credentials, scoped per provider.
# List what's stored:
ringlet keychain list
# Remove a key:
ringlet keychain remove anthropic work
# Force file-backed credentials (e.g. on a headless server):
ringlet config set credentials.backend file Daemon authentication
The daemon binds to 127.0.0.1:8765 by default — never 0.0.0.0 unless you set
--listen explicitly. All HTTP and WebSocket endpoints require a bearer token, generated on
first run and stored in ~/.config/ringlet/http_token (mode 0600).
# Rotate the token:
ringlet daemon rotate-token
# Read the token (for CI):
cat ~/.config/ringlet/http_token
# Use it:
curl -H "Authorization: Bearer $(cat ~/.config/ringlet/http_token)" \
http://127.0.0.1:8765/api/profiles Sandboxing
Remote agent sessions never have the same privileges as the user running the daemon. Each session is wrapped in a sandbox before exec.
- Linux:
bwrapwith a read-only system root, an explicit workspace bind-mount,--unshare-all, and no network access unless the profile explicitly opts in (typically the profile does opt in — agents need to call provider APIs — but the network namespace is fresh and the agent doesn't inherit your existing connections). - macOS:
sandbox-execwith a custom.sbprofile. Read-only system, writable workspace, deny by default onnetwork-bindandfile-write*outside the workspace.
What the agent CAN'T do, by default
- Read or write files outside its profile's workspace.
- Connect to localhost services (the daemon's HTTP port is unreachable from inside the sandbox).
- Spawn subprocesses with elevated privileges.
- Mount filesystems or namespaces.
- See other profiles' HOMEs.
What it CAN do, by default
- Read and write to the workspace bind-mount (your project directory).
- Make outbound HTTPS calls to the provider API listed in the profile.
- Read the agent's binary and the runtime libraries it needs (read-only system root).
Hooks as a guardrail layer
For finer-grained control than the sandbox, use the pre-tool-use hook. It runs before any tool call
the agent makes; return deny to block it.
ringlet hooks add work --on pre-tool-use \
--shell 'echo "$RINGLET_TOOL_INPUT" | grep -qv "rm -rf"'
# Exit 0 → allow; non-zero → deny. Threat model
Ringlet protects against:
- Key leakage between projects (different profiles = different keychain entries).
- Accidental destructive commands during a remote session (sandbox + hooks).
- API keys ending up in shell history or in
.envfiles committed to git (keychain by default).
It does not protect against:
- A malicious agent talking to a malicious provider (you pick the provider).
- An attacker with root on your laptop (Keychain protects against process-level access, not a compromised OS).
- Prompt injection inside the agent's context. Use hooks for high-impact tool calls.
Reporting vulnerabilities
Email security@neullabs.com. We'll respond within 72 hours and credit you in the changelog unless you'd rather we didn't.
Audit log
With --audit-log, every profile launch, tool call, and provider request is appended to a
local SQLite database. Suitable for after-the-fact review; not currently tamper-evident (planned for the
team tier).
ringlet daemon --stay-alive --audit-log ~/.ringlet/audit.db
ringlet audit query --since 2026-05-01 --profile work