← Soundcheck Insights
Security

How the platform protects your data

A candid inventory of what’s actually shipped — including the gaps we haven’t closed yet. We’d rather be specific than wave around “enterprise-grade” copy.

Last updated · June 2026

Identity & access

Authentication
Clerk (SOC 2 Type II provider). Google OAuth + email/password, MFA support, password policy, brute-force throttling, and session management all owned by Clerk. We never see a password.
Approval gate
Self-signups land in a pending state and can't reach the platform until a super-admin approves them — a stray Google account can't auto-provision itself in.
Webhook integrity
Clerk and Inngest webhooks are signature-verified (svix / HMAC) before any database write.

Authorization & multi-tenant isolation

Three-tier role model
super_admin (Soundcheck staff), admin (agency operator), user (agency seat-holder). Roles are enforced server-side; client-side checks are UI sugar only.
Scoped queries by default
Every database read for a tenant resource — research, focus groups, personas, dashboards — flows through a single helper that filters by agency and assignment. No raw queries bypass it.
Layout-level gates
Direct URLs to super-admin or admin-only routes are gated at the layout layer, so a stale link or a guess can't reach a page outside the visitor's role.
Cross-agency rejection
Server actions validate that every resource they touch belongs to the operator's own agency before mutating. Cross-agency operations require a super-admin-only path.
Soft delete
Tenant resources carry a deleted-at flag; queries always filter. Accidental deletes are recoverable. Hard delete requires direct DB access.

Data isolation between operators

Every operator’s data is siloed at the schema layer (every tenant table carries an agency_id foreign key). On top of that schema isolation, §7.3 of the Trial Tier Terms makes the following commitments contractually binding:

  • We will not use one operator’s confidential information or client data to develop products competing with that operator’s individual business.
  • Aggregated learnings used to improve the Platform are anonymized to a level where no specific operator or end-client is identifiable.
  • Internal admin access to operator data is limited to personnel whose access is reasonably necessary, all bound by written confidentiality.
  • Internal admin-access logs are maintained and producible on a good-faith request.

Incognito Mode per-project lockdown

Some operators run engagements for clients in regulated industries — finance, healthcare, defense — where the client contract prohibits anythird party, including Soundcheck staff, from inspecting the project’s content. For those cases, every project carries an operator-flippable Incognito Mode toggle. Best practice is to enable it at intake time, before any generation runs; the operator can also flip it later from the project Settings panel.

What gets locked
When Incognito Mode is ON, Soundcheck super-admins cannot open the project's detail page, dashboard, reports, personas, share links, bot conversations, or any file downloads. The lockout is enforced server-side, before any content reaches the rendered response.
What stays visible
The project's existence, the owning agency, its product type, status, and aggregate token counts remain visible to super-admins for billing reconciliation and invoicing — but nothing beyond metadata.
Set at intake or later
Operators see the Incognito Mode toggle on every New-Project form. Setting it there means no Soundcheck staff ever has visibility on the project content. Toggling later still blocks future reads but is a weaker guarantee to the client.
Who can flip it
Only the project owner or an admin of the owning agency can toggle Incognito Mode. Super-admins cannot disable an operator's lockdown — once on, only the operator's own team can take it off.
Strategic projects inherit
When the operator upgrades an Incognito research project into a GoGlobal or Scale engagement, the strategic project starts Incognito too. The operator can also force-on at create time.
Audit
Every flip is recorded with actor and timestamp. The operator's compliance officer can produce the trail on request.
Limitation
Incognito Mode gates human read access. The platform's own automated workers (research generation, dashboard distillation, monthly updates) still run inside the project — that's how the deliverable gets produced. The data never reaches a human at Soundcheck while the flag is on; it only reaches Anthropic's API under their no-training agreement (see AI handling below).

Transport, storage, and secrets

TLS in transit
All traffic over Vercel TLS 1.2+. Database connections use Neon TLS. File uploads go to Vercel Blob via signed HTTPS URLs.
At-rest encryption
Neon Postgres encrypts at rest with AES-256. Vercel Blob encrypts at rest.
Secrets management
All API keys (Clerk, Anthropic, Inngest, Postgres, Blob, share-link signer) live in Vercel environment variables. Nothing is committed to source. The local .env.local file is gitignored.
Anthropic API key isolation
Server-side only. Every Claude call runs in Inngest functions or server actions; the key is never reachable from a browser.

File uploads & parsing

