How we store, encrypt, isolate, and protect your data. Built for the most paranoid security teams.
Kataloop uses PostgreSQL (hosted on Neon) with strict tenant isolation. Here's how we structure data to ensure security and anonymity.
Complete data isolation between companies
Every query includes a tenantId filter. Row-level security (RLS) ensures Company A can never access Company B's data.
-- All queries automatically filtered by tenant
SELECT * FROM rides
WHERE tenantId = @currentTenantId -- Enforced at application layer
AND teamId = @managersTeamId;
-- Row-Level Security Policy (PostgreSQL)
CREATE POLICY tenant_isolation ON rides
USING (tenantId = current_setting('app.current_tenant_id'));model Tenant {
id String @id @default(cuid())
name String // "Acme Corp"
domain String @unique // "acme.com"
saltSecret String // Company-specific hash salt
kAnonymity Int @default(5) // Minimum threshold
dataRegion String @default("us-east-1")
createdAt DateTime @default(now())
// Relations
teams Team[]
participants Participant[]
rides Ride[]
}Security Note: The saltSecret is unique per company, making hash comparisons across tenants impossible.
model Participant {
participantPid String @id @default(cuid()) // Internal reference
hashedHrId String // bcrypt(hrId + salt) - IRREVERSIBLE
currentAlias String // "Brave Lion" - rotates per submission
tenantId String
teamId String?
createdAt DateTime @default(now())
lastActiveAt DateTime @updatedAt
// Relations
tenant Tenant @relation(fields: [tenantId])
team Team? @relation(fields: [teamId])
rides Ride[]
@@index([tenantId])
@@index([hashedHrId, tenantId]) // For deduplication only
}What We Store: Cryptographic hash (irreversible), rotating pseudonym, tenant/team association.
What We DON'T Store: Real HR ID, email, name, IP address, device fingerprint.
model Ride {
id String @id @default(cuid())
participantPid String // Links to participant (internal only)
sessionAlias String // Alias at time of submission
tenantId String
teamId String?
// Content (encrypted at rest)
conversation Json // Full feedback content
theme String? // AI-detected theme
sentiment Float? // -1 to 1
// Anonymized output (shown to managers)
anonymizedSummary String? // AI-generated, PII stripped
// Metadata
status RideStatus @default(PENDING)
createdAt DateTime @default(now())
// Relations
participant Participant @relation(fields: [participantPid])
tenant Tenant @relation(fields: [tenantId])
@@index([tenantId, teamId])
@@index([tenantId, theme])
@@index([createdAt])
}Manager Access: Managers only see anonymizedSummary,theme, and aggregate counts. The conversation field is never exposed.
model Theme {
id String @id @default(cuid())
tenantId String
teamId String?
name String // "Process Inefficiency"
description String // AI-generated summary
contributorCount Int @default(0) // Must be >= k for visibility
confidence Float // 0-1
suggestedAction String? // AI recommendation
status ThemeStatus @default(PENDING) // PENDING until k reached
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
tenant Tenant @relation(fields: [tenantId])
@@index([tenantId, status])
}K-Anonymity Enforcement: Themes with contributorCount < kAnonymityremain in PENDING status and are never shown to managers.
Unlike "anonymous" tools that still collect identifying metadata:
A high-level view of how data flows through Kataloop's infrastructure.
KATALOOP DATA ARCHITECTURE
============================================================================
EMPLOYEE KATALOOP MANAGER
| | |
| 1. Submit Feedback | |
| ---------------------------> | |
| | |
| 2. Generate Session | |
| Pseudonym | |
| (Brave Lion) | |
| | |
| +------------+------------+ |
| | | |
| | PROCESSING LAYER | |
| | | |
| | - AI Theme Detection | |
| | - K-Anonymity Check | |
| | - PII Stripping | |
| | | |
| +------------+------------+ |
| | |
| v |
| +-------------------------+ |
| | POSTGRESQL DB | |
| | | |
| | Tenant Isolation: | |
| | +-----------------+ | |
| | | tenant_abc | | |
| | | - participants | | |
| | | - rides | | |
| | | - themes | | |
| | +-----------------+ | |
| | +-----------------+ | |
| | | tenant_xyz | | |
| | | - participants | | |
| | | - rides | | |
| | | - themes | | |
| | +-----------------+ | |
| +-------------------------+ |
| | |
| | 3. Aggregated Patterns Only |
| | ------------------------------> |
| | |
| | - Theme: "Process Inefficiency" |
| | - Contributors: 12 |
| | - Suggested Action: ... |
| | |
| | NO individual quotes |
| | NO identity linkage |
| | |
============================================================================
DATA FLOW SECURITY CONTROLS
[Employee] -> [TLS 1.3] -> [Load Balancer] -> [App Server]
|
v
[Encryption Layer]
(AES-256 at rest)
|
v
[PostgreSQL (Neon)]
(Row-level security)
Our security team is available for architecture reviews, penetration testing coordination, and custom compliance assessments.