﻿# Osolix · SOC 2 Type II Control Matrix — v1

**Status:** Wave-B Foundation evidence · 2026-Q2
**Owner:** Chief Compliance Officer
**Audit dimension:** #13 Compliance & regulatory
**Re-attestation:** Quarterly

This document maps every Trust Services Criterion (TSC) from the AICPA SOC 2 framework to the Osolix control that satisfies it, plus the live evidence the auditor can verify on the platform. Where a control is partially implemented or in build, the gap is documented with an owner and an ETA so the auditor can see the trajectory.

The matrix is organised by the five Trust Services Criteria categories: **Security (CC1–CC8)**, **Availability (A1)**, **Processing Integrity (PI1)**, **Confidentiality (C1)**, and **Privacy (P1)**.

---

## Common Criteria — Security (CC)

### CC1 — Control Environment

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC1.1 | Code of conduct, ethics, integrity values | `docs/30-team-job-descriptions.md` defines roles + ethics expectations | `/admin/audit` lens roster + charter §7 | ✅ |
| CC1.2 | Board / governance body oversight of internal controls | Quarterly platform-audit re-attestation per charter §6 | `/admin/audit` certificate registry | ✅ |
| CC1.3 | Management establishes structure, reporting lines, authorities | Sidebar IA + role-based access control + DoA approval matrix | `Sidebar.tsx` + `RoleSeeder` + `ApprovalMatrixService` | ✅ |
| CC1.4 | Demonstrates commitment to attract, develop, retain competent individuals | Job descriptions + onboarding playbook | `docs/30-team-job-descriptions.md` | ✅ |
| CC1.5 | Holds individuals accountable for internal-control responsibilities | Audit trail interceptor logs every CRUD with user ID | `AuditInterceptor.cs` → `[audit].[AuditLogs]` table | ✅ |

### CC2 — Communication and Information

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC2.1 | Obtains or generates relevant information for internal control | Structured logs (Serilog) + traces + AI Governance dashboard | `Program.cs` Serilog config | ✅ |
| CC2.2 | Internally communicates control responsibilities | Notifications hub + email + in-app inbox | `NotificationsController` | ✅ |
| CC2.3 | Externally communicates control matters | Status page (`/system-status`) + customer release notes | `StatusPage.tsx` (Wave B) | ✅ |

### CC3 — Risk Assessment

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC3.1 | Specifies suitable objectives | Charter §1 + Wave plan | `docs/60-audit-charter.md` | ✅ |
| CC3.2 | Identifies and analyses risks | OWASP Top 10 checklist + threat model | `docs/62-owasp-top10-checklist.md` | ✅ |
| CC3.3 | Considers fraud potential | Fraud Analytics dashboard + segregation-of-duties checks | `/finance/fraud-analytics` | ✅ |
| CC3.4 | Identifies and assesses changes | Domain-event log + migration history | `[mdm].[DomainEvents]` + `[__EFMigrationsHistory]` | ✅ |

### CC4 — Monitoring Activities

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC4.1 | Selects, develops, performs ongoing or separate evaluations | Continuous platform audit + nightly AI agent scans | `/admin/audit` + `NightlyAgents` job | ✅ |
| CC4.2 | Evaluates and communicates deficiencies in a timely manner | Management Letter findings + Whistleblower portal | `ManagementLetterFinding` + `WhistleblowerReport` | ✅ |

### CC5 — Control Activities

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC5.1 | Selects + develops control activities to mitigate risk | RBAC + tenant filter + rate limit + WAF | `RequireModuleAttribute` + `OsolixDbContext` global filter | ✅ |
| CC5.2 | Selects + develops general controls over technology | Code review + automated tests + CI/CD pipeline | Playwright + dotnet test | ✅ |
| CC5.3 | Deploys controls through policies + procedures | Approval matrix + DoA chain + segregation-of-duties | `ApprovalMatrixService` | ✅ |