Direct-to-Blob uploads
Files go straight from the operator's browser to Vercel Blob via short-lived signed URLs. The platform never proxies the bytes through its own functions.
Server-side parsing
PDFs, DOCX, XLSX, PPTX, images — all extracted server-side. Raw binaries stay in Blob; only extracted text and relevant metadata flow into Claude prompts.
Mime / size validation
Validated at upload time and again at parse time.

Public sharing (branded dashboards)

Non-guessable URLs
Public share links use a 12-character random slug — 71 bits of entropy, infeasible to enumerate.
Optional password gate
Per-share bcrypt(12)-hashed password. After entry, an HMAC-signed cookie-bound session.
Disable on demand
Disabling a share returns 404 immediately; the slug stays bound to the project so re-enabling is instant.
No platform chrome on shared views
Public viewers see only the branded dashboard — no operator nav, no edit controls, no feedback chat.
Incognito Mode beats sharing
If a project is Incognito Mode AND the share is enabled, the public share still works for end-clients with the slug — the lockout is for Soundcheck staff, not the operator's audience.

Telegram bot integration

Each Market Research, GoGlobal, Scale, Customer Journey, Virtual Focus Group, and Persona Panel project can expose a Telegram bot deep-link so end-clients can ask questions about the deliverable conversationally. The bot is a thin wrapper on top of the same Anthropic call path the platform already uses; no separate data store, no third-party AI provider.

Per-conversation session
Every Telegram chat is bound to one share slug and one Telegram user ID. The bot only ever sees that one project's content. Sessions are tracked server-side in a telegram_sessions table for audit.
Webhook integrity
Telegram webhooks are signature-verified before any database read. An unsigned request from anywhere else hits a 403.
Operator-only audit log
Every Telegram message — inbound and outbound — is persisted in telegram_messages and visible to the project owner via the Bot Conversations panel. The operator can see exactly what their client asked and what the bot answered.
Gating
For MR / GoGlobal / Scale, the bot deep-link is only minted when (a) the project has an active monthly subscription, or (b) the operator is an admin/super-admin needing internal Q&A on the project. The bot won't accept conversations on locked share links.
Same data boundary
The bot can answer about reports + every monthly update so far; it has no access to other operators' projects, agency-wide context, or content outside the share slug.

Monthly Update Subscription

Operators can subscribe an engagement to a recurring monthly refresh. Once a month, a worker runs Tavily + Anthropic web search to surface what changed in the market, drafts a short markdown diff, renders it as a branded DOCX, and merges the delta into the project’s dashboard. The data path is the same single-tenant path the original engagement used — no operator’s data ever joins another operator’s refresh run.

No cross-tenant pooling
Monthly runs are queued by project ID. Each run reads only that project's intake, reports, prior updates, and dashboard payload; nothing from a sibling engagement, even within the same agency.
External search calls
Tavily queries carry no project, agency, or client identifiers — only the topic terms derived from the project's own watch areas. Tavily's privacy policy applies to those queries.
Cancellation = pro-rata + bot context truncation
Cancelling a subscription pro-rates the current month's charge and stops further runs. Already-generated monthly DOCX rolls remain downloadable forever; the Telegram bot loses the post-cancel monthly context the day after cancellation.
Incognito Mode applies here too
If the parent project is Incognito Mode, the monthly DOCX, dashboard delta merge, and bot timeline are all blocked from super-admin view in the same way as the base project.

Pricing & billing integrity

Operators can’t retroactively re-tag completed work to dodge invoiced amounts. Billing is a property the platform actively protects:

Snapshot model
Every project, at creation, snapshots its tier, the operator-cost rate, and the MSRP. Subsequent tier changes never retroactively re-bill.
Tier change audit log
Every transition recorded with actor, timestamp, prior/new tier, and a reason. Visible on the agency detail page.
Frozen Reference Pricelist (Founding Cohort)
Founding Cohort agencies get a frozen MSRP snapshot at activation; future Soundcheck MSRP hikes never retro-price them for the lifetime of their Founding participation.
Month close
Billing is month-by-month (no quarterly minimums). Once a billing month closes, line items are frozen into snapshots and uneditable. Reopening requires an explicit super-admin action.
Incognito Mode + billing
Incognito Mode projects still appear in monthly rollups for the owning agency. The rollup uses agency-scoped joins that don't read project content — only count + price snapshot fields — so billing reconciles without ever opening a locked project.
Partnership Agreement record
The long-form Operator Partnership Agreement (signed off-platform via Docusign) is recorded per agency: signed-by name, signed date, optional executed-PDF blob, notes.

