← Back to home

Security

Last updated: April 26, 2026

This page summarises how Tappy protects your data and our program for keeping the Service secure. For deeper questions, email security@tappy.sh.

Encryption

We encrypt at three layers — in transit, at rest at the storage layer, and field-level for sensitive secrets before they hit the database.

1. In transit

  • All requests to Tappy are TLS 1.2+ (HTTPS). HTTP is redirected.
  • All outbound connections from Tappy to sub-processors (Anthropic, OpenRouter, Stripe, Clerk, PlanetScale, Upstash, AWS, Sentry, PostHog) are TLS-only.
  • Internal service-to-service traffic on Railway runs over a private network, not the public internet.

2. At rest (storage layer)

  • Primary database (managed Postgres via PlanetScale): AES-256 volume encryption managed by the provider. Customer data in tables — documents, chat history, workspace knowledge — is protected by this layer.
  • Cache layer (Upstash Redis): AES-256 at-rest encryption. We only cache short-lived data (source listings, schema metadata, query results) — no long-term secrets.
  • Object storage (S3): SSE-S3 server-side encryption on all uploaded files (AES-256).
  • Database backups: encrypted and rotated on a 35-day window by the Postgres provider.

3. Field-level (application layer, for secrets)

Storage-layer encryption protects data if someone walks off with a disk; it doesn't protect against application-level threats (e.g. a SQL-injection leak). For anything truly sensitive we add a second layer: field-level AES-256-GCM encryption applied by Tappy before the value is written.

Field-level encryption applies to:

  • Database passwords and connection strings (Postgres, Snowflake).
  • API keys for connected sources (Stripe Sigma, generic API sources).
  • Placeholder credential values for LLM-generated API source fetchers.
  • OAuth refresh tokens (Google, Microsoft, HubSpot).
  • Custom request headers / cookies saved against web sources.

Implementation: secretCipher.ts uses Node's crypto.createCipheriv with AES-256-GCM and a per-record 12-byte IV. The master key lives in the SENSITIVE_DATA_SECRET env var, not in the database, not in source control. Cipher output stores iv:authTag:ciphertext (hex, colon-separated) and is verified on every decrypt so tampering is detected.

What is NOT field-level encrypted (and why)

Documents, notes, chat messages, and workspace knowledge are stored in the database without an additional per-field layer. These are covered by the at-rest encryption above; encrypting them at the app layer would break search, querying, and streaming updates without a meaningful threat-model benefit for our use case. We document this explicitly so customers with stricter requirements can make an informed decision.

Authentication & Access

  • User authentication is handled by Clerk with support for email + password, OAuth, and multi-factor authentication.
  • Production administrative access requires multi-factor authentication on every underlying provider (Railway, GitHub, Stripe, Google Cloud, Microsoft, PlanetScale, Upstash).
  • Production secrets are never committed to source control. Access to the secrets store is limited and audited.
  • Access reviews are performed at least quarterly.

Application Security

  • Code execution (Python, JavaScript fetch code) runs in isolated E2B / VM sandboxes with per-run timeouts, CPU and memory limits. Sandboxes are destroyed after each run.
  • Outbound requests from sandboxes are pinned to a per-source allowlist of hosts and are SSRF-guarded to block private, loopback, and metadata endpoints.
  • LLM-generated code is executed only inside these sandboxes, never in the main application runtime.
  • Dependencies are scanned for known vulnerabilities and upgraded on a regular cadence.
  • Per-user rate limits apply to expensive endpoints (LLM calls, extractions, sandbox execution).

Data Handling & AI

  • We do not use your documents, messages, connected-source data, or credentials to train machine-learning models.
  • When AI features process your data, we pass it to Anthropic (Claude) or OpenAI over their standard commercial APIs, and selected non-Anthropic model requests may be routed through OpenRouter. Under our API/commercial terms, inputs are not used for provider model training.
  • Query results from connected sources may be held in short-lived caches for performance and analysis continuity. We also store source data where you explicitly upload files, save materialised rows for API / Web sources, include outputs in documents, or create frozen snapshots.
  • You can export or delete your data at any time — see /data-deletion.

Sub-processors

A full list of sub-processors we rely on is maintained at /trust. We evaluate sub-processors for security posture before onboarding and review them annually.

Backups & Recovery

  • The production database is backed up continuously by our managed Postgres provider with point-in-time recovery.
  • We test restoration from backups on a regular schedule.

Monitoring & Incident Response

  • Application errors and security-relevant events are captured in our observability stack.
  • We maintain a written incident-response runbook. Material security incidents affecting customer data are communicated to affected customers without undue delay.
  • To report a suspected vulnerability, email security@tappy.sh. Please allow us a reasonable time to investigate and remediate before public disclosure.

Compliance

  • We are preparing for SOC 2 Type I and Type II reports. Progress and timing can be shared under NDA on request.
  • We support GDPR / UK GDPR data-subject rights including access, correction, deletion, and portability.
  • A Data Processing Agreement (DPA) is available to customers on request — email privacy@tappy.sh.

Contact

Security questions, vulnerability reports, and questionnaire requests: security@tappy.sh.