Skip to main content
Version: 1.0.0
Last Updated: 2025-11-26
Constitution Reference: Section 4 (Security Rules), Section 7 (What AI Must Never Do)

1. Overview

The Finance & Accounting (FA) module handles highly sensitive financial data including bank account numbers, tax IDs, credit card details, and personally identifiable financial information (PII). This document outlines security requirements, encryption standards, and compliance considerations for all FA implementations.

2. Data Classification

2.1 Highly Sensitive Data (Encryption Required)

The following fields MUST be encrypted at rest using AES-256-GCM or equivalent: Vendor Information (FA-04):
  • fa_vendors.tax_id_encrypted - EIN/SSN
  • fa_vendors.bank_account_encrypted - Bank account numbers
  • fa_vendors.routing_number_encrypted - Bank routing numbers
  • fa_vendors.credit_card_encrypted - Corporate credit card numbers (if stored)
Customer Information (FA-06):
  • fa_customers.tax_id_encrypted - EIN/SSN
  • fa_customers.payment_method_encrypted - Stored payment methods (ACH, cards)
Employee Payroll (Future):
  • fa_payroll.ssn_encrypted - Social Security Numbers
  • fa_payroll.bank_account_encrypted - Direct deposit account numbers
Implementation:
Key Management:
  • Encryption keys MUST be stored in Supabase Vault (NOT in code or environment variables)
  • Keys MUST be rotated annually
  • Separate keys for production, staging, and development environments

2.2 Sensitive Data (Access Control Required)

The following data requires strict RLS but does NOT require encryption: Financial Balances:
  • fa_accounts.current_balance - Account balances
  • fa_journal_entries - All journal entry data
  • fa_vendor_bills.amount - Invoice amounts
  • fa_invoices.total_amount - Customer invoice amounts
Access Control:
  • Only users with org_admin or platform_admin roles
  • Finance staff explicitly granted access via pf_user_roles
  • RLS enforced via fa_is_finance_admin() function

2.3 Restricted Logging

NEVER LOG:
  • Full tax IDs (log last 4 digits only: ***-**-1234)
  • Bank account numbers (log last 4 digits only: *****6789)
  • Credit card numbers (log last 4 digits only: ****1234)
  • Encryption keys or decrypted sensitive data
Safe Logging:

3. Row-Level Security (RLS) Patterns

3.1 Standard Finance Admin Access

Pattern: Only finance admins (org_admin, platform_admin, or explicitly granted finance staff) can view/modify financial data.
Helper Function:

3.2 Department Manager Limited Access

Use Case: Department managers can view budget data for their department only.

3.3 Recursive RLS Anti-Pattern (AVOID)

Problem: RLS policies that query tables with their own RLS create infinite recursion.
Solution: Use SECURITY DEFINER functions to bypass RLS in helper queries.

4. Audit Logging

4.1 Automatic Audit Triggers

All FA tables MUST have audit logging via pf_audit_logs:
Audit Log Contents:
  • user_id - Who made the change
  • organization_id - Tenant context
  • module - ‘fa’
  • action - ‘create’, ‘update’, ‘delete’
  • table_name - ‘fa_journal_entries’
  • record_id - Primary key of changed record
  • old_values - Full record before change (JSON)
  • new_values - Full record after change (JSON)
  • timestamp - When change occurred
Retention:
  • Audit logs MUST be retained for 7 years (financial compliance)
  • Audit logs MUST be immutable (no UPDATE/DELETE policies)

4.2 High-Risk Actions (Additional Logging)

Certain actions require ADDITIONAL logging beyond standard audit: Period Close/Reopen:
Journal Entry Voids:

5. Input Validation & SQL Injection Prevention

5.1 Parameterized Queries

ALWAYS use Supabase client methods (NOT raw SQL):

5.2 Amount Validation

Prevent numeric overflow and precision errors:

5.3 Date Validation

Prevent posting to invalid periods:

6. Multi-Tenancy Security

6.1 Organization Isolation

