Skip to main content

Data Retention Policy

Status: DRAFT Owner: Engineering / Legal Last Review: 2026-02-21 Applicable Standards: GDPR (Art. 5(1)(e), Art. 17) / SOC 2 (P4.2, CC6.5) / IRS Record Retention / SEC Rule 17a-4

1. Purpose

This document describes Equa’s current data retention practices, identifies gaps, and recommends a formal data lifecycle management framework. An equity management platform must balance GDPR data minimization with regulatory retention obligations for securities and tax records.

2. Scope

ComponentIn ScopeNotes
equa-serverYesSession lifecycle, soft delete logic, entity retention
PostgreSQL (Cloud SQL)YesAll persisted data, session store
AWS S3YesDocument uploads, certificates
equa-webPartialClient-side session cookies, local storage

3. Current Retention Implementation

3.1 Session Retention

Source: equa-server/modules/auth/src/sessions.ts, equa-server/modules/auth/src/lib/session-cleaning.ts
ParameterValueSource
Session storePostgreSQL via TypeORMSessionStoreequa-server/modules/auth/src/sessions.ts
Max age42 minutes rolling (API_SESSION_MAX_AGE, default: 2,520,000ms)equa-server/modules/auth/src/sessions.ts
Rollingtrue — expiry resets on each requestequa-server/modules/auth/src/sessions.ts
CleanupCron job removes expired records based on expires columnequa-server/modules/auth/src/lib/session-cleaning.ts
On logoutSession record is destroyedApplication logic
Sessions are one of the few data types with an explicit, automated retention and cleanup policy. Source: equa-server/modules/auth/src/magic-link.ts
ParameterValue
Expiry15 minutes (MAGIC_LINK_EXPIRY_MINUTES = 15)
CleanupcleanupExpiredMagicLinks() deletes records where expiresAt < now
Fields storedtoken, email, expiresAt, used
Magic links are the second data type with automated lifecycle management. The cleanup function is called periodically to remove expired tokens.

3.3 Onboarding Session Retention

Source: equa-server/modules/persistence/lab/sql/migrations/2.33.0-onboarding-tables.sql
ParameterValue
Expiry24 hours (expires_at DEFAULT NOW() + INTERVAL '24 hours')
Related tablesonboarding_files (CASCADE on delete), onboarding_questions (CASCADE on delete)
Fields storedemail, initial_prompt, analysis_result, file_analysis_results
The onboarding_sessions table has an expires_at column with a 24-hour default, and child tables (onboarding_files, onboarding_questions) cascade on delete.
No automated cleanup job for expired onboarding sessions was found in the codebase. The expires_at column exists but may not be actively enforced by a purge job.Recommendation: Implement a scheduled cleanup job (similar to cleanupExpiredMagicLinks) that deletes onboarding sessions past their expires_at timestamp.

3.4 Email Verification Retention

Source: equa-server/modules/persistence/src/schema.ts (EmailVerifications entity, line 799)
ParameterValue
Fieldsuser (UUID), code
TTLNone documented
CleanupNone found
The EmailVerifications entity stores verification codes with no documented TTL or cleanup mechanism. Expired verification codes accumulate indefinitely.Recommendation: Add an expiresAt column and a cleanup job to purge verification codes after a reasonable period (e.g., 24 hours).

3.5 One-Time Code Retention

Source: equa-server/modules/persistence/src/schema.ts (Onetimecodes entity, line 835)
ParameterValue
Fieldsuser (UUID), code, available (boolean, default: true)
TTLNone — no expiry column exists
State managementavailable boolean toggled to false after use
CleanupNone found
The Onetimecodes entity has an available boolean to mark codes as used, but no expiry column or cleanup mechanism. Used one-time codes remain in the database indefinitely.Recommendation: Add an expiresAt column and a cleanup job, or delete used codes after a short retention period (e.g., 7 days).

3.6 Soft Delete Mechanism

Source: equa-server/modules/common/src/lib/utility.ts (line 37) The platform uses a deleted boolean flag on entities that extend the CreatedModifiedDeleted base class. This is the primary soft-delete mechanism — there is no separate DeletedRecords snapshot table. Base class definition:
abstract class CreatedModifiedDeleted extends CreatedModified {
  @Column({ default: false })
  deleted: boolean = false
}
Entities using CreatedModifiedDeleted (soft-deletable):
EntitySource LineData Type
Users410User accounts
Members892Organization members (equity holders)
Organizations1207Company records
TaxIds871Tax identification numbers
Tasks847Workflow tasks
TasksExerciseOption859Option exercise tasks
Waitlists398Waitlist entries
RegisteredAgents1363Registered agents
OrganizationTemplates1405Document templates
Additionally, some hashed entities use a standalone deleted: boolean column (not via the base class):
EntitySource LineNotes
SecurityTypes925 (line 984)deleted column with doNotHash comment
Authorizations1378 (line 1400)deleted column with doNotHash comment
Strengths:
  • Preserves data for regulatory retention requirements
  • Simple, consistent pattern across entities
  • Timestamps available via created and modified from the base class
Limitations:
  • No automatic purge schedule — soft-deleted records accumulate indefinitely
  • No distinction between regulatory-hold deletions and routine cleanup
  • No deletedBy field to track who performed the deletion
  • No deletedAt timestamp separate from modified (the modified column updates on soft delete, but is ambiguous)
  • No mechanism to permanently purge records after retention periods expire

