Security
Enforced in the code, not promised in a policy
Connecting an AI to the systems your company runs on is a real decision, and it should not come down to trusting a marketing page. Everything below is a constraint in the runtime, with the place it is enforced named so you can check it.
The last section is the list of things we have not done. That one matters more than the rest.
What an agent is allowed to do
The controls people ask about first, because this is the part that is genuinely new. These are constraints in the runtime, not settings we recommend you tick.
Permissions are set per action, not per app
Every tool an integration exposes has its own mode: ask every time, always allow, or disabled. Connecting Slack does not grant everything Slack can do. A conversation can also override a mode for that session only, and the override dies with the chat.
IntegrationToolPermission, tool_gate_service.resolve_gate
Every write stops for a human
Anything that changes an outside system — a CRM record, an issue, an email draft — halts the run and files an approval with the exact proposed change. There is no auto-approve mode anywhere in the product, on any plan, for any customer. “Always allow” removes the prompt, not the approval.
SkillApproval, skill_runtime.execute_run
Unattended work is held to stricter limits than you are
A scheduled or event-triggered task can never reach shell execution, on any plan, with any opt-in. That was ruled categorically out of scope rather than gated behind a setting, because a cron job with a terminal is a different risk class from a person with one.
scheduled_task_service, risk_class high_impact_write
Write tools are off until an admin turns them on
Until an organisation opts in, write tools are stripped before the model is even told they exist. The model cannot ask to use a capability it has never been offered.
tool_registry.build_anthropic_tools
Who can see what
Scoping is applied at retrieval, not at display — an agent cannot surface something a person is not entitled to, then hide it in the UI.
Every query is scoped to one organisation
Tenant isolation is a column on every table and a filter on every query, with an automated audit wired into CI that fails the build on a query that could cross organisations.
organization_id, cross-org query audit in CI
Knowledge carries its own scope
An entry can be personal to one person, limited to a department, shared within a room, or open to the organisation. The check runs wherever a requesting user is known — the dashboard, the Slack bot, MCP, and direct API-key calls alike.
scope_service.is_visible, SourceObjectAcl
Private sources stay private
For sources that expose real per-object permissions — private Slack channels, Drive, Calendar, Gmail, and the meeting tools — membership is resolved to actual people and enforced on retrieval, rather than flattening everything to organisation-wide.
SourceObjectAcl, reconciliation_worker
Sign-in is OAuth only
Google and GitHub. No passwords are collected, hashed, or stored, and the tokens the backend issues are revocable and expire in seven days.
NextAuth, backend-issued JWT
What is kept, and for how long
The product is built around extracted knowledge, not a copy of your content. That is a storage design, not a retention promise bolted on afterwards.
Raw content is not kept long term
Fetched source material is purged on a rolling 90-day cycle. Conversation transcripts synced from an AI client are discarded as soon as knowledge has been extracted from them — they are never retained.
RawItem purge cycle
Credentials are encrypted at rest
OAuth tokens and API keys are encrypted with Fernet before they touch the database, and every connection is TLS in transit. Encryption keys live in the environment, never in the repository.
Fernet, ENCRYPTION_KEY
Deletion actually deletes
Disconnecting an integration, resetting the brain, or deleting an account removes the underlying rows rather than flagging them hidden.
cascade deletes, integration disconnect
We do not connect to your database
Direct customer database access is deliberately out of scope. Indexbrain reads through the APIs of tools you already trust, and nothing else.
product scope decision
What happens to untrusted content
Anything synced from an outside system is treated as hostile until it has been checked — including content that will end up in a model prompt.
Everything is scanned twice
Content is scanned on the way in and again on the way out to an agent, for prompt injection, exposed credentials, destructive commands, and hidden unicode. The scan is pattern-based, so it costs nothing per item and cannot itself be talked out of running.
processing/safety_scanner.py
Answers cite their sources
Synthesised answers carry citations back to the evidence they came from, and citations the model invents are detected and stripped before the answer is returned.
query_planner, citation validation
Runs are recorded, step by step
Each run keeps an immutable record of every tool call, its arguments, and its result, alongside an activity log covering every meaningful action in the product.
SkillRun, SkillRunStep, activity_service
Sandboxes are small and disposable
Where code execution is enabled, it runs in a per-scope container with a hard CPU and memory ceiling that stops automatically when idle. Reaching one still requires an approved, write-enabled skill.
sandbox_service, 0.5 vCPU / 256MB
Not yet
What we have not built
A security page that only lists strengths is no use to the person doing the review. These are the honest gaps as they stand today.
SOC 2
Not certified. Many of the underlying controls are in place, but SOC 2 is an audited process with an observation window, and we have not been through it. We will say so on this page when that changes rather than implying it early.
Third-party penetration test
Not yet commissioned. Security work so far has been internal review and fixing what it found.
Customer-managed encryption keys
Keys are managed by us. Bring-your-own-key and key rotation policy are not built.
Sandbox network egress policy
Sandboxes can reach the internet, which is what makes installing packages and calling external APIs possible. There is no allowlist yet — a deliberate trade-off, and one we will revisit.
The legal documents
Subprocessors, data-processing terms, and what we collect are all written down rather than summarised here.
Doing a security review before you connect anything? Talk to us — you will get the engineer who wrote the thing you are asking about.
Start with read-only and see for yourself
Connect one source, leave every write tool off, and watch what it does with real company context before you grant it anything.