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

# SOC 2 Readiness

> Honest mapping of Causeloop's current SOC 2 control posture — what's in place, what's partial, and what's still a gap.

This page summarises Causeloop's readiness for a SOC 2 Type I and Type II report, drawn directly from `docs/SOC2-TYPE-I-READINESS-PLAN.md` and `docs/SOC2-TYPE-II-READINESS-AUDIT.md`. Controls that are not yet fully implemented are represented accurately as partial or gaps — not as complete.

<Note>
  **Where we are:** Causeloop has an unusually strong security-by-design foundation for a pre-audit product. The technical architecture — real JWT + WorkOS RS256/JWKS, RBAC permission catalogue, RLS on tenant tables, rate limiting, idempotency, a comprehensive audit log, TLS, and envelope encryption design — positions it well for Type I. The gaps that block a Type II report are real and documented below.
</Note>

## Target scope

The planned SOC 2 scope covers three Trust Services Categories:

| Category                   | In scope  | Notes                                           |
| -------------------------- | --------- | ----------------------------------------------- |
| Security (CC1–CC9)         | Yes       | Primary category                                |
| Availability (A1)          | Yes       | Health endpoints, uptime                        |
| Confidentiality (C1)       | Yes       | Encryption, export controls                     |
| Processing Integrity (PI1) | Partially | Deferred for Type I pending ingestion engine    |
| Privacy (P1–P8)            | Partially | RTBF + export APIs exist; full pipeline pending |

## Type I vs. Type II

|                    | Type I                                            | Type II                                                |
| ------------------ | ------------------------------------------------- | ------------------------------------------------------ |
| What's tested      | Controls designed and in place on a specific date | Controls operated effectively over a 3–12 month window |
| Evidence burden    | Each control *exists* and is documented           | Each control *kept working* throughout the window      |
| Realistic timeline | \~8–12 weeks                                      | Type I work + observation window + audit               |
| Buyer signal       | "We built this correctly"                         | "We've been running this reliably"                     |

**Current state:** Type I is achievable within 8–12 weeks if organizational tracks (policy suite, risk assessment, vendor inventory) run in parallel with the remaining technical work. Type II requires the additional observation window after Type I controls are in place.

## Controls in place

| Control                                                           | Status                    | Evidence                                                                                                          |
| ----------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **JWT auth** — HS256 tokens, scoped permission catalogue          | In place                  | `app/security.py`, `app/models.py` PERMISSIONS constant                                                           |
| **WorkOS RS256/JWKS** — frontend session verification             | In place                  | `POST /auth/exchange` verifies WorkOS access tokens against JWKS URL                                              |
| **RBAC** — role-based access with typed scopes                    | In place                  | `require_scope()` decorators on all protected routes; admin/owner/analyst/viewer roles                            |
| **Personal Access Tokens** — SHA-256 hashed, scoped               | In place                  | `personal_access_tokens` table; `pat_hash` stored, never plaintext                                                |
| **Row-Level Security** — tenant data isolation at DB layer        | Partial — see gaps        | RLS + FORCE RLS on \~18 tenant tables; two-role model documented                                                  |
| **Rate limiting** — 1,000 req/min token bucket                    | In place                  | `app/middleware/rate_limit.py`                                                                                    |
| **Idempotency** — `Idempotency-Key` deduplication                 | In place                  | `app/middleware/idempotency.py`                                                                                   |
| **Audit log** — append-only, RLS-scoped, workspace-retained       | In place                  | `audit_log` table; `0002_audit_trace_append_only.sql` trigger; \~121 call sites                                   |
| **TLS in transit** — Caddy + Let's Encrypt                        | In place                  | `Caddyfile`; HSTS + security headers                                                                              |
| **CORS allowlist**                                                | In place                  | `CORS_ORIGINS` env var; no wildcard in production                                                                 |
| **Inbound webhook HMAC — fail-closed**                            | In place                  | `x-causeloop-signature` verified with `hmac.compare_digest`; fails closed if missing                              |
| **Envelope encryption design** — AES-256-GCM KEK/DEK              | In place (partial wiring) | `app/crypto/envelope.py`; `workspace_keys` table; `0003_workspace_keys.sql`                                       |
| **Retention policy model** — per-workspace configurable retention | In place                  | `workspace_settings` retention columns; `app/services/retention.py`                                               |
| **RTBF API** — Article 17 request tracking                        | In place                  | `POST /governance/rtbf/requests`; subject\_ref HMAC-hashed; duplicate-request guard; erasure certificate endpoint |
| **Data export API** — tenant data export                          | In place                  | `POST /governance/exports`; RLS-scoped; secrets excluded from export                                              |
| **Non-root container**                                            | In place                  | `Dockerfile` — `adduser appuser; USER appuser`                                                                    |
| **NOSUPERUSER app role** — `causeloop_app`                        | In place                  | `0006_resolve_inbound_webhook.sql` GRANT guidance; docs specify `NOBYPASSRLS`                                     |

## Partial controls and gaps

### Technical gaps (code-addressable)

