> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsevvo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> What sevvo's control plane does and does not see.

sevvo is a **hybrid control plane / data plane** system. The control plane
orchestrates; the data plane touches your data. The boundary between them is
the most important contract in the product.

## The short version

* **sevvo's control plane never sees raw source rows or canonical output.**
  Bounded, user-triggered previews travel directly from the agent to the
  user's browser.
* **sevvo stores connector credentials in the control plane.** OAuth
  credentials live in Pipedream; native database credentials are temporarily
  stored as JSON on the `connections` table until encrypted vault storage
  lands.
* **sevvo's control plane never opens inbound connections** to your
  environment. The agent connects outbound to sevvo over TLS on port 443;
  users' browsers connect separately to the customer-supplied data-plane URL
  over the customer's network or VPN.
* **sevvo cannot execute arbitrary code on your agent.** Workflow
  definitions are shipped in the agent image; upgrading means pulling a new
  image tag, not accepting new code at runtime.

## The data boundary

| Data class                                                             | Where it lives      | Notes                                                                                 |
| ---------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------- |
| OAuth source credentials                                               | Pipedream           | Resolved just-in-time by the control plane.                                           |
| Native database credentials                                            | sevvo control plane | Temporary `connections.credentials` JSON until encrypted vault storage lands.         |
| Raw source rows                                                        | Customer env        | Agent reads, transforms, and writes without round-tripping through the control plane. |
| Canonical model output                                                 | Customer env        | Written to your sink (S3, warehouse, Postgres).                                       |
| Connection metadata (host, db name, SSL mode)                          | sevvo control plane | `connections.safeMetadata`.                                                           |
| Pipeline definitions, schedules, model configs                         | sevvo control plane | The thing you manage in the UI.                                                       |
| Run metadata (row counts, byte counts, durations, schema fingerprints) | sevvo control plane | Returned by Temporal activities. No row content.                                      |
| Preview query results                                                  | User's browser      | Returned directly by the agent over the customer network; not proxied by sevvo.       |

Every Temporal activity return type is a metadata shape — counts, durations,
hashes, opaque references. Orchestration inputs carry identifiers (`orgId`,
`connectionId`, `modelId`), not credentials or embedded data.

## Browser-direct preview queries

The agent's interactive preview endpoint can return real rows directly to the
user's browser so the hosted console can render a table while the user is
authoring a model. The browser must be able to reach the customer-supplied
data-plane URL, which may be available only on the customer's VPN. The payload
does not pass through Convex, Temporal, or another sevvo control-plane service.

It is bounded by construction:

* **User-triggered only.** It does not run on a schedule.
* **SELECT / WITH only.** The agent rejects any other statement type.
* **Single statement.** Semicolon chains are rejected.
* **Hard row cap of 100.** The agent wraps the query in
  `select * from (<sql>) as preview_query limit 100`.
* **10-second timeout.**
* **Per-cell text truncation at 1024 characters.**
* **Value sanitization** before the rows are returned to the browser.

Canonical sync does **not** use this path. Sync flows return only metadata —
row counts, byte counts, and schema fingerprints — never source data.

## Where credentials live

OAuth connector secrets are stored directly in Pipedream. When the agent needs
to run a Google Sheets request, it calls the control plane with a
`connectionId`; the control plane resolves the connection's Pipedream account
id and returns the latest OAuth access token.

Native database credentials are stored for now as opaque JSON on the Convex
`connections.credentials` field. Normal user-facing connection queries strip
that field and return only name, type, status, and `safeMetadata` (host,
database, SSL mode, Pipedream account id).

External secret managers (AWS Secrets Manager, GCP Secret Manager, Vault) are
optional integrations. The default deployment does not require any of them.

## AI analyst data

AI analyst chat runs in the data-plane agent. User prompts, assistant
responses, sandbox state, tool output, and generated artifacts are persisted in
the agent's Postgres database, not in Convex. The browser streams directly from
the customer-supplied data-plane URL, and the AI provider key is supplied
through the agent environment.

## Authentication

**Users.** Human auth is handled by sevvo's authentication service. Every
user-facing control-plane operation resolves `{ orgId, userId }` from a
signed session. Cross-tenant access is prevented at the query layer.

**Data-plane network access.** The customer controls the private DNS, VPN,
firewall, ingress, and TLS configuration for the data-plane URL. VPN
reachability determines whether the browser can route to the agent; it does
not give sevvo's control-plane servers access to that network.

**Agents.** Each agent deployment has its own sevvo deployment token
provisioned via the UI. The agent unwraps it into deployment credentials,
exchanges those for a short-lived bearer, derives `orgId` from the returned
JWT, and attaches that bearer to every control-plane call. You can revoke an
agent's access instantly by clicking **Revoke** on its deployment page —
future bearer exchanges will fail.

**Temporal.** The agent connects outbound to sevvo's Temporal frontend
and polls a tenant-scoped task queue (`tenant-{orgId}`). The queue name is
scoped by tenant so a misconfigured agent cannot pick up another tenant's
work. mTLS is supported via `SEVVO_TEMPORAL_TLS_CERT` / `SEVVO_TEMPORAL_TLS_KEY`.

## Tenancy

* **Deployment boundary.** One agent per tenant, running in the tenant's own
  environment.
* **Task-queue boundary.** Workflows are routed by `tenant-{orgId}` task
  queue; workers only pick up work for their own tenant.
* **Auth boundary.** `requireAuth(ctx)` enforces `orgId` on every
  user-facing operation in the control plane.

## Upgrading without remote code execution

Control-plane upgrades do not push code to your agent. The agent runs the
workflow definitions baked into its image; newer workflow types become
available only when you pull a new image tag. In-flight executions replay
safely across upgrades — workflow inputs are append-only, and logic changes
use Temporal's `patched()` to avoid non-determinism.

## Security requirements we hold ourselves to

These are design rules for sevvo engineering, surfaced here so you can
audit us against them:

* Raw source rows and canonical output do not pass through the sevvo control
  plane. Bounded preview rows may leave the agent only on the direct response
  to the requesting user's browser.
* Connector credentials stay in their designated backend: OAuth credentials in
  Pipedream and native database credentials in the control plane until
  encrypted vault storage lands. AI chat does not introduce agent-local
  connector credential persistence.
* Access tokens are treated as cacheable derived credentials.
  **Refresh tokens and private keys are the highest sensitivity class** and
  are never cached outside of the customer secret store.
* OAuth session state (when v1 adds OAuth) is short-lived and auto-expired.
* Logs redact access tokens, refresh tokens, passwords, private keys, and
  connection strings with embedded credentials.
* Error payloads sent upstream are structured and sanitized — no raw SQL,
  no response bodies, no provider-returned credentials.

## Reporting a security issue

Email [security@getsevvo.com](mailto:security@getsevvo.com). PGP key and
response SLA are published at `getsevvo.com/security`.
