Data Handling
This page documents observed data flow and storage behavior in the current codebase. It is not a security certification and does not replace a formal audit.
Local vs Server-Side Processing
RowOps runs the ingestion pipeline in the client environment (browser or Node.js headless). The dashboard/control plane stores configuration and metadata, but it does not execute pipeline stages.
Based on server routes and database schema, no evidence found that raw row data or file bytes are transmitted to RowOps servers as part of the default import pipeline. Export and sync callbacks are the explicit points where data can leave the client.
Pipeline stages run locally:
- Parse: file bytes are processed in workers and stored as Arrow IPC in the local chunk store.
- Validate: rules are evaluated in WASM on Arrow IPC.
- Mask/Transform/Profile: run on valid rows in worker/WASM stages.
- Export/Sync: data leaves the client only when you configure export or sync callbacks.
Persisted Metadata
Configuration and operational metadata are stored server-side for project management and auditing.
Configuration
Examples of configuration stored server-side:
- Orgs, projects, schemas, schema versions
- API keys (publishable and secret), domain allowlist entries
- Webhooks and sync target configuration
Operational metadata
| Data | Where | Notes |
|---|---|---|
| Import runs | imports | Row counts, file size, schema/version IDs, status |
| Column mappings | mapping_history | Mapping keys and schema field names only |
| Audit logs | audit_logs | Action metadata (actor, entity, timestamp) |
| Usage events | usage_events | Small, flat telemetry payload (see below) |
| Profile reports | profile_reports | JSON report payloads if submitted |
| Sync logs | sync_logs | Event metadata with client-provided JSON payload |
| Webhook deliveries | webhook_deliveries | Event, status, HTTP status, error message |
Notes:
profile_reports.reportcan include aggregates and top values. Treat it as potentially sensitive.sync_logs.payloadis free-form JSON. Do not send row-level data unless you intend to store it.
What Is Not Persisted
No evidence found in server schema or API routes of:
- Full row-level datasets or file contents
- Arrow IPC chunks or export blobs
- Per-row validation error payloads
This does not prevent a client integration from sending row data to its own endpoints via sync/export. Those paths are explicitly controlled by the integrator.
Telemetry Caveats
The /api/track endpoint accepts a strict allowlist payload:
- Required:
action,tier,orgId,projectId,sessionId,timestamp - Optional:
stage,errorCode,sdkVersion,rowCount,errorCount,durationMs - Enums and ID formats are validated; unknown fields are rejected
- No nested objects; string values are capped at 256 characters
The payload is still client-provided. Treat it as potentially sensitive and avoid including row values.
Webhook Delivery Behavior
Webhook delivery runs client-side. The server logs delivery metadata in webhook_deliveries (status, HTTP status, error message). No evidence found that webhook payload bodies are stored server-side.
Client-Side Storage
Browser mode:
- Arrow IPC chunks are stored in IndexedDB (
rowops-chunks) during parsing and pipeline stages. - Presets are stored in IndexedDB (
rowops-presets) with org/project/schema scoping. - Some UI components cache row previews in IndexedDB (
rowops-rows). - Entitlement tokens are cached in memory for the current session only (no localStorage persistence).
Headless mode:
- Key/value storage uses SQLite files under
.rowops/storage(Node adapter). - Strict mode requires a verified entitlement token (offline if provided, otherwise via secret key exchange); demo mode skips verification.
- The default headless chunk store is in-memory; outputs are persisted only when you write them.
What This Page Does Not Guarantee
- This is not a security certification or penetration test.
- Claims are based on code review and may change between versions.
- Client integrations can change data flow by configuring export/sync callbacks.