### CC6 — Logical and Physical Access Controls

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC6.1 | Implements logical access security | JWT + PBKDF2-HMAC-SHA256 password hashing (600k iterations, self-describing/rotatable format) + MFA (TOTP) + SSO (OIDC) | `TokenService` + `PasswordHasher.cs` + `ProfileSecurityPage` (TOTP) + `SsoTenantConfig` | ✅ |
| CC6.2 | Authenticates users prior to access | `[Authorize]` on every controller + middleware pipeline | All controllers | ✅ |
| CC6.3 | Authorises users + groups based on roles + responsibilities | `RequireModule` + `RequireModuleRole` attributes; entitlement table | `RequireModuleAttribute.cs` + `useEntitlements` | ✅ |
| CC6.4 | Restricts physical access to facilities + protected information | Cloud-hosted (Azure / AWS) — provider attestations | Cloud provider SOC 2 reports | ⚪ vendor |
| CC6.5 | Discontinues logical and physical protections over physical assets | Asset retirement workflow + DoA approval | `RetirementsController` | ✅ |
| CC6.6 | Implements logical access security measures to protect against threats from outside system boundaries | TLS 1.2+ everywhere + WAF + IP allow-list option | HTTPS-only Kestrel + `health` endpoint check | ✅ |
| CC6.7 | Restricts the transmission, movement, and removal of information | Encrypted transit (HTTPS) + audit trail on every export | `AuditInterceptor` | ✅ |
| CC6.8 | Implements controls to prevent or detect and act upon the introduction of unauthorised or malicious software | Dependency scanning (npm audit, dotnet vulnerable packages) — both blocking | `.github/workflows/ci.yml` (`npm audit --audit-level=high`; `dotnet list ... package --vulnerable --include-transitive`) + CodeQL SAST | ✅ |

### CC7 — System Operations

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC7.1 | Detects and monitors system events to identify anomalies | Serilog structured logs + AI Governance alerts | `Program.cs` + `/admin/ai-governance` | ✅ |
| CC7.2 | Monitors system components for anomalies indicative of malicious acts | Failed-login lockout + cross-tenant probe alerts | `LoginAttemptLockout` middleware | ✅ |
| CC7.3 | Evaluates security events and determines whether they could prevent the entity from meeting its objectives | Incident-response runbook + on-call rotation | `docs/64-restore-drill-runbook.md` | ✅ |
| CC7.4 | Responds to identified security incidents | Whistleblower + management-letter workflow | `ManagementLetterFinding` | ✅ |
| CC7.5 | Identifies, develops, and implements activities to recover from identified security incidents | DR runbook + cross-region failover drill | `docs/46-cross-region-failover-drill.md` | ✅ |

### CC8 — Change Management

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| CC8.1 | Authorises, designs, develops or acquires, configures, documents, tests, approves, and implements changes | EF migrations + PR review + audit-charter re-attestation | `_EFMigrationsHistory` + GitHub PR rules | ✅ |

---

## Availability (A1)

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| A1.1 | Maintains current processing capacity to meet objectives | Load test at 100k assets / 50 concurrent users | `tests/load/k6-100k-assets.js` (Wave B) | 🔄 build |
| A1.2 | Authorises, designs, develops, implements, and maintains environmental protection | Cloud provider SOC 2 + multi-AZ deployment | Provider attestation | ⚪ vendor |
| A1.3 | Tests recovery plan procedures | Monthly restore drill | `docs/64-restore-drill-runbook.md` | ✅ |

---

## Processing Integrity (PI1)

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| PI1.1 | Obtains or generates accurate, complete information related to processing | Audit interceptor + RowVersion concurrency token | `AuditInterceptor` + `BaseEntity.RowVersion` | ✅ |
| PI1.2 | Implements policies and procedures over system inputs | Form validation (FluentValidation server-side + Zod client-side) | All controllers | ✅ |
| PI1.3 | Implements policies and procedures over system processing | Domain events + workflow approval state machine | `DomainEvent` table + `ApprovalMatrix` | ✅ |
| PI1.4 | Implements policies and procedures over system outputs | Output sanitisation + role-based field filter | `UserFarColumnAccess` filter | ✅ |
| PI1.5 | Stores inputs, items in process, outputs completely, accurately, and timely | Soft-delete + rowversion + immutable audit trail | Every entity | ✅ |

