A Vanta-style compliance management application for SOC 2, ISO/IEC 27001:2022 and PCI DSS v4.0.1. It ships with the full control libraries for all three frameworks, an evidence folder tree segregated by control, role-based access to folders, document lifecycle management with review scheduling, automated review reminders over a standard IMAP/POP3 + SMTP mailbox or Amazon SES, an analytics dashboard, an account settings area, and a dashboard calendar.
For preloaded compliance data you must unzip compliance-data.zip in the root directory before building.
Want a look before installing? Open app-preview.html in a browser — a clickable static preview of all 12 screens with the live theme switcher (no install needed).
For the full manual — installation paths, configuration reference, and every workflow in depth — see USER_GUIDE.md.
New to the project? Start with GETTING_STARTED.md —
one walkthrough that installs, verifies, and tests every function (including
the document-review email reminders). INSTALL.md has the
one-command installer details.
Security posture, the audit findings, and the production checklist are in
SECURITY.md. Setup requirements live in
PREREQUISITES.md, and the automated readiness report is
VALIDATION.md — re-run it any time with
python3 tools/validate.py. A design spec for the planned SharePoint
integration (OAuth email login, session retention, email-scoped viewer
links) is in docs/SHAREPOINT_INTEGRATION.md.
| Requirement | Where it lives |
|---|---|
| SOC 2 / ISO 27001 / PCI DSS v4.0.1 control libraries | backend/compliance/data/*.json (217 controls) generated by tools/build_seed_data.py |
| Neat folder tree segregated by control | backend/compliance/folder_tree.py + manage.py generate_folder_tree → compliance-data/ |
| SMTP alerts for documents coming up for review | backend/notifications/tasks.py (+ send_review_reminders command / Celery beat) |
| Mail owners from a standard mailbox (IMAP/POP3 + SMTP) | backend/notifications/mailbox.py, toggled by EMAIL_PROVIDER=mailbox (+ manage.py test_mailbox) |
| Amazon SES for mailing | backend/notifications/ses.py, toggled by EMAIL_PROVIDER=ses |
| Analytics dashboard (readiness, status mix, review timeline, ownership) | backend/analytics/ (/api/analytics/summary) + frontend/src/pages/Analytics.jsx |
| Account settings sidebar (profile, password, role & access) | frontend/src/pages/Account.jsx + /api/users/me (PATCH) & /api/users/change_password |
| User access audits (grid + CSV export) | backend/governance/ (/api/access-reviews) + frontend/src/pages/UserAudit.jsx |
| Meeting minutes with required yearly cadence | governance.MeetingSeries / MeetingMinute + frontend/src/pages/Meetings.jsx |
| Champion groups (owned, inter-departmental) | governance.ChampionGroup / GroupMember + frontend/src/pages/Groups.jsx |
| Optional Jira board tracking | backend/integrations/ (stdlib REST client) + frontend/src/pages/Jira.jsx |
| Immutable audit trail with in-app viewer — every create/update/delete captured server-side (actor, record, detail, IP); filterable, searchable, read-only, gated to admins/auditors/view-all | audit.AuditLogMiddleware + /api/audit-log/, frontend/src/pages/AuditLog.jsx |
| Theming — Audit Ledger + Blazor themes, each with light & dark, plus a custom accent-colour picker (Account → Appearance), persisted per browser | frontend/src/theme.js engine + CSS token themes in styles/app.css |
| Per-account notification bell — feed derived from each user's ownership, assignments, and role (documents, risks, events, meetings, manager digests, access reviews) | backend/notifications/notifications.py engine + NotificationReceipt, /api/notifications/*, frontend/src/components/NotificationBell.jsx |
| Two-factor auth (TOTP, RFC 6238) with backup codes + admin reset | accounts/mfa.py (stdlib), MfaDevice/MfaBackupCode, /api/auth/mfa/*, Security tab in Account.jsx, two-step Login.jsx |
| User management admin panel (create users, assign roles, activate/deactivate, reset passwords) with lockout guards | accounts.UserViewSet guards + frontend/src/pages/Users.jsx |
| Risk register with remediation notes, CSV/XLSX import, CSV export | governance.Risk/RiskNote (/api/risks), stdlib importer governance/risk_import.py, frontend/src/pages/Risks.jsx, sample file docs/sample-risk-import.csv |
| Evidence ↔ control mapping (cross-framework, with bulk attach) | compliance.ControlEvidence (/api/control-evidence) + evidence drawer in Controls.jsx, "satisfies" chips in Documents.jsx |
| Calendar on the main dashboard | frontend/src/components/Calendar.jsx + calendar_app (/api/calendar/feed) |
| Storage of common document forms | documents.FormTemplate + /api/form-templates |
| Document renaming & managing | documents.Document + rename / move / new-version / mark-reviewed actions |
| Assign owners | owner on controls, folders and documents |
| Role-based access to specific folders | accounts.Role + documents.FolderPermission (inherited down the tree) |
- Backend: Django 5 + Django REST Framework, JWT auth
- Async / scheduling: Celery + Redis (review-reminder scan runs daily)
- Storage: local filesystem by default, Amazon S3 optional (
django-storages) - Email: a standard IMAP/POP3 + SMTP mailbox, Amazon SES (boto3), plain SMTP, or console
- Frontend: React 18 + Vite
- Database: SQLite locally, PostgreSQL in Docker/production
cp .env.example .env # edit if you like; defaults work
# point the DB at Postgres for the compose stack:
echo "POSTGRES_DB=compliance" >> .env
echo "POSTGRES_USER=compliance" >> .env
echo "POSTGRES_PASSWORD=compliance" >> .env
docker compose up --buildThen open:
- App: http://localhost:8080 (log in as
admin/DemoPass123!) - API: http://localhost:8000/api/
- Django admin: http://localhost:8000/admin/
The backend container automatically migrates, seeds all three frameworks, builds the folder tree, and loads demo data on first boot.
Backend
cd backend
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp ../.env.example ../.env # console email + SQLite
python manage.py makemigrations accounts compliance documents calendar_app notifications audit governance integrations
python manage.py migrate
python manage.py seed_frameworks --with-folders # controls + app folders + roles
python manage.py bootstrap_demo # demo users, docs, events
python manage.py generate_folder_tree # physical evidence tree on disk
python manage.py runserverFrontend (second terminal)
cd frontend
npm install
npm run dev # http://localhost:5173 (proxies /api to :8000)Log in as admin / DemoPass123!.
Two layers work together:
- Role capabilities (
accounts.Role) — platform-wide flags: manage users, manage frameworks, manage documents, manage folders, view-all, auditor. Five roles are seeded: Administrator, Compliance Manager, Control Owner, Auditor, Viewer. - Folder permissions (
documents.FolderPermission) — grant a role or a specific userview/edit/manageon a folder. Grants are inherited by every subfolder, so giving "Control Owner → edit" onCC6cascades to all CC6 controls. Document access is derived from its folder; owners can always edit their own documents; auditors are capped at read-only.
Effective access is computed in Folder.effective_access(user).
Set the provider in .env:
EMAIL_PROVIDER=console # dev: prints emails to the log
EMAIL_PROVIDER=smtp # any SMTP server (set EMAIL_HOST etc.)
EMAIL_PROVIDER=mailbox # a standard inbox: IMAP/POP3 connects, SMTP sends
EMAIL_PROVIDER=ses # Amazon SES (set AWS_SES_REGION + credentials)
REVIEW_ALERT_LEAD_DAYS=30,14,7,1
With EMAIL_PROVIDER=mailbox, reminders go out through an ordinary mail account
(backend/notifications/mailbox.py). IMAP or POP3 is used to connect to the
mailbox — verifying the credentials and, for IMAP, filing a copy of each reminder
in the Sent folder — while SMTP performs the actual send (IMAP/POP3 cannot
send mail). The SMTP host/username default to the mailbox values, so a single
provider often needs only the four MAILBOX_* lines in .env.example. Verify a
mailbox and send yourself a test with python manage.py test_mailbox --to you@x.com.
Each document has a review cadence (monthly … biennial). next_review_date is
computed from last_reviewed + cadence. A daily scan
(notifications.tasks.run_review_scan, wrapped by the Celery task
scan_document_reviews) emails the document owner and the compliance team when
a lead threshold is first crossed, and again once when a document goes overdue —
never duplicating a reminder.
Run the scan on a schedule two ways:
- Celery beat (Docker
workerservice runs this automatically), or - cron:
python manage.py send_review_reminders(add--dry-runto preview).
manage.py generate_folder_tree writes a filesystem tree to compliance-data/:
compliance-data/
SOC2/CC6 - Logical and Physical Access Controls/CC6.1 - Access security/
_control.md policies/ procedures/ evidence/ forms/
ISO27001/...
PCI-DSS-v4.0.1/...
Point it anywhere with --root, or set COMPLIANCE_TREE_ROOT (e.g. an
S3-synced directory) to keep a browsable on-disk mirror alongside the app.
POST /api/auth/token/ # obtain JWT
GET /api/users/me/ # current user + capabilities
PATCH /api/users/me/ # update own profile (name/email/job title)
POST /api/users/change_password/ # change own password
GET /api/analytics/summary/ # dashboard metrics (readiness, status, reviews)
GET /api/frameworks/ # frameworks with control counts
GET /api/frameworks/{key}/controls/ # controls for a framework
GET /api/controls/ PATCH /api/controls/{id}/ # status / owner
GET /api/crosswalk/ # cross-framework control mappings
GET /api/control-evidence/?control= # evidence linked to a control (folder-scoped)
POST /api/control-evidence/bulk/ # attach several documents to one control
GET /api/control-evidence/choices/ # pick-lists: visible documents + control catalog
GET /api/folders/tree/ # access-filtered folder tree
GET /api/folders/{id}/permissions/ # folder access grants
POST /api/folder-permissions/ # grant role/user access to a folder
GET /api/documents/ # documents (folder-scoped by access)
POST /api/documents/{id}/rename/ # rename
POST /api/documents/{id}/move/ # move to another folder
POST /api/documents/{id}/new_version/ # upload a new version (archives the old)
POST /api/documents/{id}/mark_reviewed/
GET /api/documents/reviews/?days=90 # upcoming / overdue reviews
GET /api/calendar/feed/?start=&end= # events + synthesized review deadlines
GET /api/form-templates/ # shared blank forms library
POST /api/access-reviews/ # snapshot all users into an audit grid
PATCH /api/access-review-items/{id}/ # record keep / modify / revoke decisions
GET /api/access-reviews/{id}/export/ # download the audit grid as CSV
GET /api/meeting-series/ # meeting cadences w/ held-vs-required status
POST /api/meeting-minutes/ # record minutes (optional file attachment)
GET /api/champion-groups/ # owned inter-departmental champion groups
GET /api/risks/ PATCH /api/risks/{id}/ # risk register (status/owner/plan)
GET /api/risks/summary/ # open / overdue / rating counts
POST /api/risks/import/ # ingest a register from .csv or .xlsx
GET /api/risks/export/ # download the register as CSV
POST /api/risk-notes/ # add a remediation progress note
GET /api/integrations/jira/config/ # Jira connection (managers; token write-only)
GET /api/integrations/jira/boards/{id}/issues/ # issues from a tracked board
Control IDs and short titles are functional identifiers. The objective fields
are brief, original-wording paraphrases — not the normative text of the
standards. ISO/IEC 27001 and PCI DSS are copyrighted; only paste official control
text into the app if your organisation holds a licence for the source documents.
- Automated evidence collection via cloud/SaaS integrations (AWS, GitHub, Okta, …)
- Auditor workspace with read-only evidence export and a Type II audit window
- Per-control readiness scoring (evidence mapping shipped — see
/api/control-evidence) - Notifications beyond email (Slack/Teams), digests, and escalation
- SSO/SAML, granular field-level audit history, and data-retention policies
- Full test suite and CI, background-job monitoring, and S3 lifecycle rules














