Legal

Privacy Policy

Draft · last updated 2026-10-06

DRAFT — needs legal review before public launch. This page was written by the engineering team to describe what Soil's software actually does today, in plain language. It is not legal advice, has not been reviewed by a lawyer, and must not be relied on as a finished privacy policy until it has been. Where something is not decided or not known here, this page says so rather than inventing an answer.

Soil ("we," "us") is software that connects to your company's existing tools — Jira, GitLab, and, on the paid plan, GitHub, Slack, Google Drive/Calendar/Gmail, Outlook Calendar, PagerDuty, HubSpot, Freshdesk, your own Stripe or Razorpay, AWS Cost, and Zoom — to help a founder or engineering manager understand what their team is building and what's at risk, either in a weekly written brief or by answering a direct question. This page explains what data Soil accesses, why, and how it's handled.

Who this applies to

Soil is multi-tenant: one deployment serves many separate organizations ("orgs"), each with its own connected accounts and its own data. Every piece of data Soil stores belongs to exactly one org and is scoped to it in every database query — one org can never see another org's data. This is enforced in the application code, not just by policy.

What we connect to, and why

Nothing below is individually mandatory. On Soil's Free plan, Jira and GitLab are the two connectors on offer, and an org needs at least one of the two connected to activate Soil. GitHub, Slack, Google Drive, Google Calendar, Outlook Calendar, Gmail, PagerDuty, HubSpot, Freshdesk, your own Stripe or Razorpay, AWS Cost, and Zoom are part of the paid Team plan.

  • Jira — issues, statuses, assignees. Powers the weekly brief and the Ask engine's "what's planned, what's stuck" answers.
  • GitLab — merge requests, pipelines, review activity. Powers deployment/lead time/review-wait metrics in the weekly brief. Carried over from the product's earlier phase and still fully supported.
  • GitHub (Team plan) — pull requests, reviews, commit history, read-only. Feeds the on-demand Ask engine only, never the weekly brief.
  • Slack (Team plan) — messages in the specific channels an admin chooses and invites Soil's bot into. Feeds the Ask engine's "what did people decide or promise" answers, and, only if an admin turns it on, lets the bot reply when @-mentioned or post a proactive risk alert.
  • Google Drive (Team plan) — documents in the one folder an admin picks. Feeds the Ask engine's "what did we decide/sign off on" answers.
  • Google Calendar (Team plan) — meeting titles, attendees, and times tied to tracked work, to flag scheduling risk (e.g. a release review getting pushed).
  • Outlook Calendar (Team plan) — the same meeting titles, attendees, times and Teams join links as Google Calendar above, read through Microsoft Graph with the Calendars.Read scope. Read-only: Soil cannot create, move or cancel an Outlook meeting, and holds no permission that would let it. An Outlook meeting is shown only to the person whose calendar it came from and to the people Microsoft itself lists on it — admins included.
  • Gmail (Team plan) — messages that reference tracked issues or PRs, so an email thread can be cited as a source in an Ask answer.
  • PagerDuty (Team plan) — incident status, service, and urgency, plus who's currently on call, read-only. Lets a brief item or Ask answer cite an open incident, and flags scheduling risk from who's on call.
  • HubSpot (Team plan) — deals in the pipelines an admin picks: name, amount, currency, stage, close date, the dated history of those fields, and the owner's name and email. Companies: name, domains and lifecycle stage. Soil does not request your contacts, and does not request the bodies of your sales emails — where an activity timeline is available it records that a touch happened and when, never what was said.
  • Freshdesk (Team plan) — ticket subject, status, priority, tags and the times each was created, first replied to and resolved, plus your Freshdesk company names. Soil never reads a conversation, a ticket description or a requester's phone number.
  • Stripe or Razorpay, your own account (Team plan) — invoice amount, currency, status, issue date, due date and paid date, plus the customer name and email on those invoices. This is read with a credential you create in your own account, and is a different account and credential from the one Soil bills your subscription through.
  • AWS Cost (Team plan) — monthly cloud spend by service, from AWS Cost Explorer, for the Cash leaks page's cloud-spike check. Spend figures only: no resource names, no account contents, nothing from inside the services themselves.
  • Zoom (Team plan) — the scheduled meetings on the Zoom account an admin connects: topic, agenda, start time, duration, time zone, join link, and the host's email address. Read-only, with the meeting:read and user:read scopes and no others — Soil's Zoom client has no write path at all, so it can never create, move or cancel a meeting. Soil does not read participant lists, recordings, transcripts, chat or cloud storage, and does not ask for the scopes those need.

The exact OAuth scope requested for each provider, and why, is documented in this repository's docs/oauth-scopes.md — that document is the technical source of truth this policy summarizes. For Google's Drive/Calendar/Gmail scopes specifically, that document records the requirement: drive.readonly and calendar.readonly are on Google's sensitive-scopes list and need Google's standard OAuth verification, and Gmail's message access is one of Google's restricted scopes, which additionally requires an annual independent third-party security assessment (CASA) and a published privacy policy meeting Google's Limited Use requirements before it can be offered beyond a small closed beta.

Whether Soil has completed either review is not stated here. That is a fact about Soil's Google Cloud project rather than about this code, so this page will not guess at it in either direction — claiming verification Soil may not have, or denying one it may hold, would both be wrong. It is an open item in docs/NEEDS_FROM_KARTIK.md, and the answer belongs on this page as soon as it is known.