---

## Confidentiality (C1)

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| C1.1 | Identifies and maintains confidential information | Tenant-scoped query filter on every entity | `OsolixDbContext.BuildTenantAndSoftDeleteFilter` | ✅ |
| C1.2 | Disposes of confidential information | Right-to-erasure flow + soft-delete + permanent purge after retention period (daily-scheduled) | `DataRetentionService` + `DataRetentionHostedService` | ✅ |

---

## Privacy (P1)

| ID | Control | Implementation | Evidence | Status |
|---|---|---|---|---|
| P1.1 | Provides notice about its privacy practices | Public privacy policy at `/welcome/Company/privacy` | `PrivacyPage.tsx` | ✅ |
| P1.2 | Communicates choice and consent | Cookie consent + marketing-email opt-out + analytics opt-out | `CookieConsentBanner.tsx` (rendered in `App.tsx`, gates `analytics.ts`) | ✅ |
| P1.3 | Collects personal information from authorised sources | Self-service signup + SSO with explicit user consent | `SignupPage` + `SsoCallbackPage` | ✅ |
| P1.4 | Processes personal information per notice | DPIA documents per data flow | `docs/65-pdpl-dpia.md` (Wave B) | ✅ |
| P1.5 | Provides quality data | Data-quality nightly job + cleanse hub | `DataQualityNightlyJob` + `/admin/data-quality` | ✅ |
| P1.6 | Provides individuals with access to personal information | User profile self-service + data export endpoint | `ProfilePage` + `/api/me/export` | ✅ |
| P1.7 | Provides individuals with the ability to update their personal information | Profile edit + email change with verification | `ProfilePage` | ✅ |
| P1.8 | Discloses or transmits personal information to authorised third parties | Encrypted transit + DPA on file with sub-processors | Stripe / Anthropic / SendGrid DPAs | ✅ |
| P1.9 | Securely retains personal information | Tenant-isolated SQL Server with TDE + Azure Key Vault for secrets | Cloud config | ✅ |
| P1.10 | Disposes of personal information | Right-to-erasure flow | `DataRetentionService` | ✅ |

---

## Status legend

* ✅ — control fully implemented; evidence on file.
* 🔄 — partially implemented; gap captured in audit registry; ETA tracked.
* ⚪ — vendor-provided control; rely on sub-processor's SOC 2.

---

## Gap summary (refreshed 2026-07-21 — decisions/0126; see that record for the verification evidence)

1. **CC6.8, C1.2/P1.10, P1.2** — all closed. Confirmed shipped and wired (not just present as a
   file): dependency scanning is blocking in `ci.yml`, `DataRetentionService` runs on a daily
   `DataRetentionHostedService` schedule with its own test coverage, and `CookieConsentBanner.tsx`
   is rendered in `App.tsx` and gates `analytics.ts`.
2. **A1.1 — still open, scope narrowed.** The load-test file path in the original gap line
   (`tests/load/k6-100k-assets.js`) never existed; the real script is `tests/k6/load.js`. It
   validates **concurrency** (a 100-VU ramp against p95 latency thresholds), not **data-volume**
   scale — there is no test yet that proves performance against a 100k-row asset dataset
   specifically. Keep this item open until a data-scale load test exists; do not close it on the
   strength of the concurrency test alone.
3. **New item — CC6.1 crypto-agility (closed 2026-07-21):** the password hasher previously
   hardcoded its iteration count with no version marker in the stored hash, meaning the count
   could never be raised again without invalidating every existing password. Fixed to a
   self-describing, backward-compatible format at 600,000 iterations (OWASP's current minimum)
   with silent upgrade-on-login. See `decisions/0126-password-hash-crypto-agility-and-doc-accuracy.md`.

Each open item is mirrored in the platform audit registry with the lens owner, current score, and ETA. See `/admin/audit` "Next Actions" panel.
