Security & privacy
askTheodor is built so that the powerful, autonomous parts can’t hurt you. Your data stays on your machine, your provider keys are encrypted at rest, nothing consequential happens without a gate you control, and spending is capped. This page lays out the whole security and privacy model in one place — and is honest about what’s shipped today versus what’s still being built.
Local-first: your data stays yours
Your workspace — Companies, Workers, conversations, the Library, Plans — lives in a local database on your own device. There is no askTheodor cloud that holds your content; nothing is uploaded to us. You bring your own AI provider keys, so the only data leaving your machine is what a worker sends to the provider you chose, when you (or a Plan you approved) ask it to.
In a team, this stays true: instead of a vendor cloud, you self-host the shared Team-Hub on a server you control, and instances sync directly to each other. See Teams & remote.
Provider keys are encrypted at rest
The API keys that unlock your providers are stored in askTheodor’s local database on your machine — never sent to askTheodor’s servers. Since v0.9.268 they are encrypted at rest with AES-256-GCM. The encryption key is a random 32-byte key kept in a separate, permission-restricted file outside the database, generated on first launch.
What that does and doesn’t protect you from, stated plainly:
- A copy of the database file alone reveals nothing. A stolen or backed-up
.db, a synced folder, or a file recovered from a disk contains only ciphertext. - Full access to your user account is still full access. Anyone who can read both the database and the key file — i.e. someone already logged in as you — can recover the keys. This is protection against data-at-rest exposure, not against a compromised machine.
- Keys don’t travel in backups. Because the encryption key is machine-local, restoring a workspace bundle on another computer means re-entering your provider keys. That’s by design.
When keys are pushed to a paired hub, they travel over an encrypted key-push channel, sealed in transit, and are revocable per hub.
The approval gate
Whenever a worker is about to do something sensitive or irreversible — send an email, post publicly, run a flagged shell command, or take a destructive computer-control action — the approval gate stops it and waits for your OK. You see what it wants to do, with the exact arguments, and choose. On a headless hub, where no one is present, the gate auto-denies, which is precisely why a hub can never send on its own.
The autonomy kill-switch
One control pauses all unattended work at once — every Plan, Routine, and background dispatch stops. It’s the big red button for when something looks wrong, and in a team it’s designed to reach every hub in your fleet from a Command Center, so you can freeze everything in one move.
Budgets and limits
Spending can’t run away:
- Budgets set a money ceiling, globally and per Company; when a ceiling is hit, a hard-stop blocks further runs until you raise it.
- Per-tool limits cap how many times — and how much — an individual tool may be called, and can require approval at the level of specific arguments.
These travel with the workspace, so the same ceilings apply on a hub as on your desktop.
Draft-only channels
Connectors to the outside world (email, WhatsApp, …) can run draft-only: an inbound message produces a worker-written draft, and the app sends nothing on its own. This is the default for Team-Hubs, and it’s a structural reason a hub can prepare outreach but never release it.
Injection screening on ingested content
When a worker ingests outside content — reading your inbox, fetching a web page — that content can contain prompt-injection attempts: hidden instructions trying to hijack the worker. askTheodor runs an injection scanner over ingested material on those paths, so a malicious page or email is far less able to turn your worker against you. The screening stays on the team ingestion paths too.
Security in a team (the Fleet layer)
When instances talk to each other, the team layer adds its own defenses on top of everything above:
- HMAC-signed requests. Every request between paired instances carries a cryptographic HMAC signature proving it came from a genuine peer and wasn’t altered, backed by a replay cache and a freshness window so old or duplicated requests are rejected.
- Scoped, least-privilege pairing. A pairing grants only a specific scope — sync, delegate, keys, or full — so a teammate’s Command Center can be limited to exactly what it needs (typically sync + delegate, not full).
- Sealed secrets. Licenses and API keys move over the encrypted key-push channel, never as plaintext sync rows, and are per-hub and revocable.
- Conflict-safe deletes. Deletes of shared items don’t hard-remove anything over sync; they become soft-deletes that the Master approves, with a full audit trail of who did what.
- Kill-switch fleet-wide. The autonomy pause is meant to propagate to hubs, so pausing from a Command Center stops the whole fleet.
Your privacy checklist
- Use providers you trust — content you send goes to them, under their policy, not ours.
- Keep autonomy model choices sensible for unattended runs (the app gates which models may run unattended).
- Review what’s in your Library before sharing a Company; scope decides who can read it.
- Pair only machines you control, and grant the narrowest scope that does the job.
🎓 Learn it hands-on: Backup, export & privacy · Tool allowlists & least privilege
Terms in this page
- Local-first — your data lives on devices you own (a local database), not on a vendor’s cloud.
- Encrypted at rest — data stored as ciphertext rather than plain text. askTheodor encrypts provider API keys in its local database with AES-256-GCM, keeping the encryption key in a separate protected file outside that database.
- Approval gate — the checkpoint that pauses sensitive or irreversible actions for your explicit OK; auto-denies when headless.
- Autonomy — a worker acting unattended; always bounded by budgets, limits, the gate, and the kill-switch.
- Kill-switch — the single control that pauses all unattended work at once, designed to reach every hub.
- Budget — a money ceiling (global or per Company) that triggers a hard-stop when reached.
- Hard-stop — an automatic halt that blocks further runs (e.g. on hitting a budget).
- Per-tool limit — a cap on how often/how much a specific tool may be used, optionally with argument-level approval.
- Draft-only channel — a connector where inbound messages yield a worker draft and the app sends nothing automatically.
- Prompt injection — hidden instructions buried in outside content that try to hijack a worker; screened by the injection scanner.
- Injection scanner — the check askTheodor runs over ingested content (inbox, web pages) to catch injection attempts.
- HMAC — a cryptographic signature on each inter-instance request proving it came from a paired peer and wasn’t tampered with.
- Replay cache / freshness window — protections that reject duplicated or stale signed requests.
- Scope — the capability a pairing grants (sync / delegate / keys / full); kept as narrow as possible.
- Least privilege — granting each machine only the access it needs and no more.
- Encrypted key-push — the sealed channel that moves licenses and API keys to a hub without exposing them in sync data.
- Soft-delete — marking a shared item for removal (pending the Master’s approval) instead of erasing it immediately.
- Server-side enforcement — the receiving instance checking a change against the sender’s role and rejecting unauthorized destructive operations. (Planned.)
- Audit trail — the recorded history of who requested, approved, or rejected each cross-instance action.
- Penetration test — a deliberate security probe of the team endpoints planned before general release.