How your data is stored and protected

  • Credentials are encrypted at rest with AES-256-GCM before being written to the database, using a key that is never logged or committed to source control (soil/crypto.py's encrypt_credentials, with a fresh random nonce stored per encryption). That covers all four kinds of credential Soil holds: each connector's OAuth access and refresh tokens or pasted API key, an org's own AI-model API key if it sets one, the bearer token for an outbound MCP server an admin connects, and any expense CSV an admin uploads to Cash leaks and asks Soil to keep.
  • A credential is also kept out of every other channel out of the process — a provider's error message shown on a screen, a log line, an error report, a 500 page — by one redaction function that lives beside the encryption (soil/crypto.py's redact).
  • Soil stores history, not just a current snapshot — ticket status changes, merge request events, and similar activity are kept over time so the weekly brief and Ask engine can answer questions like "when did this slip" or "how long has this typically taken." This history is also scoped per-org and never shared across orgs.
  • Login is email + password, handled entirely by Soil's own code (no third-party identity provider). Passwords are hashed with scrypt and are never stored, logged, or visible to us in plain text. Login sessions are random, revocable tokens, not something that can be decoded to reveal your password.
  • A small number of failed login attempts will temporarily lock an account, to slow down password-guessing.

Where an AI model is involved

Soil's weekly brief and its answers to direct questions are written by first computing facts with plain, deterministic code — not by asking an AI model to figure out what's true. An AI model (Anthropic's Claude, when this feature is turned on) is used only to turn those already-computed facts into readable prose; it does not decide what to look up and does not have open-ended access to your connected tools. When this is enabled, the facts being narrated (not raw credentials, and not your full Jira/Slack/Drive contents) are sent to Anthropic's API to generate that text. See Anthropic's own privacy policy for how they handle API data.

Who else can see your data (sub-processors)

Soil is one deployment with a small, fixed set of outside services behind it. These are the only third parties Soil's own code sends anything to, and each is named here only after checking that it is really wired up:

  • Anthropic — the AI model that words a brief or an answer, as described above. Receives already-computed facts, never a credential.
  • Stripe — billing for the paid plan. Receives your organization's name and whatever you type into Stripe's own checkout page. Soil never receives or stores your card details.
  • Resend — transactional email: the sign-in link, the morning brief, the weekly digest. Receives the recipient address and the contents of that email. If no email provider is configured on a deployment, no email is sent at all rather than queued elsewhere.
  • Sentry — error reports, if error tracking is enabled on the deployment you use. Error capture only, with no performance tracing; stack-frame local variables and request bodies are both switched off, and every event is passed through the same redaction function described above, specifically so that a credential or a pasted password cannot leave in a crash report (soil/web/app.py's _init_sentry).

Where Soil's own database and servers are physically hosted, and in which country, is not stated on this page yet. That is a fact about the deployment rather than the code, it matters for an India-first customer, and it is an open item in docs/NEEDS_FROM_KARTIK.md.

Payment information

If your organization is on Soil's paid plan, billing is handled by Stripe. Soil does not receive or store your card details — Stripe processes payment directly and Soil only receives confirmation of your subscription status.

Email delivery

If your organization has an email address on file, the weekly brief may be emailed to it via Resend, a transactional email provider. No email is sent if no address is configured.

What we don't do

  • We don't sell your data to anyone.
  • We don't use your connected data to train any AI model.
  • We don't run any third-party analytics or advertising trackers on this site today.
  • Soil's Slack bot only reads channels it has been explicitly invited into, and only posts messages if an org admin has turned that feature on — it is never on by default.

Your controls

An org admin can choose which providers to connect and which Slack channels or Drive folder to sync, and can turn optional features (the Slack bot's replies, proactive alerts, the Actions review queue) on or off at any time from within the product.

An org admin can disconnect any connected tool at any time from the Connections page, which deletes that tool's stored credential and every row synced from it immediately (soil/store.py's disconnect_integration). An org admin can also export all of the organization's data, or permanently delete the organization and everything in it, from Settings — both self-serve, both logged. Deletion is one cascading database statement: immediate, with no grace period, and irreversible, because Soil keeps no copy to restore from (delete_organization; the Terms describe this in full). Deleting your own account is a separate, larger action, described in the next section. How long data is kept for an organization that nobody deletes, and how long deleted rows may survive in backups, are not decided — so no retention period is claimed here either.

Deleting your own account

You can permanently delete your own account. This is a bigger action than deleting one organization, and not only for you. An organization in Soil is unusable without an admin — nobody could connect a tool, invite a teammate or delete it — so deleting your account also deletes every organization you are the only admin of, and everything in it, including work that other people in that organization put there. The same is true of an organization you are the only person in. Organizations that somebody else also administers are not deleted: you are removed from them and they keep working for everyone else (soil/store.py's delete_user_account).

Before anything is deleted, Soil shows you what deleting your account would destroy in your case specifically — which organizations would go, how many other people would lose them, which connected tools go with them — counted from your real data rather than described in general terms, and you have to type your own email address to confirm (preview_account_deletion). Nothing is deleted until you do.

What then happens is what happens to a deleted organization: it is immediate, there is no grace period, and it cannot be undone, because Soil keeps no copy to restore from. Two things survive on purpose. The log entry recording that the deletion happened is kept, as it is for an organization deletion, and it names the email address of the account that was deleted. And records that belong to an organization that is not being deleted — a question asked in it, an action someone approved, the note that a tool was connected — stay in that organization's history with the link to you removed, because deleting them would rewrite other people's records rather than yours. As above, how long a deleted row may survive inside database backups is not decided, so no period is claimed here.

Questions

This is a draft, and there is no published contact address for it yet: no support mailbox is configured anywhere in this deployment, and naming one that does not exist would be worse than saying so plainly. Until an address is published and this policy has been reviewed, questions, corrections or requests about your data should go to the person who invited you to your organization, or to whoever runs the Soil deployment you signed up on. Publishing a real address is an open item in docs/NEEDS_FROM_KARTIK.md.