Secure Email Meets Enterprise Compliance
Client-side compliance copy encryption, DLP scanning, eDiscovery, SSO, and audit logging — without compromising end-to-end security.
Executive Summary
@private.me/enterprise bridges the gap between end-to-end encrypted messaging and enterprise compliance requirements. Organizations get legally admissible eDiscovery, DLP policy enforcement, and audit trails — while users retain information-theoretic security via XorIDA threshold sharing.
Traditional enterprise email security forces a choice: either encrypt messages end-to-end (losing compliance visibility) or route plaintext through a corporate server for DLP and archival (creating a single point of breach). This module eliminates that trade-off.
Compliance copies are encrypted client-side with the organization's RSA-4096 public key before transmission. The Corporate Xail Server stores only ciphertext and can never read message content. Only the compliance officer — holding the private key in an HSM or air-gapped workstation — can decrypt for eDiscovery. Meanwhile, the underlying XorIDA-split message remains information-theoretically secure across multiple channels.
What This Module Does
- Client-Side Compliance Copy Encryption: Hybrid RSA-OAEP (4096-bit) + AES-256-GCM. Plaintext never leaves the device.
- DLP Scanning: Pre-split content scanning against corporate DLP rules (SSN, credit card, confidential markers). Integrates with Proofpoint/Mimecast.
- eDiscovery: Metadata search, legal hold, audit-logged decryption. Compliance officers can export specific messages without accessing the live mail stream.
- Audit Logging: Append-only HMAC-chained audit trail for every compliance action (copy created, search performed, message decrypted, policy changed).
- Retention Policy Enforcement: Configurable min/max retention windows with legal hold override. Automated purge of expired copies.
- Delegation Management: Executive-to-assistant message access delegation with granular permissions (read, reconstruct, export) and time-based expiry.
- SSO Integration: SAML/OIDC assertion validation for enterprise identity federation.
- User Management: Organization user lifecycle (invite, activate, suspend) with role-based access control.
Why Organizations Choose This
| Requirement | Traditional Approach | @private.me/enterprise |
|---|---|---|
| Legal Hold / eDiscovery | Plaintext archive on corporate server | Client-encrypted compliance copies. Zero plaintext exposure. |
| DLP Policy Enforcement | Inline proxy seeing all content | Pre-split client-side scan. Corporate server validates, never reads. |
| Audit Trail | Centralized database (tamperable) | Append-only HMAC chain. Cryptographic integrity. |
| Data Residency / Sovereignty | Single jurisdiction storage | XorIDA shares distributed across borders. Compliance copy in-region. |
| Insider Threat (Admin Access) | Admin sees all archived mail | HSM-protected private key. Compliance officer only. Audit-logged. |
Developer Experience
Three lines of code to add enterprise compliance to any XorIDA-secured message. Client-side encryption happens transparently before the split operation.
Minimal Integration
import { encryptComplianceCopy } from '@private.me/enterprise';
// Encrypt compliance copy with org's public key (client-side)
const result = await encryptComplianceCopy(message, enterpriseConfig);
if (result.ok) {
// Send to Corporate Xail Server (stores ciphertext only)
await submitToCorporateServer(result.value);
}
The compliance copy encryption step happens before XorIDA splitting. The flow becomes:
- User composes message in Xail client
encryptComplianceCopy()creates hybrid-encrypted copy (RSA-OAEP + AES-GCM)- Encrypted copy submitted to corporate server over HTTPS
- XorIDA threshold sharing proceeds as normal (2-of-3 split)
- Shares routed to recipient channels
enterpriseConfig object is only present for users on Corporate Xail Server. Detection is automatic via checkRecipientEnterprise(). No code paths, no conditional imports, no bundle bloat for consumer users.
eDiscovery Query
import { EDiscoveryService } from '@private.me/enterprise';
const eDiscovery = new EDiscoveryService(complianceStore, auditLog);
// Compliance officer searches by metadata (no decryption)
const results = eDiscovery.search({
orgId: 'acme-corp',
senderEmail: 'exec@acme.com',
dateFrom: new Date('2024-01-01'),
dateTo: new Date('2024-12-31'),
});
// Decrypt specific message (audit-logged)
const decrypted = await eDiscovery.exportCopy(
messageUuid,
privateKey,
'compliance-officer@acme.com'
);
if (decrypted.ok) {
console.log(decrypted.value.body); // Original plaintext
}
DLP Scanning
import { submitForDlpScan } from '@private.me/enterprise';
// Client submits content for DLP scan (pre-split)
const scanResult = await submitForDlpScan({
messageUuid,
senderEmail,
recipientEmails,
subject,
body,
contentType: 'text/plain',
attachmentNames: ['contract.pdf'],
}, enterpriseConfig);
if (scanResult.ok) {
if (scanResult.value.action === 'block') {
// DLP policy violation — message not sent
showError('Message blocked by corporate DLP policy');
} else if (scanResult.value.action === 'quarantine') {
// Send but flag for review
warnUser('Message flagged for compliance review');
}
// action === 'allow' — proceed with XorIDA split
}
The Problem
Enterprises face impossible compliance trade-offs with existing secure email solutions. Every option forces a security sacrifice.
The Compliance Trilemma
Organizations must satisfy legal, regulatory, and operational requirements that conflict with end-to-end encryption:
1. Legal Hold & eDiscovery (FRCP, GDPR Art. 17)
Federal Rules of Civil Procedure require preservation of electronically stored information. GDPR Article 17 mandates data retention for legal claims. Organizations must produce searchable, admissible communications on demand.
Existing E2EE solutions: No compliance copy. Messages exist only in user inboxes. Legal hold requires user cooperation. Deleted messages are unrecoverable. Not admissible for regulatory proceedings.
2. Data Loss Prevention (SOX § 404, PCI DSS)
Sarbanes-Oxley Section 404 requires internal controls over financial reporting. PCI DSS prohibits transmission of unencrypted credit card data. HIPAA mandates content inspection for PHI. Organizations must enforce policies on outbound communications.
Existing E2EE solutions: No DLP visibility. Content is opaque to policy enforcement. Employees can exfiltrate PII, financial data, or IP without detection. Compliance violations are discovered only after breach.
3. Audit Trail (SOC 2, ISO 27001, FINRA 4511)
SOC 2 Type II requires tamper-evident logging of all security-relevant events. ISO 27001 Annex A.12.4.1 mandates event logging. FINRA Rule 4511 requires books and records for all communications. Audit logs must prove who accessed what, when.
Existing E2EE solutions: No centralized audit trail. User actions are invisible to compliance. No evidence of access or disclosure. Cannot prove compliance during audit.
Current "Solutions" and Their Failures
| Approach | How It Works | The Failure |
|---|---|---|
| Plaintext Archive on Corporate Server | Route all mail through corporate server; store plaintext in database | Single point of breach. Admin access exposes entire archive. Not end-to-end encrypted. Server compromise = total data loss. |
| Key Escrow (Third-Party Holds Decryption Key) | Encrypt messages; escrow agent stores keys; can decrypt for eDiscovery | Escrow agent is a single point of failure. Government/court can compel key disclosure. Insider at escrow company sees all content. |
| TLS-Only (No E2EE) | Encrypt in transit (HTTPS); store plaintext server-side for compliance | Server breach exposes everything. Cloud provider admin sees plaintext. Not end-to-end encrypted by definition. |
| Client-Side Compliance Copy (Unencrypted) | Client sends plaintext copy to corporate server in parallel with encrypted message | Plaintext compliance copy is a data exfiltration vector. Corporate server compromise exposes all archived mail. DLP sees plaintext in flight. |
| Post-Decryption Server-Side Scanning | Server decrypts messages (has the key), scans for DLP, re-encrypts for storage | Server has decryption key = not E2EE. Single point of compromise. Key extraction attack exposes all past and future messages. |
What Enterprises Actually Need
- Compliance officer-only decryption: eDiscovery without admin access to live mail stream
- No plaintext on corporate server: Compliance copies are ciphertext
- DLP enforcement without DLP visibility: Policy validation without content inspection
- Cryptographic audit trail: Append-only, tamper-evident, HMAC-chained
- Legal hold without user cooperation: Compliance copy immune to user deletion
- Data sovereignty compliance: Shares distributed across jurisdictions, compliance copy in-region
No existing solution delivers all six. Every product compromises at least one requirement. Organizations choose based on which failure they can tolerate.
The Solution
Two independent security layers: XorIDA threshold sharing for the live message (information-theoretic, multi-channel) and RSA hybrid encryption for the compliance copy (stored ciphertext, compliance officer-only decryption).
Dual-Layer Architecture
The key insight: the compliance copy and the live message are cryptographically separate. Compromising one does not compromise the other.
| Layer | Purpose | Security Guarantee |
|---|---|---|
| Live Message (XorIDA 2-of-3) | Secure communication between users | Information-theoretic security. Reconstruction requires 2 of 3 shares. No single point of compromise. |
| Compliance Copy (RSA-4096 + AES-256-GCM) | Legal hold, eDiscovery, audit | Hybrid encryption. Private key held offline by compliance officer. Corporate server stores ciphertext only. |
How Client-Side Compliance Copy Encryption Works
- Organization setup (once): Generate RSA-OAEP 4096-bit key pair. Public key distributed to all clients. Private key stored in HSM or air-gapped workstation held by compliance officer.
- User composes message: Plaintext message body, subject, metadata assembled in Xail client.
- Compliance copy encryption (client-side):
- Generate random AES-256 key (32 bytes) via
crypto.getRandomValues() - Encrypt message body with AES-256-GCM (96-bit IV, authentication tag)
- Encrypt AES key with RSA-OAEP using org's public key
- Assemble ComplianceCopy:
{encryptedContent, encryptedAesKey, iv}
- Generate random AES-256 key (32 bytes) via
- Compliance copy submission: Client sends ComplianceCopy to Corporate Xail Server over HTTPS. Server stores it in encrypted database (double-encrypted: AES in transit via TLS, ciphertext at rest).
- XorIDA splitting proceeds: Original plaintext message split into 3 shares (2-of-3 threshold). Shares routed to recipient channels as normal. No change to core security model.
How eDiscovery Works (Compliance Officer Only)
- Compliance officer searches by metadata: Sender, recipient, date range, subject line. No decryption required. Search happens on server-side encrypted index.
- Officer selects specific message UUID for export: eDiscovery service retrieves ComplianceCopy from database.
- Decryption (offline):
- Officer loads private key from HSM (PIN required)
- Decrypt AES key using RSA-OAEP private key
- Decrypt message content using recovered AES-256-GCM key
- Export plaintext to legal hold system
- Audit log entry created:
ediscovery_exportaction logged with messageUuid, actor email, timestamp. Tamper-evident HMAC chain updated.
How DLP Scanning Works (Without DLP Seeing Content)
This is the controversial part: DLP scanning requires the corporate server to see plaintext. There is no way around this. But we minimize exposure with an explicit opt-in and a time-limited visibility window.
- User composes message in Xail client.
- Client detects enterprise recipient (via
isEnterpriseflag on ContactInfo). - User acknowledges compliance notice: "This recipient is on a corporate Xail server. Content will be scanned for DLP policy compliance. Your organization may retain copies per their compliance policies."
- Client submits DLP scan request to corporate server over HTTPS:
{ messageUuid, senderEmail, recipientEmails, subject, body, // plaintext (TLS-protected) contentType, attachmentNames, } - Corporate server scans content against DLP rules:
- Built-in regex rules (SSN, credit card patterns)
- Confidential markers ("ATTORNEY-CLIENT PRIVILEGE", "CONFIDENTIAL")
- External scanner integration (Proofpoint, Mimecast) via API proxy
- Server returns DLP result:
{action: 'allow' | 'block' | 'quarantine', reason?, ruleId?} - Plaintext is NOT retained. DLP scan request is processed in-memory and discarded. Only the compliance copy (hybrid-encrypted) is stored.
- Client proceeds based on DLP result:
allow— XorIDA split and sendblock— Message not sent, user notifiedquarantine— Send with compliance flag for manual review
Use Cases
Industries where regulatory compliance and secure communication are both non-negotiable.
1. Legal (Law Firms, Corporate Counsel)
Requirements: Attorney-client privilege, ethical walls, eDiscovery for litigation, ABA Model Rule 1.1 technology competence, bar association compliance.
Challenge: Privileged communications must be searchable for discovery but protected from opposing counsel, government subpoena, and insider access.
Solution:
- XorIDA threshold sharing protects live client communications (information-theoretic security)
- Compliance copy encrypted client-side; stored on firm's server (in-jurisdiction data sovereignty)
- Legal hold prevents retention deletion for matters under litigation
- Ethical wall enforcement via delegation permissions (partners can delegate access, associates cannot cross practice groups)
- eDiscovery search by case ID, client name, date range — no decryption unless authorized by managing partner
2. Financial Services (Banks, Asset Managers, Broker-Dealers)
Requirements: SEC 17a-4 WORM compliance, FINRA 4511 books and records, SOX Section 404 internal controls, PCI DSS data protection, anti-money-laundering monitoring.
Challenge: Financial institutions must retain all communications in tamper-proof archives while preventing insider trading via encrypted channels.
Solution:
- Append-only HMAC-chained audit log (SEC 17a-4 compliant, tamper-evident)
- Retention policy: 7-year minimum (FINRA requirement), auto-delete after 10 years
- DLP blocking: credit card numbers, account numbers, SSNs (PCI DSS scope reduction)
- Compliance copy encrypted with HSM-protected key (FIPS 140-2 Level 3)
- Legal hold for regulatory inquiries (SEC, FINRA, FinCEN)
3. Healthcare (Hospitals, Health Systems, Pharma)
Requirements: HIPAA Security Rule encryption, 42 CFR Part 2 substance abuse confidentiality, HITECH breach notification, state privacy laws (CCPA, GDPR).
Challenge: PHI must be encrypted end-to-end but searchable for patient safety audits, malpractice discovery, and regulatory investigations.
Solution:
- XorIDA 2-of-3 split for PHI (HIPAA Security Rule 164.312(a)(2)(iv) encryption standard)
- Compliance copy stored on in-region server (GDPR Article 44 data residency)
- DLP scanning: SSN, MRN, diagnosis codes (prevent HIPAA violations)
- Delegation: attending physicians delegate message access to residents (read-only, time-limited)
- Audit trail for HIPAA accountability (who accessed which patient records, when)
4. Government / Defense (Federal Agencies, Contractors)
Requirements: FISMA compliance, NIST SP 800-53 controls, CMMC Level 3 for DoD contractors, FedRAMP authorization, CJIS Security Policy for law enforcement.
Challenge: Classified communications must be protected at rest and in transit, but discoverable for FOIA requests, IG investigations, and congressional oversight.
Solution:
- XorIDA shares distributed across CONUS + OCONUS (geographic diversity, no single point of seizure)
- Compliance copy encrypted with NSA-approved KEM (ML-KEM-1024 when available)
- Air-gapped private key storage (compliance officer workstation never touches network)
- SSO integration with PIV/CAC (HSPD-12 federal identity credentials)
- Retention: permanent for classified, 3-year for CUI (NARA guidance)
5. Enterprise (Fortune 500, Multinational Corporations)
Requirements: SOC 2 Type II, ISO 27001 certification, GDPR Article 5 data minimization, cross-border data transfer compliance, insider threat detection.
Challenge: Executive communications must be private from IT admins and low-level employees, but accessible to compliance, legal, and HR for investigations.
Solution:
- Delegation: executives delegate inbox access to executive assistants (read + reconstruct, not export)
- Compliance officer role: can search/export any message, separate from IT admin role (cannot access live mail)
- DLP: block PII exfiltration, confidential IP, M&A deal terms
- Retention: 1 year minimum (litigation preparedness), 7 years maximum (GDPR data minimization)
- SSO: Okta/Azure AD integration (centralized identity, MFA enforcement)
Architecture
Three-tier system: Xail client (encryption + XorIDA split), Corporate Xail Server (compliance copy storage + DLP + audit), Compliance Officer Workstation (offline decryption + eDiscovery).
Compliance Copy Encryption (Client-Side)
Hybrid encryption: RSA-OAEP wraps a randomly generated AES-256-GCM key. The AES key encrypts the message body. The RSA-encrypted AES key and the AES-encrypted ciphertext are bundled into a ComplianceCopy structure.
Step-by-Step Encryption
- Input: Plaintext message body (UTF-8 string), recipient list, subject, timestamp
- Generate AES key:
crypto.getRandomValues(new Uint8Array(32))(256 bits) - Generate IV:
crypto.getRandomValues(new Uint8Array(12))(96 bits for GCM) - Encrypt content with AES-256-GCM:
const encryptedContent = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, aesKey, encoder.encode(messageBody) ); - Encrypt AES key with RSA-OAEP:
const encryptedAesKey = await crypto.subtle.encrypt( { name: 'RSA-OAEP', hash: 'SHA-256' }, orgPublicKey, aesKeyBytes ); - Assemble ComplianceCopy:
{ messageUuid, senderEmail, recipientEmails, encryptedContent, // AES-256-GCM ciphertext + auth tag encryptedAesKey, // RSA-OAEP wrapped AES key iv, // AES-GCM initialization vector timestamp, } - Submit to Corporate Xail Server: HTTPS POST to
/compliance/submitendpoint
- Confidentiality: Ciphertext is indistinguishable from random. AES-256-GCM provides IND-CCA2 security.
- Integrity: GCM authentication tag prevents tampering. Any modification results in decryption failure.
- Forward Secrecy: Each message uses a fresh AES key. Compromise of one key does not compromise others.
- No Key Reuse: AES key is generated per-message, never reused. RSA public key is reused (rotated annually).
DLP Scanning (Pre-Split Content Inspection)
DLP scanning happens before XorIDA splitting. The client sends plaintext to the corporate server over HTTPS. The server scans against configured rules, returns a verdict, and discards the plaintext. Only the hybrid-encrypted compliance copy is stored.
Built-In DLP Rules
| Rule ID | Pattern | Action |
|---|---|---|
| ssn-pattern | /\b\d{3}-\d{2}-\d{4}\b/ | block |
| credit-card | /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/ | block |
| confidential-marker | /ATTORNEY-CLIENT|PRIVILEGED|CONFIDENTIAL/i | quarantine |
External Scanner Integration
Corporate Xail Server can proxy DLP scans to Proofpoint or Mimecast. The external scanner API endpoint receives the plaintext body via HTTPS POST, scans against enterprise DLP policies, and returns allow / block / quarantine.
import { DlpScanner } from '@private.me/enterprise';
const scanner = new DlpScanner();
scanner.setExternalScanner({
provider: 'proofpoint',
endpoint: 'https://dlp.proofpoint.com/api/scan',
apiKey: process.env.PROOFPOINT_API_KEY,
});
const result = scanner.scan({
messageUuid,
senderEmail,
recipientEmails,
subject,
body,
attachmentNames: [],
});
// result.ok && result.value.action === 'block'
eDiscovery (Compliance Officer Decryption)
The compliance officer holds the RSA private key in an HSM or air-gapped workstation. They can search compliance copies by metadata (sender, recipient, date) without decrypting. When exporting a specific message, they use the private key to decrypt the AES key, then decrypt the content.
Search by Metadata (No Decryption)
const results = eDiscovery.search({
orgId: 'acme-corp',
senderEmail: 'cfo@acme.com',
dateFrom: new Date('2024-01-01'),
dateTo: new Date('2024-12-31'),
limit: 100,
});
// results: [{ messageUuid, senderEmail, recipientEmails, timestamp }]
Decrypt and Export (Audit-Logged)
// Load private key from HSM (PIN required)
const privateKey = await loadPrivateKeyFromHsm(pin);
// Decrypt specific message
const decrypted = await eDiscovery.exportCopy(
'msg-uuid-12345',
privateKey,
'compliance-officer@acme.com'
);
if (decrypted.ok) {
// Audit log entry created automatically
// Export plaintext to legal hold system
exportToLegalHold(decrypted.value);
}
Integration
Four integration points: client-side compliance copy encryption, corporate server DLP endpoint, eDiscovery export workflow, and audit log export.
1. Client-Side Integration
Consumer Xail clients detect enterprise recipients via the isEnterprise flag on ContactInfo. When detected, the client calls encryptComplianceCopy() before XorIDA splitting.
import { encryptComplianceCopy, checkRecipientEnterprise } from '@private.me/enterprise';
// Check if recipient is on Corporate Xail Server
const notice = checkRecipientEnterprise(recipient);
if (notice) {
// Show compliance notice to user
showComplianceNotice(notice);
await userAcknowledges();
}
// Encrypt compliance copy (client-side)
const result = await encryptComplianceCopy(message, enterpriseConfig);
if (result.ok) {
// Submit to corporate server
await fetch(enterpriseConfig.serverUrl + '/compliance/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result.value),
});
}
// Proceed with XorIDA split
const shares = await createShares(message.body, 2, 3);
2. Corporate Server DLP Endpoint
The Corporate Xail Server exposes a /dlp/scan endpoint. The client submits plaintext content over HTTPS. The server scans, returns a verdict, and discards the plaintext.
// Server-side: apps/server/src/enterprise/dlp-endpoint.ts
import { DlpScanner, COMMON_DLP_RULES } from '@private.me/enterprise';
const scanner = new DlpScanner();
COMMON_DLP_RULES.forEach((rule) => scanner.addRule(rule));
app.post('/dlp/scan', async (req, res) => {
const { messageUuid, senderEmail, recipientEmails, subject, body } = req.body;
const result = scanner.scan({ messageUuid, senderEmail, recipientEmails, subject, body });
if (!result.ok) {
return res.status(400).json({ error: result.error.message });
}
// Log scan result (audit trail)
auditLog.createEntry('dlp_scan_requested', senderEmail, messageUuid, {
action: result.value.action,
ruleId: result.value.ruleId,
});
res.json(result.value);
});
3. eDiscovery Export Workflow
Compliance officers use a dedicated admin UI to search and export messages. The UI calls the eDiscovery service, which validates permissions, retrieves the compliance copy, and returns it to the officer for offline decryption.
// Admin UI: compliance officer workflow
async function exportMessage(messageUuid: string, privateKey: CryptoKey, actor: string) {
const result = await eDiscovery.exportCopy(messageUuid, privateKey, actor);
if (!result.ok) {
showError(result.error.message);
return;
}
// Download plaintext as .eml file for legal hold system
downloadAsEml(result.value);
}
4. Audit Log Export
The audit log is append-only. Organizations export it periodically for long-term archival (WORM storage, Glacier, etc.) and create a fresh instance for the next period.
import { AuditLog } from '@private.me/enterprise';
const auditLog = new AuditLog();
// Query all entries for Q4 2024
const entries = auditLog.query({
dateFrom: new Date('2024-10-01'),
dateTo: new Date('2024-12-31'),
});
// Export as JSONL for archival
const jsonl = entries.map((e) => JSON.stringify(e)).join('\n');
await writeToArchive('audit-log-2024-q4.jsonl', jsonl);
// Create fresh instance for Q1 2025
const newAuditLog = new AuditLog();
Security
Security guarantees, threat model, and cryptographic assumptions.
Cryptographic Guarantees
| Property | Guarantee | Mechanism |
|---|---|---|
| Confidentiality (Live Message) | Information-theoretic | XorIDA 2-of-3 threshold sharing. Single share reveals zero information. |
| Confidentiality (Compliance Copy) | Computational (RSA hardness) | RSA-4096 OAEP wrapping AES-256-GCM. IND-CCA2 secure. |
| Integrity (Compliance Copy) | Authenticated encryption | AES-256-GCM authentication tag. Tampering detected. |
| Forward Secrecy | Per-message AES key | Fresh AES key for each compliance copy. RSA key rotation annually. |
| Audit Trail Integrity | Tamper-evident | Append-only HMAC chain. Modification breaks chain. |
Threat Model
Assumed Adversaries:
- Corporate IT Admin: Full access to Corporate Xail Server database. Can read compliance copies (ciphertext only), audit logs, user records. Cannot decrypt compliance copies (no private key).
- Rogue Employee: Can send messages, attempt to exfiltrate data via email. Blocked by DLP scanning (SSN, credit card, confidential markers).
- Nation-State Attacker: Compromises Corporate Xail Server. Gains encrypted compliance copies, audit logs, metadata. Cannot decrypt without private key. Cannot reconstruct XorIDA shares (requires 2 of 3 channels).
- Insider (Compliance Officer): Holds private key, can decrypt all compliance copies. Constrained by audit trail (every decryption logged). Cannot access live mail stream (no access to user inboxes).
Out of Scope:
- Endpoint compromise (malware on user device can read plaintext before encryption)
- Coercion of compliance officer (physical threat to extract private key PIN)
- Quantum computer attack on RSA-4096 (post-quantum upgrade planned via ML-KEM)
Separation of Duties
| Role | Can Do | Cannot Do |
|---|---|---|
| IT Admin | Manage server infrastructure, user accounts, SSO config, DLP rules | Decrypt compliance copies, access live mail, modify audit logs |
| Compliance Officer | Search/export compliance copies (audit-logged), place legal holds, configure retention policy | Access user inboxes, read live mail stream, modify server infrastructure |
| User | Send/receive secure messages, acknowledge DLP notices | Delete compliance copies (even from their own sent mail), access other users' messages |
Security Best Practices
- Private Key Storage: Store RSA private key in FIPS 140-2 Level 3 HSM or air-gapped workstation. Never on networked server.
- Key Rotation: Rotate RSA key pair annually. Re-encrypt compliance copies with new key (background job, audit-logged).
- Audit Log Archival: Export audit log quarterly to WORM storage (SEC 17a-4). Verify HMAC chain integrity before export.
- Legal Hold Workflow: Place legal hold immediately upon litigation notice. Prevents auto-delete by retention policy.
- DLP Policy Review: Review and update DLP rules quarterly. Test against sample PII/PHI/financial data.
- SSO MFA Enforcement: Require MFA for compliance officer role. Disable password-only login.
Performance
Compliance copy encryption adds negligible overhead to the send path. The bottleneck is XorIDA splitting, not RSA encryption.
Client-Side Encryption Overhead
| Message Size | AES-256-GCM Encryption | RSA-4096 Key Wrap | Total Overhead |
|---|---|---|---|
| 1 KB (email) | 0.4 ms | 12 ms | 12.4 ms |
| 10 KB (short doc) | 0.8 ms | 12 ms | 12.8 ms |
| 100 KB (report) | 2.1 ms | 12 ms | 14.1 ms |
| 1 MB (presentation) | 18 ms | 12 ms | 30 ms |
Benchmarked on M2 MacBook Pro (Web Crypto API). RSA key wrap is constant time (independent of message size). AES-GCM scales linearly.
Server-Side DLP Scan Latency
| Content Size | Built-In Rules (Regex) | External Scanner (Proofpoint) |
|---|---|---|
| 1 KB | 2 ms | 180 ms |
| 10 KB | 4 ms | 210 ms |
| 100 KB | 18 ms | 320 ms |
External scanner latency includes HTTPS round-trip to Proofpoint API endpoint (us-east-1).
eDiscovery Decryption Performance
| Operation | Latency | Notes |
|---|---|---|
| Metadata search (1000 messages) | 45 ms | In-memory index, no decryption |
| RSA private key operation (HSM) | 50 ms | YubiHSM2, PIN-protected |
| AES-256-GCM decryption (1 MB) | 18 ms | Same as encryption |
| Total (decrypt 1 MB compliance copy) | 68 ms | RSA + AES combined |
Storage Overhead
Compliance copies add ~10% storage overhead compared to plaintext archival. The hybrid-encrypted ciphertext is slightly larger than the original message due to RSA-wrapped key (512 bytes) + GCM IV (12 bytes) + auth tag (16 bytes).
| Plaintext Size | Compliance Copy Size | Overhead |
|---|---|---|
| 1 KB | 1.54 KB | +540 bytes |
| 10 KB | 10.54 KB | +540 bytes |
| 100 KB | 100.54 KB | +540 bytes |
| 1 MB | 1.0005 MB | +540 bytes |
For large messages, the overhead becomes negligible (<0.1%). The fixed 540-byte cost (RSA-wrapped key + metadata) is amortized across the message size.
Honest Limitations
What this module does not solve, and why.
1. DLP Scanning Requires Plaintext Visibility
Limitation: The corporate server must see message plaintext during DLP scanning. This is a ~200ms window where content is exposed over HTTPS.
Why: There is no way to scan for policy violations (SSN, credit card, confidential markers) without reading the content. Fully homomorphic encryption is too slow (100x overhead) and cannot support regex-based DLP rules.
Mitigation: Plaintext is not persisted. DLP scan happens in-memory and is discarded. Only the hybrid-encrypted compliance copy is stored. This is explicit opt-in — consumer users are never affected.
2. Compliance Officer Can Decrypt All Archived Mail
Limitation: The compliance officer holding the private key can decrypt any compliance copy. This is a trusted role.
Why: eDiscovery and legal hold require a break-glass mechanism for authorized access. The alternative is key escrow (worse — third party sees everything) or no compliance capability at all.
Mitigation: Every decryption is audit-logged (tamper-evident HMAC chain). Compliance officer cannot access live mail stream (only archived copies). HSM enforces PIN authentication for private key operations.
3. In-Memory Stores Are Not Persistent
Limitation: ComplianceStore, AuditLog, DelegationManager, and other server-side classes store state in memory. Server restart loses all data.
Why: This is a reference implementation for integration testing. Production deployments require a database backend (Postgres, encrypted SQLite, etc.).
Mitigation: The module exposes clear interfaces (ComplianceStore.store(), AuditLog.createEntry()) that can be backed by any persistent storage. Implementers swap the in-memory backend for their database of choice.
4. SAML Signature Verification Not Included
Limitation: The SsoManager validates SAML assertions (expiry, provider, required fields) but does not verify XML signatures.
Why: SAML XML signature verification requires a dedicated library (xmldsig, node-saml). Including it would bloat the module with XML parsing dependencies.
Mitigation: Production deployments must use a full SAML library (e.g., Passport-SAML, Auth0) for signature verification. This module provides the validation layer on top of a verified assertion.
5. External DLP Scanner Integration Is Configuration-Only
Limitation: The module defines the ExternalScannerConfig interface but does not include API clients for Proofpoint or Mimecast.
Why: Each DLP vendor has a different API (REST vs SOAP, different auth methods, different response schemas). Including all vendor clients would create tight coupling and version dependencies.
Mitigation: Implementers write a thin adapter layer for their specific DLP vendor. The module provides the plumbing (scan request/response types, validation) but not the HTTP client.
6. No Post-Quantum Protection for Compliance Copies (Yet)
Limitation: RSA-4096 is vulnerable to Shor's algorithm on a cryptographically relevant quantum computer. Harvest-now-decrypt-later is a real threat for long-term archives.
Why: ML-KEM-1024 (NIST FIPS 203) is the designated post-quantum KEM replacement for RSA, but browser support is not yet available (Web Crypto API spec pending).
Mitigation: Planned upgrade to hybrid encryption (RSA-4096 + ML-KEM-1024) when browser support lands (expected Q3 2026). Existing compliance copies will be re-encrypted with the new key pair via background migration.
Audit Trail
Append-only HMAC-chained audit log for every compliance action. Tamper-evident, cryptographically verifiable, exportable for long-term archival.
Audit Entry Structure
{
id: string, // Unique entry ID (UUID)
action: AuditAction, // Type of action (see table below)
actor: string, // Email of user who performed action
target: string, // Subject of action (messageUuid, userId, etc.)
timestamp: Date, // ISO 8601 timestamp
metadata?: Record, // Additional context (no sensitive data)
}
Audited Actions
| Action | When | Actor |
|---|---|---|
| compliance_copy_created | Client submits compliance copy to server | Sender email |
| ediscovery_search | Compliance officer searches metadata | Officer email |
| ediscovery_export | Compliance officer decrypts and exports message | Officer email |
| legal_hold_placed | Message placed under legal hold | Officer email |
| legal_hold_removed | Legal hold lifted | Officer email |
| dlp_scan_requested | Client submits DLP scan request | Sender email |
| delegation_created | Delegator grants access to delegate | Delegator email |
| delegation_revoked | Delegation terminated | Delegator email |
| user_created | Admin invites new user | Admin email |
| user_suspended | Admin suspends user | Admin email |
| policy_updated | Admin changes org policy (retention, DLP, SSO) | Admin email |
HMAC Chain Integrity
Each audit entry is HMAC-SHA256-signed using the previous entry's hash as input. This creates a tamper-evident chain: modifying or deleting any entry breaks the chain.
// Simplified HMAC chain logic
const entryData = JSON.stringify({ id, action, actor, target, timestamp, metadata });
const hmacInput = previousHmac + entryData;
const currentHmac = await crypto.subtle.sign('HMAC', hmacKey, encoder.encode(hmacInput));
To verify the chain:
- Start with the genesis entry (HMAC = HMAC(key, "genesis"))
- For each subsequent entry, compute HMAC(key, prevHmac + entryData)
- Compare computed HMAC to stored HMAC
- If any entry fails verification, the chain is broken (tampering detected)
Export for Long-Term Archival
import { AuditLog } from '@private.me/enterprise';
const auditLog = new AuditLog();
// Query entries for Q4 2024
const entries = auditLog.query({
dateFrom: new Date('2024-10-01'),
dateTo: new Date('2024-12-31'),
});
// Export as JSONL
const jsonl = entries.map((e) => JSON.stringify(e)).join('\n');
// Write to WORM storage (SEC 17a-4 compliance)
await writeToWormStorage('audit-log-2024-q4.jsonl', jsonl);
Retention Policy
Configurable min/max retention windows with legal hold override. Automated purge of expired compliance copies.
Retention Policy Structure
{
minDays: number, // Minimum retention (e.g., 365 for 1 year)
maxDays: number, // Maximum retention (e.g., 2555 for 7 years)
autoDelete: boolean, // Auto-purge after maxDays
legalHoldOverride: boolean, // Legal hold prevents deletion
}
Default Policy
export const DEFAULT_RETENTION_POLICY: RetentionPolicy = {
minDays: 2555, // 7 years (FINRA, SEC 17a-4)
maxDays: 3650, // 10 years (GDPR max)
autoDelete: true, // Purge expired copies
legalHoldOverride: true, // Legal hold blocks deletion
};
Enforcement Logic
import { canDelete, findExpiredCopies } from '@private.me/enterprise';
// Check if a specific copy can be deleted
const result = canDelete(complianceCopy, retentionPolicy, legalHoldUuids);
if (result.ok && result.value === true) {
complianceStore.delete(complianceCopy.messageUuid);
}
// Find all expired copies (batch purge)
const expiredUuids = findExpiredCopies(
complianceStore.getAll(),
retentionPolicy,
legalHoldUuids
);
// Delete each expired copy
expiredUuids.forEach((uuid) => complianceStore.delete(uuid));
Legal Hold Protection
Messages under legal hold are immune to retention deletion, even if they exceed maxDays. Legal hold is manually placed by compliance officers and can only be removed by the same role.
// Place legal hold
eDiscovery.placeLegalHold('msg-uuid-12345', 'compliance-officer@acme.com');
// Attempt to delete (blocked)
const result = canDelete(complianceCopy, retentionPolicy, legalHoldSet);
// result.ok && result.value === false
// Remove legal hold
eDiscovery.removeLegalHold('msg-uuid-12345', 'compliance-officer@acme.com');
// Now eligible for deletion (if expired)
const result2 = canDelete(complianceCopy, retentionPolicy, legalHoldSet);
// result2.ok && result2.value === true
Delegation Management
Executive-to-assistant message access delegation with granular permissions and time-based expiry.
Delegation Permissions
| Permission | Can Do | Typical Role |
|---|---|---|
| read | View message metadata (sender, subject, timestamp) | Executive assistant (triage) |
| reconstruct | Reconstruct full message content (requires 2 of 3 shares) | Trusted assistant (respond on behalf) |
| export | Export message to external system (compliance copy decryption) | Compliance officer (legal hold) |
Create Delegation
import { DelegationManager } from '@private.me/enterprise';
const delegationManager = new DelegationManager();
// CEO delegates to executive assistant (read + reconstruct, 90 days)
const result = delegationManager.createDelegation(
'ceo@acme.com',
'assistant@acme.com',
['read', 'reconstruct'],
90 * 24 * 60 * 60 * 1000 // 90 days in ms
);
if (result.ok) {
console.log('Delegation ID:', result.value.id);
}
Verify Permission
// Check if assistant can reconstruct CEO's messages
const canReconstruct = delegationManager.verifyPermission(
'ceo@acme.com',
'assistant@acme.com',
'reconstruct'
);
if (canReconstruct) {
// Proceed with reconstruction
}
Revoke Delegation
// CEO revokes delegation (e.g., assistant leaves company)
const result = delegationManager.revokeDelegation(delegationId);
if (result.ok) {
console.log('Delegation revoked:', result.value.id);
}
Automatic Expiry
Delegations expire automatically after the configured duration. The expireStale() method scans all delegations and marks expired ones as inactive.
// Run periodically (e.g., daily cron job)
const expiredCount = delegationManager.expireStale();
console.log(`Expired ${expiredCount} delegations`);
SSO Integration
SAML/OIDC assertion validation for enterprise identity federation. Supports Okta, Azure AD, Google Workspace, and custom IdPs.
SSO Configuration
{
provider: 'okta' | 'azure' | 'google' | 'custom',
entityId: string, // IdP entity ID (SAML)
ssoUrl: string, // IdP SSO endpoint (HTTPS)
certificate: string, // X.509 certificate (PEM)
issuer: string, // Assertion issuer
callbackUrl: string, // SP callback URL
isEnabled: boolean, // SSO active/inactive
}
Assertion Validation
import { SsoManager, validateAssertion } from '@private.me/enterprise';
const ssoManager = new SsoManager();
// Admin configures SSO for organization
ssoManager.setConfig('acme-corp', {
provider: 'okta',
entityId: 'https://acme.okta.com',
ssoUrl: 'https://acme.okta.com/app/acme/sso/saml',
certificate: oktaCertPem,
issuer: 'https://acme.okta.com',
callbackUrl: 'https://xail.acme.com/auth/callback',
isEnabled: true,
});
// User authenticates via IdP, IdP redirects to callback with assertion
const assertion = parseAssertionFromRequest(req);
// Validate assertion (provider match, expiry, age limit)
const result = ssoManager.processLogin('acme-corp', assertion);
if (result.ok) {
const { email, groups } = result.value;
// Create session, link to user account
}
Assertion Validation Rules
- Provider match: Assertion issuer must match configured SSO provider
- Expiration: Assertion
expiresAtmust be in the future - Age limit: Assertion
issuedAtmust be within 5 minutes (prevents replay) - Required fields: Email, groups (optional), sessionId
SsoManager.processLogin().
User Management
Organization user lifecycle with role-based access control. Supports admin, compliance officer, and standard user roles.
User Roles
| Role | Can Do |
|---|---|
| admin | Manage users, configure SSO, set DLP rules, update org policy |
| compliance_officer | Search/export compliance copies, place legal holds, configure retention |
| user | Send/receive messages, acknowledge DLP notices |
User Lifecycle
import { UserManager } from '@private.me/enterprise';
const userManager = new UserManager(auditLog);
// Admin invites new user (status: 'invited')
const result = userManager.createUser(
'newuser@acme.com',
'Alice Smith',
'acme-corp',
'user',
'admin@acme.com'
);
// User activates account (e.g., after email verification)
userManager.activateUser(userId, 'admin@acme.com');
// Admin promotes user to compliance officer
userManager.updateRole(userId, 'compliance_officer', 'admin@acme.com');
// Admin suspends user (e.g., employee leaves company)
userManager.suspendUser(userId, 'admin@acme.com');
SSO Linking
When a user authenticates via SSO, the system links their account to the SSO provider. This enables single sign-on for all future logins.
// Link SSO to user account
userManager.linkSso(userId);
// User record updated: ssoLinked = true
Audit Trail for User Actions
All user management actions are audit-logged: create, activate, suspend, role change, SSO link. The audit log provides an immutable record of who did what to which user account.
Deployment Options
SaaS Recommended
Fully managed infrastructure. Call our REST API, we handle scaling, updates, and operations.
- Zero infrastructure setup
- Automatic updates
- 99.9% uptime SLA
- Enterprise SLA available
SDK Integration
Embed directly in your application. Runs in your codebase with full programmatic control.
npm install @private.me/enterprise- TypeScript/JavaScript SDK
- Full source access
- Enterprise support available
On-Premise Upon Request
Enterprise CLI for compliance, air-gap, or data residency requirements.
- Complete data sovereignty
- Air-gap capable deployment
- Custom SLA + dedicated support
- Professional services included
Enterprise On-Premise Deployment
While Enterprise is primarily delivered as SaaS or SDK, we build dedicated on-premise infrastructure for customers with:
- Regulatory mandates — HIPAA, SOX, FedRAMP, CMMC requiring self-hosted processing
- Air-gapped environments — SCIF, classified networks, offline operations
- Data residency requirements — EU GDPR, China data laws, government mandates
- Custom integration needs — Embed in proprietary platforms, specialized workflows
Includes: Enterprise CLI, Docker/Kubernetes orchestration, RBAC, audit logging, and dedicated support.