> ## Documentation Index
> Fetch the complete documentation index at: https://docs-terra.withunify.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Security Policy

**Terra** is built with security as a foundational principle. This document outlines our security architecture, threat model, and practices to ensure government-grade compliance and enterprise readiness.

***

## 🛡️ Table of Contents

1. [Security Architecture](#security-architecture)
2. [Threat Model](#threat-model)
3. [Authentication & Authorization](#authentication--authorization)
4. [Data Protection](#data-protection)
5. [Audit & Compliance](#audit--compliance)
6. [Vulnerability Reporting](#vulnerability-reporting)
7. [Security Best Practices](#security-best-practices)

***

## 🏗️ Security Architecture

### Defense-in-Depth Strategy

Terra implements multiple layers of security controls:

```
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: Network & Infrastructure                          │
│ • CloudFlare DDoS protection                                │
│ • TLS 1.3 encryption in transit                            │
│ • Geographic access controls (optional)                     │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: Application Security                              │
│ • CSP headers (Content Security Policy)                    │
│ • HSTS (HTTP Strict Transport Security)                    │
│ • XSS protection via DOMPurify                             │
│ • CSRF protection via Next.js                              │
│ • Rate limiting on public endpoints                         │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ Layer 3: Authentication & Authorization                    │
│ • WorkOS SSO with MFA support                              │
│ • Role-Based Access Control (RBAC)                         │
│ • Session encryption (JWT with secure cookies)             │
│ • Row-Level Security (RLS) in database                     │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ Layer 4: Data Security                                     │
│ • Encryption at rest (AES-256)                             │
│ • Encrypted submission data (sensitive fields)             │
│ • PII redaction in logs                                    │
│ • Secure file storage with signed URLs                     │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│ Layer 5: Monitoring & Audit                                │
│ • Comprehensive audit logging                               │
│ • Real-time security event monitoring (Sentry)             │
│ • Access logs with IP tracking                             │
│ • Automated vulnerability scanning                          │
└─────────────────────────────────────────────────────────────┘
```

### Security Components

#### Middleware Security (`src/middleware.ts`)

* **Purpose:** First line of defense for all HTTP requests
* **Controls:**
  * CSP header injection with nonce-based script execution
  * Role-based route protection (admin vs. user)
  * Session decryption and validation
  * Multi-tenant domain routing
  * Redirect validation (prevents open redirects)
* **Fail-Secure:** Defaults deny access, requires explicit session

#### Auth Guards (`src/lib/auth-guards.ts`)

* **`requireAdmin()`** - Blocks non-admin users
* **`checkFormAccess()`** - Verifies form ownership/team membership
* **`verifySubmissionAccess()`** - Ensures submission ownership

#### Security Utilities (`src/lib/security/`)

* **Integration Validator** - Prevents XSS in third-party integration IDs
* **Submission Guard** - Verifies resource ownership for sensitive operations
* **Path Sanitization** - Prevents path traversal in file operations

***

## 🎯 Threat Model

### Assets Protected

| Asset                   | Sensitivity | Protection Mechanisms                                      |
| ----------------------- | ----------- | ---------------------------------------------------------- |
| **User Credentials**    | CRITICAL    | WorkOS SSO, encrypted sessions, MFA support                |
| **Submission Data**     | HIGH        | Encryption at rest, RLS policies, access controls          |
| **Form Configurations** | MEDIUM      | RBAC, audit logging, version control                       |
| **API Keys**            | CRITICAL    | Environment variables, never logged, rotation support      |
| **File Uploads**        | MEDIUM      | Signed URLs, type validation, size limits, access controls |
| **Audit Logs**          | HIGH        | Tamper-evident, retention policies, admin-only access      |

### Threat Actors

#### 1. **External Attackers (Untrusted)**

* **Goal:** Data theft, service disruption, unauthorized access
* **Mitigations:**
  * Rate limiting on public endpoints
  * DDoS protection (CloudFlare)
  * Input validation on all server actions
  * CSP to prevent XSS
  * SQL injection prevention (parameterized queries via Supabase)

#### 2. **Malicious Insiders (Low-Privilege Users)**

* **Goal:** Privilege escalation, access other users' data
* **Mitigations:**
  * RBAC enforcement in middleware
  * Row-level security in database
  * Submission ownership verification
  * Audit logging of all actions
  * Fail-secure auth guards

#### 3. **Compromised Accounts (Legitimate Users)**

* **Goal:** Abuse stolen credentials
* **Mitigations:**
  * Session expiration (configurable)
  * MFA enforcement (WorkOS)
  * Anomaly detection in audit logs
  * IP tracking and geo-blocking (optional)

#### 4. **Supply Chain Attacks (Dependencies)**

* **Goal:** Inject malicious code via npm packages
* **Mitigations:**
  * Automated dependency scanning (npm audit, Snyk)
  * Lock files (pnpm-lock.yaml)
  * Regular security updates
  * Minimal dependency footprint

### Attack Vectors & Mitigations

| Attack Vector                         | Risk Level | Mitigation Status                                        |
| ------------------------------------- | ---------- | -------------------------------------------------------- |
| **SQL Injection**                     | HIGH       | ✅ Mitigated - Supabase client uses parameterized queries |
| **XSS (Cross-Site Scripting)**        | HIGH       | ✅ Mitigated - DOMPurify + CSP + input validation         |
| **CSRF (Cross-Site Request Forgery)** | MEDIUM     | ✅ Mitigated - Next.js built-in protection                |
| **Path Traversal**                    | MEDIUM     | ✅ Mitigated - Path sanitization in file operations       |
| **Privilege Escalation**              | HIGH       | ✅ Mitigated - RBAC + RLS + auth guards                   |
| **Session Hijacking**                 | MEDIUM     | ✅ Mitigated - Encrypted cookies + HTTPS only             |
| **Data Exposure via API**             | HIGH       | ✅ Mitigated - Auth guards + submission ownership checks  |
| **Rate Limit Bypass**                 | LOW        | ⚠️ In Progress - Adding rate limiting                    |
| **Account Enumeration**               | LOW        | ✅ Mitigated - Generic error messages                     |
| **Open Redirect**                     | LOW        | ✅ Mitigated - Redirect validation in middleware          |

***

## 🔐 Authentication & Authorization

### Authentication Flow (WorkOS SSO)

```
1. User visits /login
     ↓
2. Redirected to WorkOS Auth0 (OAuth 2.0)
     ↓
3. User authenticates (email/password + MFA if enabled)
     ↓
4. WorkOS callback with authorization code
     ↓
5. Terra exchanges code for user profile + tokens
     ↓
6. Session created (encrypted JWT in HTTP-only cookie)
     ↓
7. User redirected to dashboard or portal based on role
```

### Role-Based Access Control (RBAC)

| Role             | Permissions                                        | Routes                           |
| ---------------- | -------------------------------------------------- | -------------------------------- |
| **super\_admin** | Full system access, can manage all forms/users     | All routes                       |
| **admin**        | Manage forms, view submissions, configure settings | /forms, /applications, /settings |
| **user**         | Limited access (reserved for future use)           | /portal                          |
| **applicant**    | View own submissions only                          | /portal                          |

### Authorization Enforcement

**Middleware-Level (Route Protection)**

```typescript theme={null}
// src/middleware.ts
// Runs on EVERY request before page render
if (isAdminRoute && !hasAdminAccess(userRole)) {
  redirect("/portal"); // Deny access
}
```

**Action-Level (Resource Protection)**

```typescript theme={null}
// src/app/actions/*.ts
// Runs on EVERY server action before execution
const auth = await checkFormAccess(formId);
if (!auth.success) {
  return { success: false, error: "Unauthorized" };
}
```

**Database-Level (Row-Level Security)**

```sql theme={null}
-- Supabase RLS policies ensure even direct DB queries are filtered
CREATE POLICY "Users can only view their own submissions"
  ON submissions FOR SELECT
  USING (user_id = auth.uid());
```

***

## 🔒 Data Protection

### Encryption

#### In Transit

* **TLS 1.3** for all HTTPS connections
* **Certificate pinning** (optional for high-security deployments)
* **No downgrade attacks** - HSTS enforced

#### At Rest

* **Database:** AES-256 encryption (Supabase managed)
* **File Storage:** AES-256 encryption (Supabase Storage)
* **Sensitive Fields:** Additional application-level encryption for:
  * Bank account numbers
  * Routing numbers
  * Social security numbers
  * Plaid access tokens

#### In Use

* **Memory:** Secrets loaded from environment variables, never hardcoded
* **Logs:** PII automatically redacted by logger (`src/lib/logger.ts`)

### Data Classification

| Data Type        | Classification | Encryption        | Retention                          |
| ---------------- | -------------- | ----------------- | ---------------------------------- |
| User Credentials | CRITICAL       | WorkOS managed    | Until account deletion             |
| Submission Data  | HIGH           | At rest (AES-256) | Configurable (default: indefinite) |
| Audit Logs       | MEDIUM         | At rest (AES-256) | 2 years (compliance)               |
| Form Schemas     | LOW            | At rest (AES-256) | Indefinite                         |
| File Uploads     | MEDIUM         | At rest (AES-256) | Linked to submission               |

### PII Handling

**Terra follows GDPR/CCPA principles:**

1. **Data Minimization** - Only collect necessary data
2. **Purpose Limitation** - Data used only for stated purpose
3. **Storage Limitation** - Configurable retention policies
4. **Integrity & Confidentiality** - Encryption + access controls
5. **Right to Erasure** - Users can delete their data

**PII Redaction in Logs:**

```typescript theme={null}
// src/lib/logger.ts automatically redacts:
- Emails
- Phone numbers
- SSNs
- Credit card numbers
- API keys / tokens
- Passwords
```

***

## 📊 Audit & Compliance

### Audit Logging

**Every mutation operation is logged:**

```typescript theme={null}
// Example: Form published
logFormAudit("publish", formId, userId, userEmail, userRole, {
  form_title: "Application Form",
});
```

**Audit Log Schema:**

* **Who:** `user_id`, `user_email`, `user_role`
* **What:** `action_type` (create, update, delete, etc.)
* **Which:** `entity_type`, `entity_id`
* **When:** `created_at` (UTC timestamp)
* **Where:** `ip_address`, `user_agent`
* **Why:** `metadata` (context)
* **Changes:** `changes` (before/after diff)

**Audit Log Retention:** 2 years minimum (configurable via migration 079)

### Compliance Frameworks

#### SOC 2 Type II (System and Organization Controls)

* ✅ **CC6.1** - Logical access controls (RBAC, RLS)
* ✅ **CC6.6** - Audit logging and monitoring
* ✅ **CC6.7** - Encryption at rest and in transit
* ✅ **CC7.2** - Change management (audit logs + version control)

#### ISO 27001 (Information Security Management)

* ✅ **A.9** - Access control (authentication, authorization)
* ✅ **A.10** - Cryptography (TLS, AES-256)
* ✅ **A.12** - Operations security (logging, monitoring)
* ✅ **A.14** - System acquisition and development (secure SDLC)

#### GDPR (General Data Protection Regulation)

* ✅ **Article 25** - Privacy by design and default
* ✅ **Article 32** - Security of processing (encryption)
* ✅ **Article 33** - Breach notification (monitoring + alerts)
* ✅ **Article 35** - Data protection impact assessment (threat model)

#### HIPAA (Health Insurance Portability and Accountability Act)

* ⚠️ **Not HIPAA-certified** - Additional BAA required for PHI
* ✅ **Technical safeguards** in place (encryption, access controls)
* ✅ **Audit controls** (comprehensive logging)

### Compliance Reporting

**Automated compliance reports available:**

* User access logs (who accessed what, when)
* Form modification history (version control)
* Submission exports (with audit trail)
* Security event summary (failed logins, access denied)

***

## 🚨 Vulnerability Reporting

### Responsible Disclosure Policy

We take security vulnerabilities seriously. If you discover a security issue:

**DO:**

* ✅ Report privately via GitHub Security Advisories
* ✅ Provide detailed reproduction steps
* ✅ Allow 90 days for remediation before public disclosure
* ✅ Work with us to verify the fix

**DON'T:**

* ❌ Publicly disclose before we've had a chance to fix
* ❌ Exploit vulnerabilities beyond proof-of-concept
* ❌ Access or modify other users' data
* ❌ Perform DOS/DDOS attacks

### Reporting Channels

1. **GitHub Security Advisory** (Preferred)
   * Navigate to: [https://github.com/anthropics/terra/security/advisories](https://github.com/anthropics/terra/security/advisories)
   * Click "Report a vulnerability"

2. **Email:** [security@withunify.org](mailto:security@withunify.org) (if GitHub unavailable)
   * Use PGP key: \[Link to public key]
   * Include: Description, impact, reproduction steps

### Response Timeline

| Severity     | Initial Response | Fix Timeline | Disclosure          |
| ------------ | ---------------- | ------------ | ------------------- |
| **Critical** | 24 hours         | 7 days       | After fix + 14 days |
| **High**     | 48 hours         | 30 days      | After fix + 30 days |
| **Medium**   | 5 days           | 60 days      | After fix + 60 days |
| **Low**      | 10 days          | 90 days      | After fix + 90 days |

### Security Bounty

Currently **no formal bug bounty program**, but we recognize security researchers:

* Public acknowledgment (with permission)
* Swag/merchandise for significant findings
* Potential monetary reward for critical vulnerabilities (case-by-case)

***

## 🔧 Security Best Practices (For Developers)

### Code Review Checklist

Before submitting a PR, verify:

* [ ] **Authentication:** All server actions have auth guards
* [ ] **Authorization:** Resource ownership verified (checkFormAccess, verifySubmissionAccess)
* [ ] **Input Validation:** All user input validated (zod schemas)
* [ ] **Output Encoding:** User-generated content sanitized (DOMPurify)
* [ ] **SQL Injection:** Using Supabase client (no raw SQL strings)
* [ ] **XSS Prevention:** No `dangerouslySetInnerHTML` without sanitization
* [ ] **Path Traversal:** File paths sanitized (sanitizeStoragePath)
* [ ] **Secrets:** No hardcoded API keys or passwords
* [ ] **Logging:** No PII in log messages
* [ ] **Error Messages:** Generic errors to users (details in logs)
* [ ] **Rate Limiting:** Considered for new public endpoints
* [ ] **Audit Logging:** Mutations logged via audit-logger.ts

### Secure Coding Patterns

#### ✅ GOOD: Server Action with Auth

```typescript theme={null}
export async function updateForm(formId: string, data: FormData) {
  // 1. Auth guard
  const auth = await checkFormAccess(formId);
  if (!auth.success) return { success: false, error: auth.error };

  // 2. Input validation
  const validated = formSchema.safeParse(data);
  if (!validated.success) return { success: false, error: "Invalid input" };

  // 3. Database operation
  const { error } = await supabaseAdmin
    .from("forms")
    .update(validated.data)
    .eq("id", formId);

  // 4. Audit logging
  await logFormAudit("update", formId, auth.session.user.id, ...);

  return { success: true };
}
```

#### ❌ BAD: Missing Auth / Validation

```typescript theme={null}
export async function updateForm(formId: string, data: any) {
  // NO auth check - anyone can update any form!
  // NO input validation - SQL injection risk!
  const { error } = await supabaseAdmin
    .from("forms")
    .update(data) // Unsafe!
    .eq("id", formId);

  return { success: !error };
}
```

### Security Testing

Run security checks locally:

```bash theme={null}
# Type safety
pnpm --dir apps/terra tsc --noEmit

# Linting (includes security rules)
pnpm --dir apps/terra lint

# Dependency vulnerabilities
npm audit

# Unit tests (includes security tests)
pnpm --dir apps/terra test

# E2E tests
pnpm --dir apps/terra test:e2e
```

***

## 📅 Security Update Policy

* **Critical vulnerabilities:** Patched within 7 days
* **High vulnerabilities:** Patched within 30 days
* **Dependency updates:** Monthly review, quarterly updates
* **Security audits:** Quarterly internal review, annual external audit

***

## 📚 Additional Resources

* [OWASP Top 10](https://owasp.org/www-project-top-ten/)
* [CWE Top 25](https://cwe.mitre.org/top25/)
* [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
* [SOC 2 Compliance Guide](https://www.vanta.com/resources/soc-2-compliance-guide)

***

**Last Updated:** 2026-01-08
**Security Contact:** [security@withunify.org](mailto:security@withunify.org)
**Version:** 1.0