CRITICAL: All FA queries MUST filter by organization_id to prevent cross-tenant data leaks.
RLS Enforcement:
  • EVERY FA table has organization_id column
  • EVERY RLS policy checks has_org_access(auth.uid(), organization_id)
  • NEVER disable RLS on FA tables (even temporarily)

6.2 Site-Level Security

Some organizations segment data by site. Respect site_id filtering:

7. API Security

7.1 Edge Function Authentication

All FA edge functions MUST verify JWT tokens:

7.2 Rate Limiting

Critical endpoints require rate limiting:

8. Secrets Management

8.1 Encryption Keys

NEVER store encryption keys in:
  • Environment variables (.env files)
  • Source code
  • Database tables
  • Edge function code
CORRECT Storage:

8.2 Third-Party API Keys

Payment processors, bank integrations, tax services:

9. Compliance Requirements

9.1 SOC 2 Type II Considerations

Access Control:
  • Segregation of duties (creator ≠ approver)
  • Dual approval for high-value transactions (configurable threshold)
  • Immutable audit logs with 7-year retention
Data Protection:
  • Encryption at rest (AES-256) for PII/PHI
  • Encryption in transit (TLS 1.3)
  • Regular key rotation (annually)
Monitoring:
  • Failed login attempts logged
  • Unusual transaction patterns flagged
  • Period close/reopen events alerted

9.2 HIPAA Considerations (If Applicable)

BAA Required: If FA module processes Protected Health Information (PHI):
  • Supabase must have signed Business Associate Agreement (BAA)
  • All PHI fields must be encrypted at rest
  • Access logs must be retained for 6 years
  • Breach notification procedures must be documented
PHI in FA:
  • Patient billing records in fa_customers (if customers = patients)
  • Grant compliance reports mentioning patient counts (de-identified only)

9.3 PCI DSS (If Storing Cards)

DO NOT STORE:
  • Full credit card numbers (use tokenization via Stripe/Authorize.Net)
  • CVV/CVC codes (NEVER store these)
IF STORING CARD DATA:
  • Requires PCI DSS Level 1 compliance
  • Quarterly vulnerability scans
  • Annual penetration testing
  • Recommend: Use Stripe Payment Intents instead

10. Security Checklist

Pre-Implementation Checklist

  • All FA tables have RLS policies enabled
  • RLS policies use SECURITY DEFINER helper functions (no recursion)
  • Sensitive fields use pgp_sym_encrypt() encryption
  • Encryption keys stored in Supabase Vault
  • Audit logging enabled on all FA tables
  • Input validation on all amount/date fields
  • Rate limiting on critical edge functions
  • JWT token verification in all edge functions
  • Organization ID filtering on all queries
  • No sensitive data logged (tax IDs, account numbers masked)

Post-Implementation Checklist

  • Penetration testing completed
  • Security code review completed
  • RLS policies tested with multiple user roles
  • Encryption/decryption tested end-to-end
  • Audit logs verified for all operations
  • Rate limiting tested (429 responses)
  • Data leak testing (attempt cross-tenant access)
  • SQL injection testing (attempt malicious inputs)
  • Performance testing (RLS overhead acceptable)
  • Documentation updated with security considerations

11. Incident Response

Security Breach Procedure

1. Immediate Actions (0-1 hour):
  • Disable affected user accounts
  • Revoke leaked API keys/tokens
  • Enable additional logging/monitoring
  • Notify security team and CFO
2. Investigation (1-24 hours):
  • Review audit logs for unauthorized access
  • Identify scope of data exposure
  • Determine attack vector and timeline
  • Preserve evidence for forensics
3. Remediation (24-72 hours):
  • Patch vulnerability
  • Rotate all encryption keys
  • Reset affected user passwords
  • Deploy security updates
4. Notification (72 hours):
  • Notify affected customers (if PII exposed)
  • File breach reports (if legally required)
  • Update security documentation
  • Conduct post-mortem review

12. Contact & Resources

Security Team: Documentation: Compliance:
  • SOC 2 Report: Available on request
  • HIPAA BAA: Contact legal@encoreos.io
  • PCI DSS: Not certified (use tokenization)

Last Security Audit: Pending
Next Audit Due: Before production release
Approved By: [CFO/CTO Name] - [Date]