| #  | Gap                                                                                                                                                                   | Criteria         | Effort | Status     |
| -- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------ | ---------- |
| 1  | **Real password hashing** — password login currently accepts any password (no Argon2/bcrypt)                                                                          | CC6.1            | S      | Gap        |
| 2  | **Centralized logging + SIEM + metrics/tracing** — no structured log aggregation, no security alerting                                                                | CC7.1–7.3, CC4.1 | L      | Gap        |
| 3  | **Security alerting** — no automated alerts on auth failures, rate-limit spikes, anomalies                                                                            | CC7.2, CC7.3     | M      | Gap        |
| 4  | **Real MFA** — TOTP + recovery codes endpoint is a stub                                                                                                               | CC6.1            | M      | Gap — stub |
| 5  | **Real SSO/SAML + OIDC** — `/sso` endpoints are stubs                                                                                                                 | CC6.1            | L      | Gap — stub |
| 6  | **SCIM on Postgres** — SCIM endpoints exist but are not backed by real data; no auto-deprovisioning                                                                   | CC6.1, CC6.5     | M      | Gap — stub |
| 7  | **Full KMS wiring** — `config_encrypted` / `secret_encrypted` columns exist; app-layer encrypt/decrypt not fully wired                                                | CC6.1, C1.1      | M      | Partial    |
| 8  | **Complete RLS coverage** — \~18 of \~45 tenant tables have policies                                                                                                  | CC6.1, C1.1      | M      | Partial    |
| 9  | **Automated verified backups** — current approach is manual `pg_dump` runbook                                                                                         | A1.2, A1.3       | M      | Gap        |
| 10 | **Retention purge job** — `purge_expired()` exists but is not scheduled; no cron or worker runs it                                                                    | C1.2, P4         | M      | Partial    |
| 11 | **RTBF deletion pipeline** — request tracking exists; actual hard-delete execution via `erase_workspace()` is wired on approve but requires `DATABASE_URL` at runtime | P4, P5, P8       | M      | Partial    |
| 12 | **Export pipeline to object storage** — exports return data in-response; no S3/GCS presigned URL, no checksum                                                         | PI1.4, C1.1      | L      | Partial    |
| 13 | **Dependency + container scanning in CI**                                                                                                                             | CC6.8, CC7.1     | S      | Gap        |
| 14 | **Change-management gates** — no branch protection, no expanded CI, no migration framework (Alembic)                                                                  | CC8.1            | M      | Gap        |
| 15 | **Real `X-RateLimit-*` headers** — current headers are stubs                                                                                                          | CC6.1            | S      | Gap        |

### Organizational gaps (not code)

These require policies, people, and process — not code changes:

| Area                       | Gap                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------- |
| Security ownership         | Assign a named security owner                                                         |
| Policy suite               | Written security policy, acceptable use policy, incident response plan, BCP/DR plan   |
| Risk assessment            | Formal, documented risk assessment                                                    |
| Access reviews             | Periodic (quarterly) access review sign-off                                           |
| Vendor inventory           | Sub-processor list with their SOC 2 reports (AWS/GCP/Neon, WorkOS, Anthropic, OpenAI) |
| Data classification        | Formal data classification policy                                                     |
| Employee security training | Annual security awareness training records                                            |
| Physical access            | Rely on sub-processor SOC 2 — collect and review their reports                        |
| Incident response tabletop | Run and document at least one IR simulation                                           |

## Recommended path to Type I

Run two tracks in parallel over \~8–12 weeks:

**Weeks 1–2 — Foundations**

* Eng: real password hashing (Argon2id); centralized logging (Sentry + OTel); branch protection + CI + dependency scanning
* Org: kick off policy suite; assign security owner; start risk assessment

**Weeks 3–5 — Identity & access**

* Eng: real MFA (TOTP + recovery); SCIM on Postgres; extend RLS to all tenant tables; secrets management
* Org: asset inventory; data-flow diagrams; vendor/sub-processor inventory

**Weeks 4–7 — SSO, encryption, availability**

* Eng: real SSO/SAML + OIDC; full KMS wiring; automated backups + restore test; security alerting
* Org: BCP/DR plan; incident-response plan

**Weeks 6–9 — Data lifecycle & privacy**

* Eng: schedule retention purge job; wire RTBF deletion pipeline; export to object storage; LLM PII-redaction layer
* Org: privacy notice; DPAs; data classification and retention policies

**Weeks 8–12 — Readiness review**

* Assemble evidence pack; internal gap walkthrough; set "as of" date; engage auditor

<Tip>
  Engage an auditor around week 2 to confirm scope — particularly whether to narrow Processing Integrity and Privacy for Type I. This avoids building to the wrong target.

  Every control put "in place" for Type I should also emit evidence logs, so the Type II observation window starts accumulating data immediately with no rework.
</Tip>

## Related documents

* `docs/SOC2-TYPE-I-READINESS-PLAN.md` — sprint plan, Type I scope, evidence pack checklist
* `docs/SOC2-TYPE-II-READINESS-AUDIT.md` — full five-category control matrix and gap register
* [Security model](/deploy-security/security-model) — technical implementation details
* [GDPR & data governance](/deploy-security/gdpr-governance) — privacy controls