Legal record-keeping

Built for litigation-readiness — not because we expect litigation, but because the alternative is reconstructing acceptance trails from logs after the fact:

Per-user T&C acceptance
End User Terms (every user) and Trial Tier Commercial Terms (admins of Trial-tier agencies). Each acceptance captures: ISO-8601 UTC timestamp, IP address, user-agent string, exact version accepted.
Version re-prompt
When we publish a new version, every user whose accepted version no longer matches is re-prompted on their next platform load. Prior acceptance stays on record as historical evidence.
Admissibility framework
Acceptance is recorded electronically pursuant to the Florida Uniform Electronic Transaction Act (Fla. Stat. ch. 668, Part I) and the federal E-SIGN Act (15 U.S.C. § 7001 et seq.).
Litigation export
The super-admin user audit page renders a printable per-user record with full timestamp, IP, user agent, accepted version, and the framework citations. CSV export covers every audit field for hold-and-produce workflows.

AI handling

No model training on prompts
Anthropic's standard API agreement does not use API prompt or response content to train models. Operator and client data sent to Claude stays operator-confidential.
Synthetic personas
Personas referenced in any deliverable are synthetic constructs grounded in research; they do not represent or correspond to any real, identifiable natural person. Platform outputs do not contain personal data of real natural persons within the meaning of applicable data-protection laws (Trial Terms §3.4).
Per-engagement context isolation
Each Claude call is scoped to one operator's project. We don't pool operators' uploads or context across tenants.

Anonymized engagement pool (platform-only)

Completed engagements are distilled into a tag-normalized anonymized record (no agency, no brand, no client name, no verbatim text — only categorical signals like archetype tag, friction tag, concept-pattern tag, and score band). This pool feeds platform-internal benchmarks and prompt improvements. It is never exposed to another operator as a competitive advantage on their own engagements; that path is contractually prohibited by §7.3(c)(ii) of the Trial Terms and Founding Cohort Terms.

What gets stored
Categorical tags only. No client names, brand names, agency identifiers, verbatim quotes, persona names, or operator-brief text ever reaches the pool.
Origin hash
Each distilled row links back to the source only through a SHA-256 hash combining the agency ID, resource ID, and an environment-protected salt. Without the salt — which lives only in Vercel env — the hash is computationally one-way.
k-anonymity ≥ 5
Every aggregate-query layer enforces a minimum of five contributing engagements per segment. A 'premium açaí + Brazil' segment with only one engagement returns null rather than the row.
Quarterly re-identification audit
A scheduled cron attempts to re-identify rows by joining the anonymized data against public registries. Any row that resolves uniquely is flagged for purge and the distillation prompt is patched.
Operator opt-out
Two levels: agencies can set their default contribution mode to 'none', 'platform_only' (default), or 'full_pool'. Operators can also flip a per-engagement opt-out — that engagement is excluded from the pool even if the agency default permits extraction. Incognito Mode projects are excluded automatically.
Stage 2 and Stage 3 are not live
Cross-operator benchmarks (Stage 2) and external 'Industry Reports' (Stage 3) would require additional contractual amendments per Soundcheck's commercial terms; neither is shipped. The current pool is Stage 1 — platform-internal only.

Operational observability

Function logs
Every server action and route handler is logged with status and duration via Vercel.
Inngest run logs
Every background pipeline (research, focus group, customer journey) is durable, retriable, and inspectable on the Inngest dashboard with per-step inputs and outputs.
DB audit fields
Every tenant row carries created-at / updated-at / deleted-at, plus a tier-change history table for agencies.

What we don't handle (by design)

No payment data on the platform
Operators are billed off-platform via wire/ACH on a NET-15 invoice cycle (Trial Terms §4.4). No credit cards, no Stripe vault, no PCI scope. That's a feature.
No real-person personal data in deliverables
The methodology generates synthetic personas. Deliverables don't contain personal data of identifiable natural persons under GDPR / CCPA. Materially smaller data-protection surface.

Build-time security gates (June 2026)

Three automated gates run on every push and pull request against main, plus on scheduled cadences. Results land in the GitHub Security tab where the founder reviews them during normal development.

