Trust & security
Ruminate stores the working context your AI agents build up: decisions, facts, risks, plans and drafts. This page describes how that data is held, who can reach it, and what the agents connected to it can and cannot do.
Ruminate is an early-stage service and this document is provisional. It describes the system as it is implemented today, including the parts that are not finished. Where a control is partial, it says so rather than rounding up.
Last reviewed 10 September 2026.
Certification status
SOC 2: not yet certified; controls are being implemented. Ruminate has not completed a SOC 2 Type I or Type II audit, holds no ISO 27001 certification, and has not commissioned an external penetration test. We do not claim otherwise, and you should not rely on a certification we do not have.
What exists today is the underlying control work: enforced authentication on every path, owner-scoped authorisation, encrypted off-site backups with a tested restore, request rate limiting, an audit trail for every agent write, and documented incident procedures. The remaining gaps are listed below.
Architecture and data flow
Ruminate is a single Next.js application on Vercel backed by managed PostgreSQL. Two kinds of client reach it — a person in a browser, and an AI agent over the Model Context Protocol — and both are authenticated before they reach any shared service code.
- A browser request carries a Clerk session; an agent request carries a Clerk OAuth token or an issued API key.
- Credentials are verified at the edge, then again independently on every data path. A verification error fails closed rather than falling back to a local identity.
- Verification produces a viewer — who is acting, which organisation owns the data, and what role they hold.
- Web and MCP share one service layer, so an authorisation rule is written once and applies to both surfaces.
- Every read and write is filtered by owner before it reaches PostgreSQL.
The boundary worth noticing is the one that is not drawn: no arrow leaves this diagram toward a model provider.
Authentication
Identity is delegated entirely to Clerk. Ruminate never stores or handles passwords.
- Two-factor authentication, recovery codes and passkeys are available to every account. They are available rather than mandatory — we do not currently enforce 2FA at the organisation level.
- Active sessions are listed with device and approximate location, and can be revoked individually. Changing a password signs out every other session.
- Access to the beta is restricted to an explicit organisation allowlist. Deployments fail to build when that list is missing, so an accidental deploy cannot open the product to the public.
Agent credentials
- API keys carry 256 bits of cryptographically random material, are displayed once at creation, and are never recoverable afterwards.
- Only a SHA-256 hash is stored. Lookup happens by hash through a unique index, so there is no code path that reads a key back out.
- A key’s organisation and role are fixed when it is issued, so switching organisations in a browser cannot silently retarget a running agent.
- Removing someone from an organisation revokes their keys and connection records automatically, through signed webhooks from Clerk. Hosted OAuth connections re-check organisation role on every single request rather than trusting a cached claim.
Tenancy and isolation
Every workspace is owned by a Clerk organisation. Authorisation compares both the kind of owner and the owner’s identifier, and an unauthorised record is indistinguishable from one that does not exist — so a workspace identifier alone never confirms that a workspace is there.
Because the web app and the MCP server share one service layer, an agent inherits exactly the checks a browser gets. Cross-organisation access is covered by mandatory regression tests that run on every change.
Being precise about how this is enforced, because the distinction matters to anyone reviewing us: row-level security is enabled on every application table, and it is what closes the database provider’s auto-generated data API — no anonymous or end-user API role can read a single row through it. It is not, however, what separates one tenant from another. The application connects with a role that bypasses row-level security, so tenant separation is enforced by owner checks in the service layer rather than by the database itself. A compromise of the application’s database credential would bypass those checks. Moving isolation into the database with a least-privilege role is on the list below.
Encryption
- Traffic to Ruminate is served over HTTPS, and HTTPS is enforced by our hosting platform. The connection between the application and the database is encrypted with TLS.
- Encryption at rest is provided by our infrastructure providers — Supabase for the database and object storage, Clerk for identity records, Vercel for build artefacts. Ruminate does not add a separate application-level encryption layer, and we would rather say so than imply one exists.
- Database backups are encrypted by us, with AES-256 and 200,000 key-derivation rounds, before they leave the machine that produced them. The key is held separately from the backups.
Backups and recovery
- The database is exported every day at 02:17 UTC. Each export is validated, encrypted, checksummed, and retained for 14 days.
- A restore drill runs automatically every month: it decrypts a real backup, loads it into a disposable database, and verifies the current application can open it. Only row counts are reported — never data.
- Backups are stored with a different provider from the database, so a single provider account compromise does not take both.
Stated plainly, because it bounds what we can promise: this daily export is the only backup. Our database plan includes no provider-native backup and no point-in-time recovery, so the worst case is losing up to 24 hours of writes — whatever happened since the last export. Moving to a plan with continuous recovery is on the list below, and it is the first thing we will do when a customer’s data justifies it.
We have not published a recovery time objective. The monthly drill restores in minutes, but that is a disposable database under no load, and a number measured there would not be one you could hold us to.
Logging and audit
Three durable trails record what happened, and all three are visible to you inside the product rather than only to us:
- Activity — every meaningful change, marked as made by a human, an agent, or the system.
- Sessions — each agent working session, with its stated intent, the client and model that reported it, what it touched, and how it ended.
- Tool calls — each MCP call with its tool name, client, outcome and duration.
What is deliberately never written to logs or telemetry: entry bodies, prompt content, and tool arguments. Failure messages are Ruminate’s own classified error text, bounded in length, and identity provider errors are recorded as a marker without the provider’s message, which can carry account detail.
Ruminate runs no product analytics, no advertising or tracking pixels, and no third-party session recording. There is no analytics vendor in the stack to list as a subprocessor because there is no analytics vendor at all.
Being straight about the gap: we do not yet run automated error alerting or anomaly detection. Operational failures are found in hosting logs or reported by users. External alerting is on the list below.
AI and MCP data handling
This is the section most worth reading, because Ruminate’s position here is unusual.
Ruminate does not run a model
No customer content is sent to any large language model provider by Ruminate. There is no model API key in the runtime, no provider SDK in the application, and no outbound request to a model endpoint anywhere in the codebase. The model work happens in your own AI client — Claude Code, Cursor, Codex — under the provider agreement you already hold. Ruminate is the workspace those agents read from and write to.
This has a direct consequence for training: your content cannot be used to train a model by us, because we never send it to one. Whatever terms govern training are the ones between you and your own AI provider.
Duplicate detection is worth naming for the same reason. When an agent checks whether an entry already exists, that comparison runs locally as a word-overlap calculation against your own workspace. There is no embedding provider and no vector database in the system.
What agents are allowed to do
- A connected agent sees a deliberately reduced tool set by default — discovery, entry composition, structure, sessions and context — not the full internal catalogue.
- A client can ask to enable only two additional groups. Membership, workspace administration and repository tools can never be turned on by a request header; those are server-controlled.
- No agent can permanently delete anything. Removal by an agent means a reversible archive. Permanent deletion requires a signed-in administrator in the browser, behind a double confirmation.
- Merges keep both original entries and stay undoable for 30 days. Archived content is restorable for 30 days before it is purged, and the purge itself is recorded in the activity trail.
- Agents cannot upload files or invite members. File attachment is a web-only action performed by a person.
- Requests are limited to 200 per minute and 3,000 per hour per organisation, and request bodies are capped before authentication or parsing. Two kill switches allow us to disable MCP entirely, or drop it to read-only, without a code deploy during an incident.
Limits you should weigh
An agent is outside our trust boundary. It reads context that other agents wrote, which means it can be influenced by that context, and we design for blast radius rather than assuming good behaviour. Three limits follow from that and are worth knowing before you connect one:
- An API key carries the full reach of the member it was issued to. There is no per-workspace or read-only key yet, so a compromised key can read and change anything that member could.
- Entry content is stored exactly as an agent writes it. Ruminate does not scan for, redact, or classify personal data on the way in — treat what your agents write as content you have chosen to store.
- Reversibility limits damage but does not prevent disruption. An agent behaving badly can still archive or rewrite a lot of entries quickly, and the remedy is restoration plus key revocation.
Subprocessors
These providers process customer data on Ruminate’s behalf. Notably absent: any AI or model provider, any analytics vendor, and any advertising network.
| Provider | Purpose | Data processed |
|---|---|---|
| Vercel | Application hosting, serverless runtime, and static documentation hosting, in iad1 (Washington, D.C., USA) | All request traffic in transit; runtime logs |
| Clerk | Identity, sessions, organisations, and authentication email | Name, email address, credentials, organisation membership |
| Supabase | Managed PostgreSQL and object storage, hosted in AWS eu-west-3 (Paris) | All workspace content and account records at rest |
| GitHub | Source control, CI, and encrypted backup storage | Encrypted database backups only |
Where your data lives
Your workspace content is stored in the EU, in Paris. The application that serves it runs in the United States, in Virginia, so a request is processed in the US even though the data at rest never leaves the EU. Encrypted backups are held by GitHub, and identity records by Clerk, both under their own regional arrangements.
If your organisation needs processing and storage in a single jurisdiction, tell us — the application region is configuration rather than architecture, and we would rather move it than have you assume it.
Optional, user-connected integrations
These are off unless a user connects them, are authorised per user, and can be disconnected at any time.
| Provider | Purpose | Data processed |
|---|---|---|
| GitHub API | Optional repository connection | Repository contents you explicitly connect |
| Google Drive API | Optional read-only document import | Documents you explicitly import |
We evaluate agent behaviour against a synthetic test workspace in continuous integration. That tooling runs against fabricated data, is disabled by default, and never touches customer content — which is why it is not listed as a subprocessor.
Privacy
A formal privacy policy and a data processing agreement are available on request through the form below. This section states the substance they are built on.
What we hold
- Account data — name, email address and organisation membership, held by Clerk.
- Workspace content — the entries, structures, drafts and sessions your team and agents create.
- Operational records — activity, sessions and tool-call telemetry, as described above.
We do not sell data, do not share it with advertisers, and do not use workspace content for any purpose other than operating the product for you.
Deletion and retention
- You can delete your account yourself from account settings. Stored application data is removed before the identity record is deleted.
- Deleting an organisation removes its workspaces, entries, sessions, activity, keys and connections in a single transaction.
- Archived content is permanently purged 30 days after archiving. Encrypted backups persist for up to 14 days after that, so deletion is fully propagated once the last backup containing it rotates out.
- Honestly stated: a small number of auxiliary records — search tokens, merge revisions and guard attempts — are not yet cleared by the deletion cascade, and operational telemetry has no expiry policy today. Both are on the list below. If you need certified erasure before then, contact us and we will do it by hand and confirm.
What we are implementing next
This is what “controls are being implemented” actually refers to, in roughly the order we intend to do it:
- Move to a database plan with provider-native backups and point-in-time recovery.
- Move the Content-Security-Policy from report-only to enforced.
- Enable certificate verification on the database connection.
- Introduce a least-privilege database role separate from the migration credential.
- Add per-key workspace scopes so an agent credential can be narrowed below full member reach.
- Define and apply a retention policy for activity, session, and tool-call telemetry.
- Add external uptime and error alerting with a named recipient.
- Establish and test a second authorised recovery operator.
Reporting a vulnerability
If you believe you have found a security issue, email hello@ruminate.so with the detail needed to reproduce it. We aim to acknowledge within two working days.
Please give us a reasonable window to fix an issue before disclosing it publicly. We will not pursue legal action against good-faith research that avoids privacy violations, data destruction, and service degradation. We do not currently run a paid bounty programme, and we would rather tell you that up front than let you assume one.
During an incident our first actions are to revoke affected keys and sessions, disable or downgrade MCP access if needed, and preserve logs before changing anything. Affected customers are contacted directly.
Request security documentation
For the full security overview, our subprocessor list, privacy policy, data processing agreement, or SOC 2 readiness plan, tell us what you need and we will send it. If you have a security questionnaire, attach it in your follow-up and we will complete it.
You can also read the product documentation or email hello@ruminate.so directly.