Tax Practice AI - Security Design¶
Version: 1.1 Last Updated: 2024-12-23 Status: Draft
Table of Contents¶
- Overview
- Authentication and Access Control
- Authorization (RBAC)
- Encryption
- Compliance Controls
- 5.1-5.6: Financial/Tax Compliance (IRS, GLBA, CCPA)
- 5.7: HIPAA Compliance (Healthcare/Medtech Module)
- Audit Trail
- Data Retention
- Network Security
- Incident Response
- Firm IP Protection
- Requirement Traceability Matrix
Related Documentation¶
| Document | Purpose |
|---|---|
| tax_practice_ai_requirements.md | Security requirement IDs (SEC-, ENC-, etc.) |
| DATABASE_SCHEMA.sql | Physical DDL with encryption markers |
| ARCHITECTURE.md | Infrastructure and service patterns |
| DATA_MODEL.md | Entity definitions with sensitive field identification |
1. Overview¶
1.1 Security Principles¶
This document defines the security architecture for the Tax Practice AI system, a tax preparation platform handling highly sensitive financial and personal data.
| Principle | Description |
|---|---|
| Defense in Depth | Multiple layers of security controls |
| Least Privilege | Users receive minimum access required for their role |
| Fail Secure | System defaults to deny on error conditions |
| Audit Everything | All access and mutations are logged immutably |
| Encrypt by Default | Data encrypted at rest and in transit |
| Compliance First | IRS, WISP, and privacy regulations are foundational |
1.2 Threat Model Summary¶
| Threat Category | Primary Concerns | Key Mitigations |
|---|---|---|
| Identity Theft | SSN, DOB, financial data exposure | Field-level encryption, tiered identity verification |
| Unauthorized Access | Staff accessing wrong clients, role escalation | RBAC, MFA, session management |
| Data Breach | Bulk data exfiltration | Encryption, network isolation, audit logging |
| Insider Threat | Malicious or negligent staff | Audit trails, access monitoring, separation of duties |
| Account Takeover | Credential theft, session hijacking | MFA, session timeout, lockout policies |
| Regulatory Violation | Non-compliance with IRS, GLBA, CCPA | Compliance controls, consent tracking, retention policies |
1.3 Data Classification¶
| Classification | Description | Examples | Controls |
|---|---|---|---|
| Restricted | Most sensitive, requires field-level encryption | SSN, bank account numbers, passwords | Field-level encryption, strict access control, no logging of values |
| Restricted-PHI | Protected Health Information (HIPAA) | Medical record numbers, diagnosis codes, treatment data, health plan IDs | Field-level encryption, HIPAA access controls, audit logging, BAA required |
| Confidential | Sensitive business/personal data | Tax returns, income amounts, client addresses | At-rest encryption, role-based access, audit logging |
| Internal | Firm operational data | Workflow states, preparer notes, invoices | At-rest encryption, staff-only access |
| Public | Non-sensitive | System status, general documentation | Standard controls |
Multi-Regulation Support: The system supports both financial (IRS, GLBA) and healthcare (HIPAA) data protection requirements. When data qualifies under multiple regulations (e.g., a medical expense on a tax return), the most restrictive controls apply.
2. Authentication and Access Control¶
2.1 Staff Authentication¶
Requirement: SEC-001 - System shall require multi-factor authentication for all staff users
| Control | Implementation | Notes |
|---|---|---|
| MFA Required | TOTP (authenticator app) or WebAuthn | Required for all staff roles |
| Password Policy | Minimum 12 characters, complexity requirements | NIST 800-63B compliant |
| Session Timeout | 30 minutes inactivity (SEC-003) | Configurable per environment |
| Account Lockout | 5 failed attempts = 15-minute lockout (SEC-005) | Progressive delays |
| Password Storage | bcrypt with cost factor 12 | Never stored in plaintext |
Authentication Flow (Staff):
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Username/ │ ──► │ Password │ ──► │ MFA │ ──► Session Created
│ Password │ │ Verified │ │ Verified │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
Log attempt Log attempt Log attempt
(SEC-004) (SEC-004) (SEC-004)
2.2 Client Authentication¶
| Tier | Method | Use Case |
|---|---|---|
| Tier 1 | Name + SSN-4 + DOB + Prior Year AGI | Returning clients |
| Tier 1 Fallback | Magic link email verification | When knowledge-based fails |
| Tier 2 | Email + Phone + Government ID (Persona) | New clients |
| Tier 3 | Video call (Google Meet) or in-person | High-risk situations |
Client Session: - Session timeout: 60 minutes inactivity - Optional: Remember device for 30 days (reduces Tier 1 to email verification) - No MFA required (accessibility consideration for senior clients)
2.3 API Authentication¶
| Consumer | Method | Token Lifetime |
|---|---|---|
| Staff Web App | JWT (signed with RS256) | 30 minutes (refresh token: 7 days) |
| Client Portal | JWT (signed with RS256) | 60 minutes (refresh token: 30 days) |
| Service-to-Service | API Key + HMAC signature | No expiration (key rotation every 90 days) |
| Webhooks (inbound) | Signature verification (provider-specific) | Per-request |
JWT Structure:
{
"sub": "user-uuid",
"role": "preparer",
"client_ids": ["uuid-1", "uuid-2"], // For clients: their own ID only
"exp": 1703376000,
"iat": 1703374200,
"jti": "unique-token-id"
}
2.4 Session Management (SEC-003)¶
| Setting | Staff | Client |
|---|---|---|
| Idle Timeout | 30 minutes | 60 minutes |
| Absolute Timeout | 12 hours | 24 hours |
| Concurrent Sessions | 3 maximum | 5 maximum |
| Session Storage | Redis (encrypted) | Redis (encrypted) |
Session Termination Events: - User logout - Idle timeout exceeded - Absolute timeout exceeded - Password change - Role change - Account lockout - Manual admin termination
2.5 Account Lockout (SEC-005)¶
| Condition | Action |
|---|---|
| 5 failed login attempts | Account locked for 15 minutes |
| 10 failed attempts (cumulative) | Account locked for 1 hour |
| 15 failed attempts (cumulative) | Account locked indefinitely, requires admin unlock |
| Lockout during active session | Session terminated immediately |
Lockout Tracking:
-- In users table
failed_login_attempts INTEGER DEFAULT 0,
lockout_until TIMESTAMP,
last_failed_login TIMESTAMP
3. Authorization (RBAC)¶
3.1 Role Definitions (SEC-002)¶
| Role | Description | PTIN Required |
|---|---|---|
| Admin | System configuration, user management, full access | No |
| Preparer | Document access, return preparation, client communication | Yes (PTIN-004) |
| Reviewer | All preparer permissions + approval authority | Yes (PTIN-004) |
| EA/CPA | All reviewer permissions + final sign-off authority | Yes (PTIN-004) |
| Client | Own documents and returns only | No |
3.2 Permission Matrix¶
| Resource | Admin | EA/CPA | Reviewer | Preparer | Client |
|---|---|---|---|---|---|
| System Configuration | CRUD | - | - | - | - |
| User Management | CRUD | - | - | - | - |
| All Client Records | R | R | R | R* | - |
| Own Client Records | CRUD | CRUD | CRUD | CRUD | R |
| Own Documents | CRUD | CRUD | CRUD | CRUD | RU |
| Create Returns | C | C | C | C | - |
| Approve Returns | U | U | U | - | - |
| Final Sign-off | U | U | - | - | - |
| E-File Transmission | U | U | - | - | - |
| Audit Logs | R | R | R | - | - |
| Firm Guidelines | CRUD | R | R | R | - |
| AI Assistant (Staff) | Full | Full | Full | Full | - |
| AI Assistant (Client) | - | - | - | - | Limited |
R = Read, C = Create, U = Update, D = Delete Preparer access to client records is limited to assigned clients
3.3 Resource Ownership¶
-- Role-based access control in queries
SELECT * FROM tax_return
WHERE
-- Admin/EA/CPA can see all
(user_role IN ('admin', 'ea_cpa')) OR
-- Reviewers can see all
(user_role = 'reviewer') OR
-- Preparers can see assigned only
(user_role = 'preparer' AND assigned_preparer_id = current_user_id) OR
-- Clients can see their own only
(user_role = 'client' AND client_id = current_user_client_id);
3.4 PTIN Enforcement (PTIN-001 to PTIN-004)¶
| Requirement | Implementation |
|---|---|
| PTIN-001: Store PTIN for all preparers | ptin_record table with encrypted PTIN |
| PTIN-002: Track PTIN expiration dates | expiration_date field, nightly check job |
| PTIN-003: Alert when PTIN renewal needed | Notification 60/30/7 days before expiration |
| PTIN-004: Prevent return preparation by expired PTINs | CHECK constraint + application validation |
Database Enforcement:
-- In users table
CONSTRAINT check_ptin_for_tax_roles CHECK (
role NOT IN ('preparer', 'reviewer', 'ea_cpa') OR
ptin IS NOT NULL
)
-- Active PTIN validation (application layer)
SELECT EXISTS (
SELECT 1 FROM ptin_record
WHERE user_id = :user_id
AND expiration_date > CURRENT_DATE
AND status = 'active'
);
4. Encryption¶
4.1 Encryption at Rest (ENC-001)¶
| Layer | Technology | Key Management |
|---|---|---|
| Aurora PostgreSQL | AES-256 (AWS managed) | AWS RDS master key |
| S3 Documents | SSE-KMS (AES-256) | AWS KMS CMK |
| Redis Cache | AES-256 | AWS ElastiCache encryption |
| EBS Volumes | AES-256 | AWS EBS encryption |
Aurora Configuration:
-- Verify encryption is enabled
SELECT datname,
pg_catalog.pg_encoding_to_char(encoding) as encoding
FROM pg_database;
-- Storage encryption is enabled at cluster creation (not SQL)
4.2 Encryption in Transit (ENC-002)¶
| Connection | Protocol | Configuration |
|---|---|---|
| Client ↔ Load Balancer | TLS 1.3 | HSTS enabled, modern cipher suites only |
| Load Balancer ↔ Application | TLS 1.2+ | Internal certificates |
| Application ↔ Aurora | TLS 1.2+ | RDS CA certificate validation |
| Application ↔ S3 | HTTPS (TLS 1.2+) | AWS SDK default |
| Application ↔ External APIs | HTTPS (TLS 1.2+) | Certificate pinning where supported |
TLS Configuration (ALB):
4.3 Key Management (ENC-003)¶
| Key Type | Storage | Rotation |
|---|---|---|
| Database Master Key | AWS KMS | Automatic (annual) |
| S3 CMK | AWS KMS | Automatic (annual) |
| Application Secrets | AWS Secrets Manager | Manual (90-day policy) |
| JWT Signing Keys | AWS Secrets Manager | Manual (90-day policy) |
| Field Encryption Keys | AWS KMS | Automatic (annual) |
Key Hierarchy:
AWS KMS
├── RDS Master Key
│ └── Database Storage Encryption
├── S3 CMK
│ └── Document Storage Encryption
├── Field Encryption Key
│ └── SSN, Bank Account encryption
└── Application Key
└── JWT signing, API tokens
4.4 Field-Level Encryption (ENC-004)¶
Fields Requiring Field-Level Encryption:
| Table | Column | Classification | Encryption Method |
|---|---|---|---|
client |
ssn_encrypted |
Restricted | AES-256-GCM via pgcrypto |
client |
drivers_license_encrypted |
Restricted | AES-256-GCM via pgcrypto |
client |
bank_routing_encrypted |
Restricted | AES-256-GCM via pgcrypto |
client |
bank_account_encrypted |
Restricted | AES-256-GCM via pgcrypto |
users |
password_hash |
Restricted | bcrypt (one-way) |
ptin_record |
ptin |
Restricted | AES-256-GCM via pgcrypto |
PHI Fields (HIPAA - when healthcare module enabled):
| Table | Column | Classification | Encryption Method |
|---|---|---|---|
client |
medical_record_number_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
client |
health_plan_id_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
medical_data |
diagnosis_codes_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
medical_data |
treatment_info_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
medical_data |
provider_info_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
medical_data |
prescription_info_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
biometric_data |
biometric_identifier_encrypted |
Restricted-PHI | AES-256-GCM via pgcrypto |
Note: PHI fields use the same encryption infrastructure as PII fields but are subject to additional HIPAA access controls and audit requirements. The medical_data and biometric_data tables are created when healthcare/medtech modules are enabled.
Encryption/Decryption Pattern:
-- Encrypt on insert/update
INSERT INTO client (ssn_encrypted, ...)
VALUES (pgp_sym_encrypt(:ssn, :key, 'cipher-algo=aes256'), ...);
-- Decrypt on select (authorized queries only)
SELECT pgp_sym_decrypt(ssn_encrypted::bytea, :key) AS ssn
FROM client
WHERE id = :id;
Key Rotation Procedure: 1. Generate new key in KMS 2. Re-encrypt all field values in background job 3. Update application to use new key 4. Retire old key after 30-day grace period
5. Compliance Controls¶
5.1 IRS Circular 230 (CIR-001 to CIR-004)¶
| Requirement | Implementation |
|---|---|
| CIR-001: Due diligence documentation | preparer_notes table with timestamps, linked to returns |
| CIR-002: Preparer and reviewer sign-off | workflow_history tracks state transitions with user IDs |
| CIR-003: Log all client communications | client_message table, append-only |
| CIR-004: Competency records | Future: user_certifications table |
Due Diligence Trail:
-- Query for due diligence documentation
SELECT
pr.id,
pr.note_type,
pr.content,
pr.created_at,
u.full_name as author
FROM preparer_notes pr
JOIN users u ON pr.created_by = u.id
WHERE pr.tax_return_id = :return_id
ORDER BY pr.created_at;
5.2 WISP / IRS Pub 4557 (WISP-001 to WISP-004)¶
| Requirement | Implementation |
|---|---|
| WISP-001: Architecture compliance | Encryption, access controls, audit logging (this document) |
| WISP-002: Security policy documentation | Separate WISP document referencing this design |
| WISP-003: Audit logs for security reviews | audit_log table with 7-year retention |
| WISP-004: Incident response documentation | Section 9 of this document |
Security Controls Summary (for WISP): - Data encrypted at rest (AES-256) and in transit (TLS 1.3) - Multi-factor authentication for all staff - Role-based access control with least privilege - Audit logging with 7-year retention - Session timeout and account lockout - Network isolation (private subnets, WAF) - Incident response procedures
5.3 GLBA Safeguards (GLB-001 to GLB-003)¶
| Requirement | Implementation |
|---|---|
| GLB-001: Safeguards for financial information | All encryption, access control, audit measures |
| GLB-002: Need-to-know access | RBAC with client assignment (Section 3.2) |
| GLB-003: Privacy notice delivery | Client portal displays privacy policy; acceptance logged |
Privacy Notice Tracking:
5.4 CCPA / State Privacy (SPL-001 to SPL-003)¶
| Requirement | Implementation |
|---|---|
| SPL-001: CCPA compliance | Data inventory, access controls, deletion capability |
| SPL-002: Data subject access requests | Export endpoint for client data |
| SPL-003: Deletion requests | Soft delete with retention override for legal hold |
Data Subject Access Request Flow:
Client Request → Identity Verification →
Data Export Generated → Review by EA/CPA →
Delivered via Secure Portal
Deletion with Retention Check:
-- Soft delete only if not under legal hold
UPDATE client
SET deleted_at = NOW()
WHERE id = :client_id
AND NOT EXISTS (
SELECT 1 FROM legal_hold
WHERE client_id = :client_id
AND status = 'active'
);
5.5 E-File Provider (EFP-001 to EFP-003)¶
| Requirement | Implementation |
|---|---|
| EFP-001: IRS Publication 3112 compliance | E-filing service follows IRS requirements |
| EFP-002: E-file acceptance records | efiling_acknowledgement table |
| EFP-003: Acknowledgement file storage | Stored in S3 with 7-year retention |
5.6 Form 7216 Consent¶
| Control | Implementation |
|---|---|
| Consent generation | form_7216_consent table with template |
| Consent tracking | Status enum: pending, signed, expired, revoked |
| Disclosure prevention | Application check before any data disclosure |
| Expiration handling | Nightly job to expire old consents, notification to clients |
Consent Validation:
-- Check for valid consent before disclosure
SELECT EXISTS (
SELECT 1 FROM form_7216_consent
WHERE client_id = :client_id
AND tax_year = :tax_year
AND status = 'signed'
AND expires_at > CURRENT_TIMESTAMP
);
5.7 HIPAA Compliance (Healthcare/Medtech Module)¶
When processing Protected Health Information (PHI) for healthcare analytics or medtech applications, the system implements HIPAA Security Rule requirements. These controls supplement the existing security architecture.
5.7.1 Administrative Safeguards¶
| Requirement | Implementation |
|---|---|
| Risk Analysis | Annual security risk assessment, documented in compliance records |
| Workforce Security | Background checks, role-based access, termination procedures |
| Security Training | HIPAA-specific training tracked in user_certifications |
| Contingency Plan | DR procedures (Section 8), backup verification |
5.7.2 Technical Safeguards¶
| Requirement | Implementation | Section Reference |
|---|---|---|
| Access Control | Unique user IDs, automatic logoff, encryption | 2.1, 2.4, 4.4 |
| Audit Controls | PHI access logging, immutable logs | 6.1, 6.2 |
| Integrity Controls | Hash verification, change tracking | 6.1 |
| Transmission Security | TLS 1.3, encrypted APIs | 4.2 |
PHI-Specific Access Controls:
-- PHI access requires explicit authorization
CREATE TABLE phi_access_authorization (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID REFERENCES users(id) NOT NULL,
client_id UUID REFERENCES client(id) NOT NULL,
phi_category phi_category_enum NOT NULL,
authorized_by UUID REFERENCES users(id) NOT NULL,
reason TEXT NOT NULL,
expires_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- All PHI queries must pass authorization check
-- SELECT ... FROM medical_data WHERE ...
-- AND EXISTS (SELECT 1 FROM phi_access_authorization
-- WHERE user_id = current_user_id
-- AND client_id = medical_data.client_id
-- AND (expires_at IS NULL OR expires_at > NOW()));
5.7.3 PHI Audit Requirements¶
| Event | Logged Data | Retention |
|---|---|---|
| PHI View | User, client, data category, timestamp | 6 years |
| PHI Export | User, client, purpose, destination | 6 years |
| PHI Disclosure | Recipient, purpose, authorization | 6 years |
| PHI Modification | User, before/after values (encrypted) | 6 years |
Accounting of Disclosures:
-- Track all PHI disclosures for patient access requests
CREATE TABLE phi_disclosure_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
client_id UUID REFERENCES client(id) NOT NULL,
disclosed_to VARCHAR(255) NOT NULL,
disclosure_purpose TEXT NOT NULL,
phi_categories phi_category_enum[] NOT NULL,
authorization_id UUID REFERENCES phi_access_authorization(id),
disclosed_at TIMESTAMP NOT NULL DEFAULT NOW(),
disclosed_by UUID REFERENCES users(id) NOT NULL
);
5.7.4 Breach Notification¶
| Timeframe | Action |
|---|---|
| Immediate | Contain breach, begin investigation |
| 60 days | Notify affected individuals (required by HIPAA) |
| 60 days | Notify HHS (if 500+ individuals affected, immediate media notice) |
| Annual | Report breaches affecting <500 individuals to HHS |
Breach Risk Assessment: - Was PHI encrypted? (encryption = safe harbor, no notification required) - Was PHI accessed or acquired? - Who accessed the PHI? - Was PHI actually viewed or only accessed?
5.7.5 Business Associate Agreements (BAAs)¶
When acting as a Business Associate for healthcare clients:
| Requirement | Implementation |
|---|---|
| BAA Tracking | business_associate_agreement table |
| Subcontractor Management | All cloud providers (AWS) have BAAs in place |
| Breach Notification Chain | Notify covered entity within 60 days |
| PHI Return/Destruction | Documented procedures on contract termination |
CREATE TABLE business_associate_agreement (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
covered_entity_name VARCHAR(255) NOT NULL,
covered_entity_id UUID REFERENCES client(id),
agreement_date DATE NOT NULL,
expiration_date DATE,
document_s3_key VARCHAR(500) NOT NULL,
status baa_status_enum NOT NULL DEFAULT 'active',
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
5.7.6 Minimum Necessary Standard¶
PHI access is limited to the minimum necessary for the intended purpose:
| Role | PHI Access Level |
|---|---|
| Admin | System administration only, no PHI content access |
| Analyst | Aggregate/de-identified data only by default |
| Authorized Staff | Specific client PHI with documented authorization |
| Client | Own PHI only |
De-identification: For analytics, PHI is de-identified per HIPAA Safe Harbor method: - Remove all 18 identifiers (name, SSN, dates, geographic data, etc.) - Or use Expert Determination method with documented analysis
6. Audit Trail¶
6.1 Audit Log Structure (AUD-001 to AUD-005)¶
Logged Events:
| Event Category | Examples | Requirement |
|---|---|---|
| User Actions | Login, logout, password change | AUD-001 |
| Document Access | View, download, upload | AUD-002 |
| Data Modifications | Create, update, delete | AUD-003 |
| AI Interactions | All prompts and responses | AUD-004 |
| Workflow Transitions | State changes | AUD-001 |
| Authorization Events | Permission checks, denials | AUD-001 |
Audit Log Schema:
CREATE TABLE audit_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
event_timestamp TIMESTAMP NOT NULL DEFAULT NOW(),
user_id UUID,
user_role user_role_enum,
client_id UUID,
session_id VARCHAR(100),
correlation_id VARCHAR(100),
event_type audit_event_type_enum NOT NULL,
resource_type VARCHAR(100),
resource_id UUID,
action VARCHAR(50) NOT NULL,
outcome audit_outcome_enum NOT NULL,
ip_address INET,
user_agent TEXT,
request_path TEXT,
request_method VARCHAR(10),
old_values JSONB,
new_values JSONB,
metadata JSONB
) PARTITION BY RANGE (event_timestamp);
6.2 Immutability (AUD-005)¶
Controls for Append-Only: 1. No UPDATE or DELETE permissions on audit_log table 2. Database triggers prevent modification 3. Table partitioning allows efficient archival without modification 4. Hash chain for integrity verification (optional enhancement)
-- Revoke modification permissions
REVOKE UPDATE, DELETE ON audit_log FROM PUBLIC;
REVOKE UPDATE, DELETE ON audit_log FROM app_service_role;
-- Only INSERT allowed
GRANT INSERT ON audit_log TO app_service_role;
GRANT SELECT ON audit_log TO app_service_role;
6.3 Retention (AUD-006)¶
| Data Type | Retention Period | Storage Tier |
|---|---|---|
| Audit logs (0-1 year) | Active | Aurora (hot) |
| Audit logs (1-3 years) | Archive | S3 Standard |
| Audit logs (3-7 years) | Deep archive | S3 Glacier |
| Audit logs (7+ years) | Delete | N/A |
Partition Management:
-- Create annual partitions
CREATE TABLE audit_log_2024 PARTITION OF audit_log
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
-- Archive old partitions to S3 before detaching
-- Then: ALTER TABLE audit_log DETACH PARTITION audit_log_2024;
6.4 Export (AUD-007)¶
Export Capabilities: - Full audit log export for regulatory review - Filtered export by client, user, date range, event type - Export formats: JSON, CSV - Export itself is logged in audit trail
def export_audit_log(
start_date: date,
end_date: date,
client_id: Optional[UUID] = None,
user_id: Optional[UUID] = None,
event_types: Optional[List[str]] = None,
format: str = "json"
) -> bytes:
"""
Export audit log entries for compliance review.
Requires Admin or EA/CPA role.
Export event is logged.
"""
pass
7. Data Retention¶
7.1 Retention Periods (RET-001 to RET-005)¶
| Data Type | Retention | Requirement | Notes |
|---|---|---|---|
| Tax returns & supporting documents | 7 years minimum | RET-001 | From filing date |
| Engagement letters | Permanent | RET-002 | Never delete |
| Client communications | 7 years | RET-001 | From communication date |
| Audit logs | 7 years | AUD-006 | From event date |
| Session data | 90 days | N/A | Security logs only |
| Temporary uploads | 24 hours | N/A | Cleaned automatically |
7.2 Storage Tiering (RET-003)¶
Document Age Storage Tier Access Time
─────────────────────────────────────────────────────
0-12 months S3 Standard Milliseconds
12-36 months S3 Standard-IA Milliseconds
36-84 months S3 Glacier IR Minutes
84+ months Delete N/A
Lifecycle Policy:
{
"Rules": [
{
"ID": "tax-document-lifecycle",
"Status": "Enabled",
"Transitions": [
{"Days": 365, "StorageClass": "STANDARD_IA"},
{"Days": 1095, "StorageClass": "GLACIER_IR"}
],
"Expiration": {"Days": 2555}
}
]
}
7.3 Legal Hold (RET-004)¶
| Control | Implementation |
|---|---|
| Hold activation | legal_hold table with start date, reason, authority |
| Scope | By client, return, or document |
| Override retention | Held items exempt from deletion until released |
| Release logging | All hold changes logged in audit trail |
CREATE TABLE legal_hold (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
client_id UUID REFERENCES client(id),
tax_return_id UUID REFERENCES tax_return(id),
document_id UUID REFERENCES document(id),
reason TEXT NOT NULL,
authority VARCHAR(255) NOT NULL,
status legal_hold_status_enum NOT NULL DEFAULT 'active',
activated_at TIMESTAMP NOT NULL DEFAULT NOW(),
activated_by UUID REFERENCES users(id),
released_at TIMESTAMP,
released_by UUID REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
7.4 Secure Deletion (RET-005)¶
| Data Type | Deletion Method |
|---|---|
| Database records | Soft delete (set deleted_at), hard delete after retention |
| S3 documents | S3 object deletion (versioning disabled for deleted objects) |
| Encrypted fields | Key deletion renders data unrecoverable |
| Backups | Automatic expiration per backup policy |
Deletion Verification:
-- Verify deletion is complete
SELECT
(SELECT COUNT(*) FROM client WHERE deleted_at < NOW() - INTERVAL '7 years') as clients_to_purge,
(SELECT COUNT(*) FROM tax_return WHERE deleted_at < NOW() - INTERVAL '7 years') as returns_to_purge,
(SELECT COUNT(*) FROM document WHERE deleted_at < NOW() - INTERVAL '7 years') as documents_to_purge;
8. Network Security¶
8.1 Architecture (NET-001, NET-002)¶
Internet
│
┌───────┴───────┐
│ CloudFront │ CDN, DDoS protection
│ + WAF │ (NET-003, NET-004)
└───────┬───────┘
│
┌───────┴───────┐
│ ALB │ Public subnet
│ │ TLS termination
└───────┬───────┘
│
┌─────────────┴─────────────┐
│ Private Subnet │ (NET-001)
│ │
┌─────────┴─────────┐ ┌────────────┴────────────┐
│ ECS / Fargate │ │ Aurora PostgreSQL │ (NET-002)
│ Application │ │ (No public access) │
└───────────────────┘ └─────────────────────────┘
8.2 Web Application Firewall (NET-003)¶
WAF Rules:
| Rule | Action | Purpose |
|---|---|---|
| AWS Managed - Common Rule Set | Block | OWASP Top 10 |
| AWS Managed - SQL Database | Block | SQL injection |
| AWS Managed - Known Bad Inputs | Block | Common attack patterns |
| Rate Limiting | Block (>1000 req/5min) | DDoS mitigation |
| Geographic Blocking | Block (configurable) | Country-based restrictions |
| IP Reputation | Block | Known bad actors |
8.3 DDoS Protection (NET-004)¶
| Layer | Protection |
|---|---|
| Layer 3/4 | AWS Shield Standard (automatic, free) |
| Layer 7 | WAF rate limiting, CloudFront caching |
| Application | Rate limiting middleware, request throttling |
8.4 Security Groups¶
Application Tier:
Inbound:
- TCP 443 from ALB security group
- TCP 22 from Bastion (admin access)
Outbound:
- TCP 5432 to Aurora security group
- TCP 443 to 0.0.0.0/0 (external APIs)
- TCP 443 to S3 VPC endpoint
Database Tier:
Inbound:
- TCP 5432 from Application security group
Outbound:
- None (database doesn't initiate connections)
8.5 VPC Endpoints¶
| Service | Endpoint Type | Purpose |
|---|---|---|
| S3 | Gateway | Document storage (no internet transit) |
| Secrets Manager | Interface | Credential retrieval |
| KMS | Interface | Encryption key operations |
| Bedrock | Interface | AI API calls |
9. Incident Response¶
9.1 Incident Classification (INC-001)¶
| Severity | Description | Response Time | Examples |
|---|---|---|---|
| Critical | Active breach, data exposure | Immediate | Confirmed data theft, ransomware |
| High | Potential breach, system compromise | 1 hour | Unauthorized access detected, malware found |
| Medium | Security event, no confirmed breach | 4 hours | Failed login spike, suspicious activity |
| Low | Anomaly, informational | 24 hours | Minor policy violation, configuration issue |
9.2 Incident Logging (INC-001)¶
Incident Record:
CREATE TABLE security_incident (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
severity incident_severity_enum NOT NULL,
status incident_status_enum NOT NULL DEFAULT 'open',
title VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
detected_at TIMESTAMP NOT NULL,
detected_by VARCHAR(100) NOT NULL,
affected_clients UUID[],
affected_users UUID[],
attack_vector VARCHAR(100),
indicators JSONB,
containment_actions JSONB,
remediation_actions JSONB,
root_cause TEXT,
lessons_learned TEXT,
reported_to VARCHAR(255)[],
closed_at TIMESTAMP,
closed_by UUID REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
9.3 Suspicious Activity Alerting (INC-002)¶
Automated Alerts:
| Trigger | Threshold | Action |
|---|---|---|
| Failed login attempts | 10 in 5 minutes (per IP) | Alert + temporary block |
| Unusual access pattern | ML anomaly detection | Alert to security team |
| Multiple concurrent sessions | New location + existing session | Alert + optional session kill |
| Bulk data access | >100 records in 1 minute | Alert + rate limit |
| After-hours access | Outside business hours | Alert (informational) |
| Privilege escalation | Role change | Immediate alert |
9.4 Forensic Export (INC-003)¶
Exportable Data for Investigation: - Audit logs for affected time period - Session history - Access logs (CloudWatch, WAF) - Database query logs - Application logs - Network flow logs (VPC)
Forensic Package:
def generate_forensic_package(
incident_id: UUID,
start_time: datetime,
end_time: datetime,
affected_users: List[UUID] = None,
affected_clients: List[UUID] = None
) -> bytes:
"""
Generate complete forensic package for incident investigation.
Includes all relevant logs, preserving chain of custody.
"""
pass
9.5 Response Procedures¶
Critical Incident Playbook: 1. Contain - Isolate affected systems, revoke compromised credentials 2. Assess - Determine scope, identify affected data 3. Notify - Internal stakeholders, legal counsel 4. Investigate - Root cause analysis, evidence preservation 5. Remediate - Patch vulnerabilities, restore systems 6. Report - Regulatory notifications if required (within 72 hours for CCPA breach) 7. Review - Post-incident analysis, update procedures
10. Firm IP Protection¶
10.1 Guideline Isolation (IPP-001)¶
| Control | Implementation |
|---|---|
| Separate storage | Firm guidelines in src/ai/skills/firm/ (not client-facing) |
| Database separation | firm_guideline table with staff-only access |
| Access control | Only staff roles can query firm guidelines |
-- Firm guidelines table with strict access
CREATE TABLE firm_guideline (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
category VARCHAR(100) NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
version INTEGER NOT NULL DEFAULT 1,
effective_date DATE NOT NULL,
created_by UUID REFERENCES users(id),
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
-- Only staff can access
REVOKE ALL ON firm_guideline FROM PUBLIC;
GRANT SELECT ON firm_guideline TO staff_role;
GRANT SELECT, INSERT, UPDATE ON firm_guideline TO admin_role;
10.2 AI Response Filtering (IPP-002)¶
Client-Facing AI Rules: - Never expose specific firm methodology - Never quote internal guidelines directly - Provide general guidance only - Reference "firm policy" without details
Implementation:
def filter_client_ai_response(response: str) -> str:
"""
Filter AI responses for client-facing contexts.
Removes any references to internal guidelines.
"""
# Check for guideline references
# Replace with generic statements
# Log if filtering was applied
pass
10.3 Access Separation (IPP-003)¶
| Context | Firm Knowledge Access |
|---|---|
| Staff AI session | Full access to firm guidelines |
| Client AI session | No access to firm guidelines |
| Client portal | No access to firm guidelines |
| Preparer notes | May reference guidelines (staff-only view) |
10.4 Citation Handling (IPP-004)¶
Staff AI Responses:
Based on [Firm Guideline: Due Diligence Checklist v3],
this return should include documentation for...
Client AI Responses:
11. Requirement Traceability Matrix¶
11.1 Security Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| SEC-001 | Multi-factor authentication for staff | 2.1 | Design Complete |
| SEC-002 | Role-based access control | 3.1, 3.2 | Design Complete |
| SEC-003 | Session timeout | 2.4 | Design Complete |
| SEC-004 | Log authentication attempts | 2.1 | Design Complete |
| SEC-005 | Account lockout | 2.5 | Design Complete |
11.2 Encryption Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| ENC-001 | Encryption at rest (AES-256) | 4.1 | Design Complete |
| ENC-002 | Encryption in transit (TLS 1.3) | 4.2 | Design Complete |
| ENC-003 | Key management via AWS KMS | 4.3 | Design Complete |
| ENC-004 | Field-level encryption | 4.4 | Design Complete |
11.3 Network Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| NET-001 | Private subnets | 8.1 | Design Complete |
| NET-002 | Database not publicly accessible | 8.1 | Design Complete |
| NET-003 | Web application firewall | 8.2 | Design Complete |
| NET-004 | DDoS protection | 8.3 | Design Complete |
11.4 Audit Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| AUD-001 | Log user actions | 6.1 | Design Complete |
| AUD-002 | Log document access | 6.1 | Design Complete |
| AUD-003 | Log data modifications | 6.1 | Design Complete |
| AUD-004 | Log AI interactions | 6.1 | Design Complete |
| AUD-005 | Immutable logs | 6.2 | Design Complete |
| AUD-006 | 7-year retention | 6.3 | Design Complete |
| AUD-007 | Log export | 6.4 | Design Complete |
11.5 Retention Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| RET-001 | 7-year retention | 7.1 | Design Complete |
| RET-002 | Permanent engagement letters | 7.1 | Design Complete |
| RET-003 | Storage tiering | 7.2 | Design Complete |
| RET-004 | Legal hold | 7.3 | Design Complete |
| RET-005 | Secure deletion | 7.4 | Design Complete |
11.6 Compliance Requirements¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| CIR-001 | Due diligence documentation | 5.1 | Design Complete |
| CIR-002 | Sign-off records | 5.1 | Design Complete |
| CIR-003 | Client communication logging | 5.1 | Design Complete |
| CIR-004 | Competency records | 5.1 | Design Complete |
| WISP-001 | Architecture compliance | 5.2 | Design Complete |
| WISP-002 | Security policy documentation | 5.2 | Design Complete |
| WISP-003 | Audit logs | 5.2 | Design Complete |
| WISP-004 | Incident response | 5.2, 9 | Design Complete |
| GLB-001 | Financial info safeguards | 5.3 | Design Complete |
| GLB-002 | Need-to-know access | 5.3 | Design Complete |
| GLB-003 | Privacy notice | 5.3 | Design Complete |
| SPL-001 | CCPA compliance | 5.4 | Design Complete |
| SPL-002 | Data access requests | 5.4 | Design Complete |
| SPL-003 | Deletion requests | 5.4 | Design Complete |
| EFP-001 | Pub 3112 compliance | 5.5 | Design Complete |
| EFP-002 | Acceptance records | 5.5 | Design Complete |
| EFP-003 | Acknowledgement storage | 5.5 | Design Complete |
| PTIN-001 | Store PTIN | 3.4 | Design Complete |
| PTIN-002 | Track PTIN expiration | 3.4 | Design Complete |
| PTIN-003 | Renewal alerts | 3.4 | Design Complete |
| PTIN-004 | Expired PTIN prevention | 3.4 | Design Complete |
| INC-001 | Incident logging | 9.1, 9.2 | Design Complete |
| INC-002 | Suspicious activity alerting | 9.3 | Design Complete |
| INC-003 | Forensic export | 9.4 | Design Complete |
| IPP-001 | Guideline isolation | 10.1 | Design Complete |
| IPP-002 | AI response filtering | 10.2 | Design Complete |
| IPP-003 | Access separation | 10.3 | Design Complete |
| IPP-004 | Citation handling | 10.4 | Design Complete |
11.7 HIPAA Requirements (Healthcare/Medtech Module)¶
| Req ID | Requirement | Section | Status |
|---|---|---|---|
| HIPAA-ADM-001 | Risk analysis documentation | 5.7.1 | Design Complete |
| HIPAA-ADM-002 | Workforce security procedures | 5.7.1 | Design Complete |
| HIPAA-ADM-003 | Security awareness training | 5.7.1 | Design Complete |
| HIPAA-ADM-004 | Contingency planning | 5.7.1, 8 | Design Complete |
| HIPAA-TEC-001 | Unique user identification | 2.1 | Design Complete |
| HIPAA-TEC-002 | Automatic logoff | 2.4 | Design Complete |
| HIPAA-TEC-003 | PHI encryption at rest | 4.1, 4.4 | Design Complete |
| HIPAA-TEC-004 | PHI encryption in transit | 4.2 | Design Complete |
| HIPAA-TEC-005 | Audit controls for PHI | 5.7.3, 6.1 | Design Complete |
| HIPAA-TEC-006 | Integrity controls | 6.2 | Design Complete |
| HIPAA-ORG-001 | Business Associate Agreements | 5.7.5 | Design Complete |
| HIPAA-ORG-002 | Breach notification procedures | 5.7.4 | Design Complete |
| HIPAA-POL-001 | Minimum necessary standard | 5.7.6 | Design Complete |
| HIPAA-POL-002 | De-identification procedures | 5.7.6 | Design Complete |
| HIPAA-POL-003 | Accounting of disclosures | 5.7.3 | Design Complete |
Document History¶
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2024-12-23 | Don McCarty | Initial security design document |
| 1.1 | 2024-12-23 | Don McCarty | Added HIPAA/PHI compliance (Section 5.7), PHI data classification, PHI field-level encryption |
This document defines security architecture for Tax Practice AI. Implementation must verify all controls are operational before production deployment.