Security

Engineered for
conversations that matter.

TiQ operates inside your most sensitive professional conversations. Security isn't a feature we added — it's a constraint we designed around from the start.

All systems operational. Authentication, transcription pipeline, LLM routing, and WebSocket layer.
Updated 2026-03-11

Three architectural decisions
that define our security model.

Minimal attack surface
The most secure data is data that doesn't exist. TiQ stores no audio, no transcripts, and no AI outputs. A breach of our backend exposes account metadata — not meeting content.
By design
Mutual authentication
Every session requires a signed short-lived token issued at session start. WebSocket connections that cannot present this token are rejected before any data is processed.
Enforced
ID-only observability
Our backend logs contain session IDs, latency metrics, and status codes — never transcript text, never suggestion content. An attacker with log access learns nothing about your conversations.
Enforced

Every session is authenticated.
Every WebSocket is gated.

The authentication flow is designed so that an unauthenticated connection cannot reach the audio pipeline under any circumstance.

1
Identity verification via Clerk
User session is verified via Clerk JWT before any session-related endpoint responds. Unauthenticated requests receive 401 with no information leakage.
POST /session/start
Authorization: Bearer <clerk_jwt>
→ 401 if invalid
2
Short-lived signed WS token issued
Session start returns both a session_id and a signed ws_token with a 300-second TTL. The token is HMAC-signed server-side and cannot be forged client-side.
{ session_id,
   ws_token, // signed
   expires_in: 300 }
3
WebSocket requires token on connect
The WebSocket handshake must present the ws_token as a query parameter. Connections without a valid, unexpired token are closed immediately — before any frame is read.
wss://backend/stream
?session_id=sess_...
&token=<ws_token>
4
Per-session and per-IP rate limiting
Each session_id is rate-limited independently. IP-level rate limiting prevents brute-force token attempts. Limits are enforced before any session state is accessed.
// limits
100 req/min per IP
1 WS per session_id
5 failed attempts → block
5
Session token expires and is discarded
On session end — whether explicit or by timeout — the session token is invalidated. Reconnection requires a new /session/start call and a fresh token. There is no persistent session credential.
on session_end:
 token.invalidate()
 buffer.clear()
 state.teardown()

BYOK keys are handled
with strict discipline.

An API key leak is a product-ending trust event. Every engineering decision around key handling was made with that outcome in mind.

Frontend key handling
The API key input field is treated as a credential from the moment the user types it.
Key stored in React component state only — never localStorage, never sessionStorage
Input field has autocomplete="off" and data-analytics-exclude
Content Security Policy headers prevent XSS from reaching the input field value
Analytics tools (PostHog, Sentry) are explicitly prevented from capturing key input field values
// Key input — hardened
<input
  type="password"
  autocomplete="off"
  data-analytics-exclude
  onChange={setKey} // state only
/>
Backend key handling
Once the key reaches the backend, the same discipline applies throughout the session lifecycle.
Key held in session object memory only — never written to Postgres, Redis, or any log sink
Central logger throws an exception if any log call attempts to write a credential field
Key is passed directly to the LLM SDK — it is never serialized, stored, or forwarded elsewhere
Session teardown explicitly nulls the key reference before deallocating the session object
// logger.js — enforced
if (data.apiKey || data.key) {
  throw new Error(
    'Credential in log call'
  );
}
Content Security Policy
The frontend enforces a strict CSP that eliminates the most common XSS injection vectors.
No inline scripts or eval — all JS must be from trusted sources
No external script loading from non-allowlisted origins
Strict-Transport-Security enforced — no HTTP fallback
Content-Security-Policy:
 default-src 'self';
 script-src 'self';
 connect-src 'self'
   wss://backend
   api.openai.com;
Chrome Extension isolation
The Chrome extension operates in a strict isolation model — it cannot be used to exfiltrate data from the page.
Manifest V3 — service worker model, no persistent background page
Extension only has access to tab audio — no DOM access on meeting tabs
Content scripts are scoped minimally — no access to page JavaScript context
Extension to backend communication uses the authenticated WebSocket only

Every hop is encrypted.
No exceptions.

