Zero-Knowledge Architecture

How Your Anonymity is Technically Protected

Plain English explanation of our zero-knowledge architecture. We built GhostRate so that even we cannot identify who said what.

100%

invite lists deleted after sending

0

PII linked to any response

8

layered anonymity protections

What IS collected

  • Your response text (after voice neutralization)
  • The date (day only) you responded
  • Which board you responded to
  • Rating scores (1–5 scales)

What is NEVER collected

  • Your name or email address
  • Your IP address
  • Exact timestamp (time of day)
  • Browser fingerprint or device ID
  • Submission order or sequence number
  • Any link between your identity and your response

The Promise

GhostRate guarantees that no person — not your employer, not our engineers, not our database administrators — can trace a response back to the person who wrote it. This isn't a policy promise. It's an architectural guarantee. The data simply does not exist to make the connection.

Eight layers of protection

Every response passes through all eight. No shortcuts.

1

The Invite List

When you're invited to provide feedback, your email address is used only to send you the invitation link. The moment all invites are sent, the entire email list is permanently deleted from our database. Your invitation link contains a random token — there is no record that connects this token to your email.

Technical note: Invite tokens are generated using cryptographically secure random bytes. The mapping table (email → token) is destroyed before the first response can arrive.

2

The Identity Firewall

GhostRate uses an architectural boundary called the Identity Firewall. When you submit your response, the system validates your token, then destroys the token before saving your response. These two operations happen on separate sides of the firewall — your identity is verified, then immediately forgotten.

Think of it like a bouncer at a club who checks your ID, lets you in, then immediately forgets your name. The bouncer knows you were allowed in, but cannot tell anyone who you are.

Technical note: Token validation and response storage use separate database transactions. The token is invalidated in Redis before the response is persisted to PostgreSQL.

3

The Threshold System

Results are locked until a minimum number of responses arrive (the "anonymity threshold"). This prevents the scenario where only one or two people respond and their identity becomes obvious by process of elimination. The default threshold is 5 responses, and organizations can set it higher.

Technical note: The threshold check is enforced at the API level. The analytics endpoints return empty results until the threshold is met, regardless of client-side logic.

4

Timestamp Protection

We only store the date you responded — never the exact time. If your manager knows you usually answer emails at 2:47 PM, they cannot use that pattern to identify your response. All responses from the same day look identical in terms of timing.

Technical note: DATE type (not TIMESTAMP) — stores only YYYY-MM-DD.

5

Response Randomization

Responses are displayed in a random order every time results are viewed. There are no sequence numbers, no "Response #1 was first" patterns. This prevents correlation attacks based on submission timing or response ordering.

Technical note: ORDER BY RANDOM() on every analytics query.

6

Voice Neutralization AI

Everyone has a unique writing style. Your manager might recognize "that sounds like something Alex would say." GhostRate uses AI-powered voice neutralization to strip identifiable writing patterns from text responses — normalizing vocabulary, sentence structure, and idioms while preserving the meaning.

Technical note: Voice neutralization runs before the response is stored. The original text is never persisted — only the neutralized version is saved.

The Identity Firewall — visualized

Two separate systems that never share state.

identity-firewall.ts — request lifecycle

Identity Side

const token = request.body.token
await redis.validate(token)
await redis.del(token)
✓ token destroyed
FIREWALL

Response Side

// no token reference
const clean = neutralize(text)
await db.save({ clean, date })
// identity: undefined

Invite list deletion — step by step

The sequence of events when you receive an invitation.

1

Board owner imports your email address

Your email is briefly stored in memory to generate invite links. It is never written to permanent storage.

2

A unique random token is generated per recipient

Each token is a 256-bit cryptographically random string. Only the token is stored — your email is not associated with it.

3

Invitations are sent

Emails are dispatched. The invite link contains only the token — your email address is not embedded.

4

Email list is permanently deleted

The entire invite list is hard-deleted from the database. No soft-delete, no audit trail. The mapping is gone forever.

5

You respond — identity is already gone

By the time you click the link, there is no record connecting your token to your email. Anonymity is structural, not promised.

Voice Neutralization AI

Everyone has a unique writing style. Your manager might recognize "that sounds like something Alex would say." GhostRate uses AI-powered voice neutralization to strip identifiable writing patterns from text responses — normalizing vocabulary, sentence structure, and idioms while preserving the meaning.

Original — identifiable

"Honestly, the stand-ups are kinda pointless tbh, we literally just repeat what's in Jira. I always zone out lol"

// original text — never stored

Neutralized — could be anyone

"The daily stand-up meetings feel redundant — they often cover information that is already tracked in the project management system."

// stored version — meaning preserved, voice removed

Technical note: Voice neutralization runs before the response is stored. The original text is never persisted — only the neutralized version is saved.

For the Technically Curious

Architecture at a glance

Stack

NestJS + PostgreSQL + Redis

Token generation

crypto.randomBytes(32)
256-bit entropy

Identity Firewall

Separate service boundary
no shared state

Invite deletion

Hard DELETE
no soft-delete or audit trail

Timestamp

DATE type only
stores YYYY-MM-DD

Response ordering

ORDER BY RANDOM()
every query

Voice neutralization

LLM-based rewriting before persistence — original text is never stored

Verify It Yourself

Every GhostRate board includes a transparency report accessible to respondents. This report shows the exact anonymity guarantees in effect for that board, including what data is collected, the threshold setting, and whether voice neutralization is enabled. You can verify the protections before you respond.

Transparency report

Every board includes a public transparency page showing exactly what is and isn't collected.

Check before you respond

View the threshold setting and all active protections before submitting a single word.

Public architecture docs

Our architecture documentation is public. We're working toward an open-source audit of our core anonymity layer.

Ready to collect honest feedback?

Start with our free plan. No credit card required.