Operations
Security and privacy
Sigil’s position is simple: there is no Sigil cloud, no account, and no telemetry. The only thing that ever leaves your machine is what your chosen LLM and embedding providers see.
What sees what
Section titled “What sees what”| Sees | |
|---|---|
| Your database | Everything. It’s yours. |
| Embedding provider | Every chunk of every ingested document, and every search query |
| LLM provider | Chunks during extraction, fact pairs during AUDM, your message during classification |
| Sigil the project | Nothing. One outbound call: the GitHub update check, which you can disable. |
Pick Ollama for both providers and the second and third rows go to zero. See Fully local setup.
Disable the update check with preferences.noUpdateCheck (Settings → General).
Secret masking
Section titled “Secret masking”Recognized secret patterns are masked at the single ingest choke point — before classification, chunking, embedding, and fact extraction. Every downstream copy is masked, so a credential never reaches your embedding provider and never lands in the database.
The trade-off is deliberate: the classifier sees masked content. For secret-bearing input the literal secret never improves routing, and preventing exfiltration outranks classifier fidelity. Masking is idempotent, so re-ingesting is safe.
Read-side masking runs too, before injection — so a secret that predates the guard doesn’t leak into a prompt.
Files that hold secrets
Section titled “Files that hold secrets”| Path | |
|---|---|
~/.sigil/config.json | API keys and database credentials. chmod 600. Never commit this to a dotfiles repo. |
~/.sigil/identity.key | Ed25519 secret for device pairing |
~/.sigil/gui.token | Dashboard bearer token |
~/.sigil/db/ | In embedded mode, your entire memory |
Configuration is written atomically (temp file, then rename) and re-chmod 600 on every write.
Network exposure
Section titled “Network exposure”By default the daemon binds to 127.0.0.1:7777 — loopback only — and gates the dashboard and HTTP MCP transport behind a bearer token.
The database connection string is the key
Section titled “The database connection string is the key”Anyone with your connection string can read every fact, every document, and every namespace in that database. There is no per-namespace encryption and no row-level access control.
- Use
sslmode=requireon any network connection - Treat the string like a password
- Prefer a database that isn’t publicly reachable
Boundaries: what each one is and isn’t
Section titled “Boundaries: what each one is and isn’t”| Mechanism | Is | Is not |
|---|---|---|
| Namespace | A retrieval partition | Access control — anyone with the connection can read all of them |
| Visibility scope | Addressing — stops a fact reaching the wrong agent or machine | A security boundary against a determined reader |
| Pod scope | A ranking and context boundary | Isolation |
| Device pairing role | Actual authorization — reader / writer / admin, revocable | Encryption of data at rest |
Device pairing is the only one of the four that’s genuinely an authorization mechanism.
Multi-device access control
Section titled “Multi-device access control”sigil pair create --name ci-runner --role reader --ns engineering --ttl 300sigil pair listsigil pair revoke <id>The plaintext code is printed once and never stored. Hand it over out of band, and keep the TTL short.
| Role | Grants |
|---|---|
reader | Search, status |
writer | Plus remember, ingest |
admin | Plus device management |
Failure behaviour as a security property
Section titled “Failure behaviour as a security property”Every hook wraps in a top-level try/catch that fails silently. That’s a safety property as much as a reliability one: a memory layer that can block a prompt is a memory layer that can hold your work hostage when it breaks.
Related bounds:
- A circuit breaker stops repeated daemon spawn attempts rather than retrying forever
llm.maxClaudeProcs(default 4) caps concurrentclaudeprocesses — an unbounded ingest fan-out once produced 1600+ live sessions- Network provider calls time out at 60s, so a hung socket can’t wedge the daemon or a hook
Auditing your memory
Section titled “Auditing your memory”sigil facts --limit=100sigil facts --category=personalsigil export --format=markdown | lessThe dashboard’s Knowledge Base is faster — filter by namespace, category, or pod, and inspect any fact’s full provenance chain in the side panel. Activity filters by agent, so you can see exactly what each one wrote.
Removing data
Section titled “Removing data”sigil forget <id> # one factsigil pod delete <uid> --confirm # a podsigil namespace delete <ns> --confirm # a namespacesigil reset # everythingIf a secret did get stored, sigil forget removes the fact — but check whether it also appears in a document’s stored full text, and whether it reached your embedding provider before you noticed. Rotate the credential.
Threat model, stated plainly
Section titled “Threat model, stated plainly”Sigil is designed for a single trusted user on machines they control.
It protects against: accidental cloud storage of your context, vendor lock-in, cross-agent leakage of directed instructions, cross-device leakage of machine-specific facts, and accidental secret ingestion.
It does not protect against: an attacker with your database credentials, an attacker with filesystem access to ~/.sigil/, or a malicious agent you gave write access to. Multi-user support with per-user ACLs is not implemented.
Reporting a vulnerability
Section titled “Reporting a vulnerability”Open an issue at github.com/Anmol-Srv/sigil, or contact the maintainer directly for anything sensitive.