CodeQL static analysis
GitHub's first-party scanner, security-extended query suite for JavaScript and TypeScript. Catches code-level vulnerabilities (SQL injection, path traversal, prototype pollution, missing auth, hardcoded credentials). Runs on every push, every PR, and weekly Monday 06:00 UTC against the main branch.
First CodeQL baseline result (June 9, 2026)
5 alerts on first pass — 4 cleared in same release (2 Python ReDoS in dev-only env parsers, 1 missing-permissions in a workflow file, 1 JS prototype-pollution-utility on a zod-error accumulator). 1 polynomial-ReDoS alert deferred for surgical fix with GitHub Security tab context. Zero critical, zero high-impact runtime alerts.
Secret scanning + push protection
GitHub Advanced Security secret scanning is on; push protection actively BLOCKS pushes that would commit detected secrets (API keys, tokens, credentials) before they enter git history. Risk-Assessment baseline export June 9, 2026: zero secrets in repository history.
Dependency vulnerability audit
`pnpm audit --prod --audit-level=high` on every push, every PR, and a daily 09:30 UTC cron. Fails the build on high or critical advisories in the production dependency tree. Dev-tool advisories surface in logs but don't block.
Dependabot
Auto-opens grouped weekly PRs for outdated npm dependencies (production + dev) and monthly PRs for pinned GitHub Action versions. Security-advisory PRs are filed separately and prioritised.
Branch protection (now hard-enforced)
On the main branch since the June 2026 upgrade to GitHub Team. Required status checks (CodeQL Analyze + pnpm audit) must pass before merge. Linear history. No force-push. No deletion. Bypass is logged for audit.
Vulnerability Disclosure Policy
Public safe-harbor at /security/disclosure paired with /.well-known/security.txt per RFC 9116. Acknowledgements wall on the same page.

Written policies (June 2026)

The two written security policies referenced by the platform live in the repository alongside the application code, version-controlled per change, and are provided in writing to any customer that requests them as part of vendor due diligence:

  • Incident Response Plan — roles, severity tiers, triage / contain / eradicate / notify phases, 72-hour customer breach-notification commitment, post-incident review template.
  • Data Retention Schedule — per-class retention for uploaded files, database rows, deliverables, Telegram sessions, Vercel and Inngest logs, Anthropic API artifacts, anonymized pool, billing, and legal records, plus the deletion-on-request workflow (acknowledge ≤ 1 business day; execute ≤ 30 days; confirm in writing).

What we haven't done yet

If a client’s security team asks, here’s what we answer straight rather than dodge:

  • No SOC 2 / ISO 27001 attestationof our own. Clerk, Vercel, Neon, and Anthropic are SOC 2; the platform on top isn’t certified. On the roadmap; not signed-and-attested today.
  • No third-party penetration test conducted to date. Continuous CodeQL + dependency audit run on every push as a partial substitute (see Build-time security gates above).
  • No paid bug bounty program. A public Vulnerability Disclosure Policy with safe harbor exists (see /security/disclosure); cash rewards are not currently offered.
  • Public share routes are rate-limited at 60 req/min per IP (June 2026) via Routing Middleware. Authenticated platform routes are not yet throttled at the edge — handler-level throttles are not implemented.
  • 2FA is supported by Clerk and enforced on every Soundcheck super-admin account (June 2026). Not yet enforced platform-wide on operator accounts; per-agency enforcement available on request.
  • Content Security Policy + strict transport + frame / referrer / permissions headers shipped June 2026 (HSTS preload-eligible, X-Frame-Options DENY, CSP with explicit allowlist for Clerk / Vercel Analytics / Gamma, Permissions-Policy denying camera / microphone / geolocation / payment / USB / motion sensors / FLoC).
  • No formal GDPR data-processing agreement templatepublished yet. The platform is built for EU agencies among others, and Trial Terms §3.4 materially reduces the GDPR surface; a published DPA template is a near-term to-do. The Anthropic DPA + Standard Contractual Clauses are in force via Anthropic’s Commercial Terms of Service (auto-incorporated per Anthropic’s March 2026 policy).

Reporting a security issue

If you spot something — a vulnerability, an unintended behaviour, data appearing where it shouldn’t — write to info@soundcheckinsights.com with the subject line Security report. We prioritise these above everything else and will acknowledge within one business day. Full safe-harbor terms + scope live in our Vulnerability Disclosure Policy (paired with /.well-known/security.txt).

For legal questions about these terms, write to valter@soundcheckinsights.com.

Soundcheck Insights LLC · Florida, United States · © 2026