A Cloud Security Posture Management (CSPM) SaaS platform that continuously audits AWS, Azure, and GCP infrastructure against industry security frameworks, scores risk, and generates exportable client audit reports.
- Scans cloud accounts for security misconfigurations across IAM, storage, networking, compute, and audit logging
- Maps every finding to CIS AWS Foundations Benchmark, HIPAA Security Rule, GDPR, and SOC 2 controls
- Scores risk per account (0–100) and per framework using severity-weighted penalties
- Exports branded PDF audit reports ready to deliver to clients
| Layer | Technology |
|---|---|
| Monorepo | Turborepo + pnpm workspaces |
| API | Node.js + Express + TypeScript |
| Web | Next.js 14 (App Router) + Tailwind CSS v3 + shadcn/ui |
| Database | PostgreSQL 15 via Prisma ORM |
| Queue | Redis 7 + BullMQ (background scan workers) |
| Cloud SDKs | AWS SDK v3, @azure/identity, googleapis |
| Auth | JWT (httpOnly cookies, access 15m + refresh 30d with rotation) |
| Encryption | AES-256-GCM for stored cloud credentials |
.
├── apps/
│ ├── api/ # Express API
│ │ ├── prisma/ # Schema + migrations
│ │ └── src/
│ │ ├── cloud/ # aws/ azure/ gcp/ scanners
│ │ ├── frameworks/ # CIS / HIPAA / GDPR / SOC2 rule registries
│ │ ├── workers/ # BullMQ scan worker
│ │ ├── services/ # Business logic
│ │ ├── controllers/
│ │ ├── routes/
│ │ ├── middleware/
│ │ └── utils/
│ └── web/ # Next.js frontend
│ ├── app/ # App Router pages
│ ├── components/ # UI + layout components
│ └── lib/ # API clients + PDF export
├── packages/
│ └── shared/ # Shared TypeScript types
├── infra/ # Docker, nginx, compose files
├── tests/ # Unit, integration, e2e stubs
└── docs/ # TCD, architecture, API spec
- Node.js 20+
- pnpm 9+
- Docker + Docker Compose (for Postgres and Redis)
1. Clone and install
git clone <repo-url>
cd CSPM-SaaS
pnpm install2. Configure environment
cp .env.example .envEdit .env and fill in the required secrets:
# Generate a JWT secret (64 hex chars)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Generate an encryption key (64 hex chars = 32 bytes for AES-256)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"3. Start Postgres and Redis
make dev # starts docker services + hot-reload dev servers
# or step by step:
docker compose -f infra/docker-compose.yml up -d postgres redis4. Run database migrations
make migrate # prisma migrate dev
make generate # prisma generate (regenerate client after schema changes)
make seed # optional: seed development data5. Start the dev servers
pnpm dev # starts api (port 4000) and web (port 3000) concurrentlyOpen http://localhost:3000.
make up # builds images and starts all 4 services
make down # stop and remove containers
make logs # tail all container logs| Target | Description |
|---|---|
make install |
Install all workspace dependencies |
make dev |
Start Docker services + hot-reload dev servers |
make build |
Production TypeScript build (all packages) |
make test |
Run test suites |
make migrate |
Run Prisma migrations against local DB |
make generate |
Regenerate Prisma client |
make seed |
Seed development data |
make up |
Full Docker Compose stack |
make down |
Stop Docker Compose stack |
make logs |
Tail Docker logs |
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/auth/register |
Create user + organisation |
| POST | /api/v1/auth/login |
Login, return httpOnly tokens |
| POST | /api/v1/auth/refresh |
Rotate refresh token |
| POST | /api/v1/auth/logout |
Revoke refresh token |
| GET | /api/v1/auth/me |
Current user profile |
| GET | /api/v1/accounts |
List cloud accounts |
| POST | /api/v1/accounts |
Connect new cloud account |
| DELETE | /api/v1/accounts/:id |
Remove cloud account |
| POST | /api/v1/scans |
Trigger a scan |
| GET | /api/v1/scans |
List scans (optional ?accountId=) |
| GET | /api/v1/scans/:id |
Scan detail with findings |
| POST | /api/v1/compliance/generate |
Generate compliance report |
| GET | /api/v1/compliance/summary |
Live framework scores for account |
| GET | /api/v1/compliance/reports |
Historical compliance reports |
| GET | /api/v1/dashboard/summary |
Overview stats and top accounts |
| GET | /api/v1/reports/audit |
Full audit data for PDF export |
| GET | /api/v1/alerts |
List alerts (?accountId=&acknowledged=false&page=1) |
| PATCH | /api/v1/alerts/:id/acknowledge |
Acknowledge an alert |
| Scanner | Controls checked |
|---|---|
| IAM | Root MFA, root access keys, password policy complexity/length, per-user MFA, access key rotation >90 days, direct AdministratorAccess attachment |
| S3 | Public ACL, server-side encryption, versioning, access logging |
| EC2 | Unrestricted SSH/RDP, all-traffic security groups, EBS encryption, IMDSv2, default VPC |
| CloudTrail | Trail existence, logging active, log file validation, management events |
| Scanner | Controls checked |
|---|---|
| RBAC | Subscription owner count >3, classic admins, wildcard custom roles, Contributor count >10, external/guest groups with privileged roles |
| Storage | Public blob access, HTTPS-only, TLS version <1.2, soft-delete, network ACL default-allow (CIS 3.7), infrastructure encryption disabled (CIS 3.2), shared key access enabled |
| Network | NSG unrestricted SSH/RDP, all-ports-open rules |
| Scanner | Controls checked |
|---|---|
| IAM | Public members (allUsers/allAuthenticatedUsers), service accounts with owner role, default SA with sensitive roles, primitive Editor role (CIS 1.2), SA key rotation >90 days (CIS 1.5) |
| Storage | Public bucket IAM, uniform bucket-level access, versioning |
| Compute | Firewall open SSH/RDP, all-ports firewall rules, OS Login, serial port, default SA with cloud-platform scope (CIS 4.1), Shielded VM not fully enabled (CIS 4.8) |
| Framework | Controls | Standard |
|---|---|---|
| CIS AWS | 21 | CIS AWS Foundations Benchmark v1.5 |
| HIPAA | 17 | §164.312 Technical + §164.308 Administrative Safeguards |
| GDPR | 15 | Articles 5, 25, 30, 32 |
| SOC 2 | 18 | CC6.x Logical Access, CC7.x Monitoring, A1.x Availability |
Risk score formula: score = max(0, 100 − Σ weights) where CRITICAL=10, HIGH=5, MEDIUM=2, LOW=1.
Create an IAM role in the target account that trusts your deployment account and attach the SecurityAudit managed policy. The platform uses STS AssumeRole with an external ID to obtain temporary credentials.
Role ARN: arn:aws:iam::<account-id>:role/CSPMAuditRole
External ID: (set in the Connect Account dialog)
Create an Azure AD service principal with Reader role on the target subscription:
az ad sp create-for-rbac --name cspm-audit --role Reader \
--scopes /subscriptions/<subscription-id>Use the output appId (clientId), password (clientSecret), and tenant (tenantId).
Create a service account with the Security Reviewer role and download a JSON key:
gcloud iam service-accounts create cspm-audit
gcloud projects add-iam-policy-binding <project-id> \
--member="serviceAccount:cspm-audit@<project-id>.iam.gserviceaccount.com" \
--role="roles/iam.securityReviewer"
gcloud iam service-accounts keys create key.json \
--iam-account=cspm-audit@<project-id>.iam.gserviceaccount.comPaste the contents of key.json into the Connect Account dialog.
| Tag | Description |
|---|---|
v0.1.0 |
Multi-cloud scanner engine — AWS/Azure/GCP + BullMQ worker |
v0.2.0 |
Compliance engine — CIS/HIPAA/GDPR/SOC2 rule registries |
v0.3.0 |
Reporting — dashboard overview and PDF audit export |
v0.4.0 |
Alerts — CRITICAL/HIGH alert feed with deduplication and acknowledgement |
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
REDIS_URL |
Yes | Redis connection string |
JWT_SECRET |
Yes | Access token signing secret (min 32 chars) |
JWT_REFRESH_SECRET |
Yes | Refresh token signing secret (min 32 chars) |
JWT_ACCESS_EXPIRES_IN |
No | Access token TTL (default: 15m) |
JWT_REFRESH_EXPIRES_IN |
No | Refresh token TTL (default: 30d) |
ENCRYPTION_KEY |
Yes | 32-byte hex key for AES-256-GCM credential encryption |
PORT |
No | API port (default: 4000) |
NEXT_PUBLIC_API_URL |
Yes | API base URL seen by the browser |
CORS_ORIGIN |
No | Allowed CORS origin (default: http://localhost:3000) |
NODE_ENV |
No | development or production |