Automated Compliance Readiness Platform for SMB SaaS
A production-grade compliance operations platform that eliminates the guesswork from SOC 2, ISO 27001, and GDPR preparation. Built for technical founders who need audit-ready documentation without enterprise tooling overhead.
ComplianceCheckpoint is not a monitoring tool. It's not AI magic. It's not "one-click compliance."
It is compliance operations software — structured workflows, evidence tracking, policy generation, and audit exports that pass real scrutiny.
We trade automation theater for:
- Crystal-clear control requirements
- Auditor-friendly evidence organization
- Export formats that work in actual audits
- SOC 2 Type I readiness: Complete Trust Services Criteria control library
- ISO 27001 readiness: Annex A controls with implementation guidance
- GDPR readiness: Documentation frameworks and DPIA templates (not legal advice)
- Policy generation: Template-based, editable policy library
- Evidence management: Versioned uploads with control mapping
- Task tracking: Ownership, deadlines, completion tracking
- Audit exports: PDF/ZIP packages ready for auditor review
- Role-based access: Founder, Admin, Contributor, Read-only Auditor
- Continuous infrastructure monitoring
- Deep cloud provider integrations (AWS/GCP/Azure)
- Real-time security posture dashboards
- Automated control testing
- Compliance certification (we prepare, you certify)
Our edge is clarity, structure, and execution — not vaporware automation.
┌─────────────────────────────────────┐
│ Frontend (Vite + React + shadcn) │
│ - TypeScript strict mode │
│ - Role-based routing │
│ - React Query for state │
└──────────────┬──────────────────────┘
│ REST / JSON
▼
┌─────────────────────────────────────┐
│ Backend (FastAPI) │
│ - Async SQLAlchemy 2.0 │
│ - Pydantic v2 validation │
│ - JWT auth via Neon │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Neon PostgreSQL │
│ - Built-in auth │
│ - Row-level security │
│ - Automated backups │
└─────────────────��───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Object Storage (S3-compatible) │
│ - Evidence file storage │
│ - Audit export packages │
│ - Version metadata in DB │
└─────────────────────────────────────┘
- Boring is good: Auditors trust conventional architecture
- Postgres for everything: No multi-database complexity
- Files in object storage: Not in the database
- Stateless API: Every request fully authenticated
- Explicit over clever: No magic, no surprises
- Vite — Fast builds, no webpack trauma
- React 18 with TypeScript strict mode
- shadcn/ui — Radix primitives + Tailwind
- TanStack Query (React Query) — Server state management
- React Hook Form + Zod — Type-safe form validation
- Recharts — Minimal progress visualization
- React Router 6 — Role-based route protection
- Python 3.11+
- FastAPI — Async, OpenAPI, Pydantic native
- SQLAlchemy 2.0 (async engine)
- Pydantic v2 — Validation and serialization
- Alembic — Database migrations
- python-jose — JWT handling
- Passlib + bcrypt — Password hashing
- boto3 — S3-compatible storage client
- Neon PostgreSQL — Serverless Postgres with built-in auth
- Backblaze B2 / AWS S3 — Evidence + export storage
- Render / Railway / Fly.io — Backend deployment
- Vercel / Netlify / Cloudflare Pages — Frontend deployment
- Docker Compose — Local Postgres + MinIO for development
- pytest + httpx — Backend testing
- Vitest + Testing Library — Frontend testing
- pre-commit hooks — Linting, formatting, type checking
id: UUID
name: str
industry: str
employee_count: int
compliance_targets: list[str] # ["SOC2", "ISO27001", "GDPR"]
created_at: datetimeid: UUID
org_id: UUID
name: str
email: str
role: enum # Founder, Admin, Contributor, Auditor
created_at: datetimeid: UUID
name: str # "SOC 2", "ISO 27001", "GDPR"
version: str
description: strid: UUID
framework_id: UUID
control_code: str # "CC6.1", "A.8.2"
title: str
description: str
category: str
severity: enum # Critical, High, Medium, Low
guidance_text: str # Markdown implementation guidanceid: UUID
org_id: UUID
framework_id: UUID
title: str
content: str # Markdown
status: enum # Draft, Approved
last_updated: datetime
approved_by: UUID | nullid: UUID
control_id: UUID
org_id: UUID
file_url: str
file_hash: str # SHA-256
uploaded_by: UUID
uploaded_at: datetime
version: int
status: enum # Pending, Accepted, Rejected
notes: str | nullid: UUID
control_id: UUID
org_id: UUID
owner_id: UUID
title: str
due_date: date
status: enum # Open, InProgress, Blocked, Complete
notes: str | null
created_at: datetimeid: UUID
org_id: UUID
framework_id: UUID
generated_at: datetime
download_url: str
expires_at: datetime
generated_by: UUID- Organization isolation: Every query filters by org_id
- Framework flexibility: Add HIPAA, PCI-DSS without schema changes
- Evidence versioning: Immutable uploads, metadata tracks changes
- Task ownership: Clear accountability, no diffusion
- Audit trail: Every export is logged and retrievable
This is deliberately boring. Auditors like boring.
backend/
├── app/
│ ├── main.py # FastAPI app initialization
│ ├── core/
│ │ ├── config.py # Environment + settings
│ │ ├── security.py # JWT + password utils
│ │ └── dependencies.py # Dependency injection
│ ├── db/
│ │ ├── base.py # SQLAlchemy Base
│ │ ├── session.py # Async session factory
│ │ └── models/
│ │ ├── __init__.py
│ │ ├── user.py
│ │ ├── organization.py
│ │ ├── framework.py
│ │ ├── control.py
│ │ ├── policy.py
│ │ ├── evidence.py
│ │ ├── task.py
│ │ └── audit_export.py
│ ├── schemas/ # Pydantic models
│ │ ├── user.py
│ │ ├── organization.py
│ │ ├── control.py
│ │ ├── policy.py
│ │ ├── evidence.py
│ │ └── task.py
│ ├── api/
│ │ └── v1/
│ │ ├── __init__.py
│ │ ├── auth.py # Login, register, session
│ │ ├── organizations.py
│ │ ├── controls.py # List, detail, filter by framework
│ │ ├── policies.py # Generate, edit, approve
│ │ ├── evidence.py # Upload, version, status
│ │ ├── tasks.py # CRUD + assignment
│ │ └── audits.py # Export generation
│ ├── services/
│ │ ├── policy_generator.py # Template-based policy creation
│ │ ├── audit_exporter.py # PDF/ZIP package creation
│ │ └── evidence_validator.py # File hash, type checking
│ └── utils/
│ ├── markdown.py # Markdown → HTML/PDF
│ └── file_hash.py # SHA-256 hashing
├── alembic/
│ ├── versions/ # Migration files
│ └── env.py
├── tests/
│ ├── conftest.py
│ ├── test_auth.py
│ ├── test_controls.py
│ └── test_evidence.py
├── requirements.txt
├── requirements-dev.txt
├── Dockerfile
├── docker-compose.yml
└── README.md
frontend/
├── src/
│ ├── app/
│ │ ├── routes.tsx # React Router config
│ │ └── providers.tsx # QueryClient, AuthContext
│ ├── components/
│ │ ├── ui/ # shadcn components
│ │ ├── layout/
│ │ │ ├── AppLayout.tsx
│ │ │ ├── Sidebar.tsx
│ │ │ └── Header.tsx
│ │ ├── tables/
│ │ │ ├── ControlsTable.tsx
│ │ │ ├── EvidenceTable.tsx
│ │ │ └── TasksTable.tsx
│ │ └── forms/
│ │ ├── PolicyForm.tsx
│ │ ├── EvidenceUpload.tsx
│ │ └── TaskForm.tsx
│ ├── pages/
│ │ ├── auth/
│ │ │ ├── Login.tsx
│ │ │ └── Register.tsx
│ │ ├── dashboard/
│ │ │ └── Dashboard.tsx
│ │ ├── controls/
│ │ │ ├── ControlsList.tsx
│ │ │ └── ControlDetail.tsx
│ │ ├── policies/
│ │ │ ├── PoliciesList.tsx
│ │ │ └── PolicyEditor.tsx
│ │ ├── evidence/
│ │ │ └── EvidenceManager.tsx
│ │ ├── tasks/
│ │ │ └── TaskBoard.tsx
│ │ └── audit/
│ │ └── AuditExport.tsx
│ ├── hooks/
│ │ ├── useAuth.ts
│ │ ├── useControls.ts
│ │ ├── usePolicies.ts
│ │ └── useEvidence.ts
│ ├── lib/
│ │ ├── api.ts # Axios instance + interceptors
│ │ ├── auth.ts # Token management
│ │ └── validators.ts # Zod schemas
│ ├── styles/
│ │ └── globals.css
│ └── main.tsx
├── public/
├── index.html
├── package.json
├── tsconfig.json
├── tailwind.config.ts
├── vite.config.ts
└── README.md
POST /api/v1/auth/register
POST /api/v1/auth/login
GET /api/v1/auth/me
POST /api/v1/auth/logout
GET /api/v1/controls?framework=soc2
GET /api/v1/controls/{id}
GET /api/v1/controls/{id}/evidence
GET /api/v1/controls/{id}/tasks
GET /api/v1/policies
POST /api/v1/policies/generate # Body: {framework_id, template_type}
GET /api/v1/policies/{id}
PUT /api/v1/policies/{id}
PUT /api/v1/policies/{id}/approve
DELETE /api/v1/policies/{id}
POST /api/v1/evidence/upload # Multipart form
GET /api/v1/evidence/control/{control_id}
GET /api/v1/evidence/{id}
PUT /api/v1/evidence/{id}/status # Body: {status, notes}
DELETE /api/v1/evidence/{id}
GET /api/v1/tasks?status=pending
POST /api/v1/tasks
GET /api/v1/tasks/{id}
PUT /api/v1/tasks/{id}
DELETE /api/v1/tasks/{id}
POST /api/v1/audit/export # Body: {framework_id}
GET /api/v1/audit/export/{id}
GET /api/v1/audit/export/{id}/download
- Every control must specify accepted evidence types
- Guidance must explain why evidence proves the control
- Examples must be concrete (not "documentation")
- Templates must be editable after generation
- No locked-in content — founders need customization
- Generated policies must include placeholder sections for org-specific details
- Must include:
- Cover page with org details
- Control-by-control breakdown
- Policy attachments
- Evidence file index with hashes
- Generation timestamp + auditor access instructions
- Must be readable without proprietary software
- Must survive email + print
- Auditors get read-only access to everything
- Contributors can upload evidence, cannot approve policies
- Admins can approve policies, assign tasks
- Founders can delete data (with confirmation)
- Node.js 18+
- Python 3.11+
- Docker + Docker Compose (for local dev)
- Neon account (or local Postgres)
- S3-compatible storage credentials
git clone https://github.com/your-org/compliancecheckpoint.git
cd compliancecheckpoint
# Backend
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements-dev.txt
# Frontend
cd ../frontend
npm installBackend (backend/.env):
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/compliance
SECRET_KEY=your-secret-key-generate-with-openssl-rand-hex-32
S3_ENDPOINT=http://localhost:9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=compliance-evidenceFrontend (frontend/.env):
VITE_API_URL=http://localhost:8000# Start Postgres + MinIO
docker-compose up -d
# Run migrations
cd backend
alembic upgrade head
# Seed initial data (frameworks + controls)
python scripts/seed_frameworks.py# Backend (from /backend)
uvicorn app.main:app --reload --port 8000
# Frontend (from /frontend, separate terminal)
npm run devNavigate to http://localhost:5173
- Connect GitHub repo
- Set environment variables:
DATABASE_URL(Neon connection string)SECRET_KEYS3_ENDPOINT,S3_ACCESS_KEY,S3_SECRET_KEY,S3_BUCKET
- Build command:
pip install -r requirements.txt - Start command:
uvicorn app.main:app --host 0.0.0.0 --port $PORT
- Connect GitHub repo
- Build command:
npm run build - Output directory:
dist - Environment variable:
VITE_API_URL(production backend URL)
# Generate migration after model changes
alembic revision --autogenerate -m "description"
# Apply in production
alembic upgrade headcd backend
pytest # All tests
pytest tests/test_auth.py # Specific module
pytest --cov=app --cov-report=htmlcd frontend
npm run test # Vitest unit tests
npm run test:ui # Vitest UI mode- Control library (SOC 2 Trust Services Criteria)
- Research AICPA TSC official documentation
- Write guidance for each control (not copy-paste)
- Categorize by domain (CC, A, PI, etc.)
- Database models + migrations
- Auth flow (register, login, session)
- Policy generator (5-7 base templates)
- Information Security Policy
- Access Control Policy
- Incident Response Policy
- Data Classification Policy
- Acceptable Use Policy
- Evidence upload + storage
- Task assignment + tracking
- Audit export (PDF package generation)
- Read-only auditor access
- Control completion dashboard
- ISO 27001 Annex A controls
- GDPR documentation templates
- Email notifications (task reminders, evidence approvals)
Everything else is decoration.
- Poorly written control guidance = instant credibility death
- Founders will know if you Ctrl+C'd from Wikipedia
- Auditors will tear apart vague language
- They don't need "compliance score" gamification
- They need: "Here's what to do next"
- Show progress, not vanity metrics
"Can I export this and give it to an auditor right now?"
If the answer isn't "yes, immediately, with zero additional work", you lose.
- Not a security monitoring tool (no agent, no integrations)
- Not a GRC platform (no risk registers, no vendor management)
- Not automated compliance (no "one-click SOC 2")
- Not legal advice (we're documentation infrastructure)
We are workflow software for compliance preparation. Boring, structured, judge-proof.
| Risk | Mitigation |
|---|---|
| Control library is shallow/wrong | Hire a compliance consultant to review before v1 launch |
| Audit exports aren't accepted | Test with 3 real auditors before claiming "audit-ready" |
| No one needs this | 100 founder interviews before writing code |
| Vanta/Drata kill you | Focus on prep, not continuous monitoring (different market) |
| You run out of money | Charge $200/mo from day 1, no freemium delusions |
We don't accept PRs for control content without citations. If you're adding framework controls:
- Cite the source (AICPA, ISO, GDPR articles)
- Write guidance in your own words (no copy-paste)
- Include evidence examples (specific file types, not "documentation")
- Test with a real auditor if possible
For code contributions:
- Follow existing patterns (boring is good)
- Write tests for new endpoints
- Update OpenAPI docs
- No clever abstractions without justification
MIT License — we're infrastructure, not legal advice.
- Issues: GitHub Issues (for bugs, not compliance questions)
- Discussions: GitHub Discussions (for product feedback)
- Email: founders@compliancecheckpoint.dev (for partnerships, not support)
This exists because compliance tooling sucks. We're trying to fix that by being:
- Honest about what we do (and don't do)
- Boring in architecture
- Ruthless about quality
- Helpful without handholding
If you're building this, you're probably technical, frustrated with existing tools, and willing to do hard research work. Good. That's who this is for.
No pep talk. Just execution.