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.