4. Regulatory Retention Requirements

4.1 Securities Records

Record TypeRetention RequirementBasis
Stock transfer recordsPermanent (while company exists)State corporation law
Equity grant agreements7 years minimum after termination/expirySEC Rule 17a-4 guidance
Board resolutions (equity-related)PermanentCorporate governance
Cap table snapshots7 years minimumSecurities law, audit requirements
409A valuation reports7 years after the later of grant exercise or expiryIRC Section 409A

4.2 Tax Records

Record TypeRetention RequirementBasis
Form 3921 (ISO exercises)7 yearsIRS requirements
Form 1099 data7 yearsIRS requirements
Tax ID records (SSN/EIN)Duration of relationship + 7 yearsIRS requirements

4.3 General PII

Record TypeRetention RequirementBasis
User account dataDuration of account + reasonable periodGDPR Article 5(1)(e)
Contact informationDuration of relationshipGDPR data minimization
Activity / audit logs3—7 years depending on contentVaries by regulation
Authentication logs1 year minimumSecurity best practices

Tier 1: Permanent Retention

Records that must be retained as long as the organization exists on the platform:
  • Stock transfer ledger entries (Shareholdings, Transactions)
  • Share class definitions (SecurityTypes, SecurityTypeShares)
  • Board resolution records (Authorizations)
  • Certificate issuance and cancellation records (Shareholdings)
  • Operating agreements (OperatingAgreements)

Tier 2: Long-Term Retention (7 years)

Records retained for 7 years after the relevant event:
  • Equity grant agreements (Options, Plans) — 7 years after termination/expiry/exercise
  • 409A valuation reports (Files in data room) — 7 years after the later of grant exercise or expiry
  • Tax filing data (TaxIds, Form 3921/1099 records)
  • Cap table snapshots (Holdings) — 7 years from snapshot date
  • Financial transaction records (Transactions)

Tier 3: Medium-Term Retention (3 years)

Records retained for 3 years after creation or last activity:
  • Audit log entries (EventLogs, non-financial)
  • User activity logs
  • Email delivery records
  • Task completion records (Tasks)

Tier 4: Short-Term Retention (1 year)

Records retained for 1 year:
  • Authentication logs (login/logout events)
  • API access logs
  • Session records beyond the 29-day active window
  • Failed authentication attempts

Tier 5: Transient (30 days or less)

Records that should be purged regularly:
  • Expired session data (currently 42 minutes — implemented)
  • Magic link tokens (currently 15 minutes — implemented)
  • Onboarding sessions (24-hour expires_atschema exists, cleanup TBD)
  • Email verification codes (no expiry — gap)
  • One-time codes (no expiry — gap)
  • Temporary upload staging files
  • Cache entries

6. Implementation Recommendations

Phase 1: Policy Documentation

  1. Formalize this document as the official data retention policy
  2. Classify all data tables into the retention tiers above
  3. Document legal holds — process for suspending retention-based deletion when litigation or regulatory investigation is anticipated

Phase 2: Automated Lifecycle Management

  1. Retention tags — Add a retentionTier and retentionExpiry metadata column to key tables or a central retention registry
  2. Purge jobs — Implement scheduled jobs that:
    • Identify records past their retention expiry
    • Check for legal holds before purging
    • Permanently delete (not soft-delete) expired records
    • Log all purge actions to the audit trail
  3. Soft-delete cleanup — Add retention expiry tracking to soft-deleted records so they are eventually purged after regulatory retention periods expire
  4. Transient data cleanup — Implement cleanup jobs for EmailVerifications, Onetimecodes, and onboarding_sessions

Phase 3: User-Facing Data Lifecycle

  1. Data export — Allow users to export their data before account closure (see Data Privacy and GDPR)
  2. Account deletion — Implement a full account deletion workflow that:
    • Exports user data (for portability)
    • Soft-deletes user records with appropriate retention tags
    • Anonymizes audit trail entries after retention period
    • Permanently purges all PII after regulatory retention periods expire
  3. Retention dashboard — Admin view showing data volumes by retention tier and upcoming purge schedules

Phase 4: Compliance Reporting

  1. Retention compliance report — Show adherence to retention schedules
  2. Data inventory — Automated discovery and classification of all stored PII
  3. Purge audit log — Tamper-evident record of all data purges for regulatory review

7. Regulatory References

StandardRequirementCurrent Status
GDPR Art. 5(1)(e)Storage limitation — personal data kept no longer than necessaryGap — no automated retention enforcement; soft-deleted records retained indefinitely
GDPR Art. 17Right to erasurePartial — soft delete exists but no permanent purge after retention period
SOC 2 P4.2Data disposal when no longer neededGap — no formal disposal procedures
SOC 2 CC6.5Disposal of confidential informationGap — no documented disposal process
IRS (IRC 6001)7-year retention for tax recordsImplemented — data retained indefinitely (exceeds requirement)
SEC Rule 17a-47-year retention for securities recordsImplemented — data retained indefinitely (exceeds requirement)

8. Revision History

DateVersionAuthorChanges
2026-02-210.1Agent (Phase 5 Session A)Initial draft
2026-02-210.2Agent (Phase 5 Session B)Template alignment, corrected soft-delete mechanism (boolean flag not snapshot table), added magic link/onboarding/verification/one-time code lifecycle items, entity-by-entity soft-delete inventory, regulatory references table