Conversation audio travels across multiple service boundaries. Each one uses TLS or WSS. There is no plaintext hop in the pipeline.

Hop What travels Protocol
Extension → Backend
Raw audio chunks (100ms), chunk_seq, session_id. Authenticated WebSocket. No transcript content at this stage.
WSS / TLS 1.3
Backend → Deepgram
Audio stream forwarded for transcription. No conversation metadata, no session context. Deepgram returns final transcript text over WSS.
WSS / TLS 1.3
Backend → LLM API
Prompt including transcript window and session context. HTTPS POST to OpenAI or Anthropic. Response is suggestion JSON — never stored after delivery.
HTTPS / TLS 1.3
Backend → Dashboard
Structured suggestion events over the authenticated WebSocket. Only confidence-gated outputs are sent. Raw transcript is never forwarded to the browser.
WSS / TLS 1.3
In-process (backend)
Transcript buffer, trigger gate, prompt assembly, and LLM orchestration happen within a single Node.js session object. No inter-process communication, no network hop.
In-memory

Vendors chosen for
security posture, not just convenience.

// Authentication
Clerk
User authentication and session management. Handles JWT issuance, MFA, and session lifecycle. TiQ never stores passwords or session tokens directly.
SOC 2 Type II GDPR
// Transcription
Deepgram
Streaming speech-to-text via Nova-3. Audio is processed in real time and not retained. TiQ uses Deepgram's API under a data processing agreement.
SOC 2 Type II HIPAA eligible
// Backend hosting
Railway
Node.js backend deployed on Railway. Isolated container per deployment. No shared compute with other tenants at the session level.
SOC 2
// Database
Railway Postgres
Stores account data, session metadata (duration, persona type, timestamp), and entitlements. No transcript or suggestion content. Encrypted at rest.
Encrypted at rest TLS in transit
// Payments
Stripe
Payment processing and subscription management. TiQ never stores card data. Stripe handles PCI DSS compliance entirely.
PCI DSS Level 1
// LLM providers
OpenAI / Anthropic
LLM inference providers. API calls made over HTTPS. For BYOK track, the user's own API key and account terms govern data handling. For Managed track, TiQ's enterprise agreement applies.
SOC 2 Type II

What's live, what's building,
what's planned.

We're a beta product. These are the security measures in place now, actively being built, and on the roadmap.

Auth
Mutual authentication — signed WS token
Session start issues HMAC-signed token. WebSocket rejects connections without valid token.
Live
Logging
Log redaction — IDs only, never content
Central logger enforces ID-only policy. Throws exception on credential or content fields.
Live
Keys
BYOK key hardening — React state only, CSP enforced
API keys held in component state, CSP headers prevent XSS capture, analytics excluded.
Live
UI
Frontend event coalescing — no raw transcript to browser
200ms event coalescing. Dashboard receives structured suggestion events — never raw transcript.
Live
Resilience
Redis session metadata — survive backend restarts
Metadata-only session state in Redis with TTL. No transcript or suggestion content persisted.
Building
Audit
Independent security review
Third-party review of authentication layer, key handling, and log redaction enforcement.
Planned
Enterprise
SOC 2 Type II audit
Formal audit covering security, availability, and confidentiality trust service criteria.
Planned
Found something?
Tell us directly.
We take security reports seriously. If you've found a vulnerability — in the authentication flow, the API key handling, the WebSocket layer, or anywhere else — please report it privately before public disclosure. We'll respond within 48 hours and keep you updated throughout the resolution.
PGP key available on request
Response SLA: 48 hours
In scope
Authentication bypass or token forgery
API key exposure or exfiltration paths
WebSocket session hijacking
Log injection that leaks conversation content
XSS vulnerabilities on the dashboard or setup screen
CSRF on session management endpoints
Chrome extension content script vulnerabilities
Out of scope
Attacks requiring physical access to user device
Vulnerabilities in third-party dependencies without an exploitation path
Social engineering attacks against TiQ employees
Security by architecture

Start a session you
can trust completely.

The security model is built into the pipeline — not bolted on. Verify the claims. Ask the hard questions. Then start a session.