PII Redaction
When designing zero-knowledge audit trails, you need to decide how to handle Personally Identifiable Information (PII) and Protected Health Information (PHI). Volidator provides two distinct strategies:
| Requirement | Strategy | Configuration | How it works |
|---|---|---|---|
| PII must never leave your servers, and showing placeholder labels in the dashboard is acceptable. | Static Redaction | redactKeys |
The SDK permanently strips fields, replacing them with a static redaction string before encrypting. |
| PII must never leave your servers, but the dashboard must display real names to authorized viewers. | JIT Hydration | referenceKeys |
The SDK replaces values with non-sensitive reference IDs, which the host app resolves on the fly inside the browser. |
| Store PII/PHI in Volidator, but guarantee Volidator cannot read it. | End-to-End Encryption (E2EE) | None (Default) | Fields are encrypted with AES-GCM client-side. Volidator stores the ciphertext. Even if Volidator is compromised, the data is mathematically unreadable without your local keys. |
[!NOTE]
Zero-Knowledge Guarantee: In all three scenarios, Volidator cannot read your data. There is zero chance of a data breach exposing your plaintext payloads as long as your Data Encryption Key (DEK) is not compromised.
Static Redaction (redactKeys)
Section titled “Static Redaction (redactKeys)”redactKeys lets you replace sensitive field values with a [REDACTED:fieldName] placeholder before encryption. The blind index for that field is still computed from the original value, so queries still work. The stored ciphertext never contains the plaintext.
Configure redactKeys
Section titled “Configure redactKeys”const volidator = new VolidatorClient({ apiKey: process.env.VOLIDATOR_API_KEY!, encryptionKey: process.env.VOLIDATOR_ENCRYPTION_KEY!, redactKeys: ['actor', 'metadata.email', 'metadata.ssn'],});Top-level fields
Section titled “Top-level fields”Supported top-level fields: actor, target.
// Inputawait volidator.log({ action: 'account.login', target: 'account_456',});
// Encrypted payload contains:// { actor: "[REDACTED:actor]", action: "account.login", target: "account_456" }// actorBlindIndex is still computed from "[email protected]"Metadata fields
Section titled “Metadata fields”Use dot notation to target fields inside metadata.
const volidator = new VolidatorClient({ apiKey: process.env.VOLIDATOR_API_KEY!, encryptionKey: process.env.VOLIDATOR_ENCRYPTION_KEY!, redactKeys: ['metadata.email', 'metadata.phone', 'metadata.dob'],});
await volidator.log({ actor: session.userId, action: 'patient.view', metadata: { phone: '+1-555-0100', // stored as [REDACTED:phone] dob: '1985-03-12', // stored as [REDACTED:dob] appointmentId: 'appt_789', // not redacted — no rule for this key },});Only string metadata values are redacted. Numbers, booleans, and objects are passed through unchanged. Apply your own stringification if needed before logging.
Blind index preservation
Section titled “Blind index preservation”Redaction happens after blind index computation. The SDK processes in this order:
- Compute
actorBlindIndexfrom the originalactorvalue. - Compute
actionBlindIndexfrom the originalactionvalue. - Compute
targetBlindIndex(if target is provided) from the originaltargetvalue. - Compute
tenantBlindIndex(if tenant is provided) from the originaltenantvalue. - Apply
redactKeysandreferenceKeyssubstitutions to the payload. - Encrypt the redacted/referenced payload.
- Send
{ actorBlindIndex, actionBlindIndex, targetBlindIndex, tenantBlindIndex, encryptedPayload }.
This means filters still work even when fields are redacted.
Compliance notes
Section titled “Compliance notes”Redaction reduces stored PII but does not eliminate it entirely:
- Action names (not currently redactable) may contain identifiers if you name actions like
user:[email protected]. - Blind indexes are deterministic. If an attacker has the key, they can confirm whether a specific value is in the index.
For HIPAA and GDPR compliance, use redactKeys for all PHI/PII fields and keep your encryption key in a secrets manager with rotation policies.
Reference-Based Redaction (JIT Hydration)
Section titled “Reference-Based Redaction (JIT Hydration)”For audit dashboards where compliance requires that PII/PHI never leave your boundary, but human auditability requires displaying actual names (e.g., “John Doe exported logs” instead of [REDACTED:actor]), use JIT Hydration.
With JIT Hydration:
- The SDK receives a structured
{ id, pii }payload. - The search index is built using
pii, but only[REF:id]is stored. - The host page hydrates the display name on the fly via a React hook.
For a complete walkthrough, see the JIT Hydration Guide.
Related
Section titled “Related”- VolidatorClient reference — full constructor options
- JIT Hydration Guide — JIT Hydration configuration
- Zero-Knowledge Architecture — what gets encrypted and when