Enterprise GRC Vendor Risk Management — Multi-Tenant SaaS Module
A proposed enterprise GRC Vendor Risk Management extension for an established multi-tenant GRC platform would add supplier onboarding with same-day inherent risk scoring, framework questionnaires (ISO 27001, SOC 2, NIST CSF, CIS), external security-rating adapters, AI evidence validation, and a full risk treatment lifecycle — delivered as gated milestones on the existing Python / SQLModel / React codebase, including an on-premise Docker Compose deployment profile.
Proposed outcome: An enterprise client would run vendor risk, compliance lifecycle automation, and risk treatment inside one multi-tenant GRC system — with tenant isolation, RBAC, auditable AI verdicts, OpenAPI APIs, dashboards/exports, and a clean-VM on-prem install runbook.
Scenario
This brief describes a proposed solution — not a delivered engagement. It maps a recurring enterprise GRC pattern: a productized multi-tenant platform must ship a client-grade Vendor Risk Management (VRM) module plus compliance automation and risk treatment without rewriting the core.
- Organization: Founder / product owner of a multi-tenant GRC SaaS serving enterprise and regulatory clients
- Engagement shape: ~10-week fixed-scope build in three strictly gated milestones against an existing GitHub backlog and written acceptance criteria
- Codebase: Established domain models, services, and repository patterns — extend, do not greenfield
- Stack: Python, SQLModel, PostgreSQL 16, Alembic, asyncpg, pytest; React (functional components + hooks); Docker Compose; object storage; reverse proxy; Grafana
- Integrations: External security-rating APIs (SecurityScorecard / BitSight class), email/notification hooks, LLM-based AI validation stages
- Architecture constraints: Strict tenant isolation, RBAC, ports-and-adapters for external providers; no unapproved pip/npm dependencies; change maps before structural domain changes
- Locales: Platform supports Arabic and English (RTL/i18n awareness)
Problem
Enterprise buyers expect vendor risk, evidence, and treatment to live in the GRC system of record — with audit trails and on-prem options. Spreadsheet-driven VRM and ad-hoc AI prompts do not meet that bar.
- No same-day inherent risk — new suppliers lack automated, explainable scoring and tier-gated approvals
- Questionnaire friction — ISO 27001 / SOC 2 / NIST CSF / CIS templates are not auto-dispatched with reminders and response tracking
- Blind external posture — security ratings, score drops, breaches, and CVEs are not continuous signals inside the platform
- Evidence without audit — integration, stub, and manual legs lack attempt history; AI verdicts are not persisted with confidence gates
- Incomplete risk lifecycle — draft → review → approval, configurable L×I matrices, KRIs, and treatment → residual loops are missing or fragmented
- On-prem gap — cloud multi-tenant alone fails buyers who need Docker Compose on a clean VM with an operational runbook
- Performance risk — 500+ vendors per tenant will expose N+1 queries and missing indexes without explicit validation
Requirements
Functional
- Vendor profiles — contacts, contracts, criticality, data-access attributes; centralized supplier onboarding
- Inherent risk — automated same-day assessment on vendor creation with factor-level explainability; per-tenant tiers, weights, thresholds
- Questionnaires — framework-aligned templates; dispatch, reminders, response tracking
- Ratings adapter — one external provider behind ports/adapters; continuous monitoring signals (score drops, breaches, CVEs)
- Workflows & alerts — tier-gated approvals, reassessment scheduling, four-category alerting; evidence repository with certification-expiry alerts
- Dashboards & API — operational + executive views; PDF/XLSX export; OpenAPI-documented REST
- Framework import — XLSX/CSV with row-level validation; imported frameworks behave like seeded ones
- Evidence & AI — orchestrator (integration / stub / manual); AI evidence validation and control assessment with persisted verdicts; confidence gate → human review
- Gaps & notifications — auto gap records, control-owner assignment, compliance-rate recalculation; informational vs action-required notifications with due-date cadence
- Risk & treatment — KPI/heat-map dashboard; five-stage lifecycle; configurable Likelihood × Impact matrix; KRIs; gap-to-risk AI paths; treatment → remediation → AI re-test → residual → gated gap closure; domain/control compliance scoring with history
Non-functional
- Tenant isolation & RBAC — no cross-tenant leakage; role-scoped UI and API
- Performance — validated at 500+ vendors/tenant; pagination, indexing, no N+1s
- Quality gates — build, lint, and pytest green at each milestone; new logic ships with tests
- Secrets — credentials only in backend env/settings — never in code, logs, or frontend env
- Change discipline — structural/domain changes require a written change map before code; PR-only merges
- On-prem — Docker Compose profile + runbook sufficient for clean-VM install
- Domain ownership — scoring formulas, tier weights, matrix semantics, and AI prompts are configurable; defaults remain product-owner decisions
Architecture
Three capability slices extend the existing hexagonal core: VRM (vendors, inherent risk, questionnaires, ratings), compliance lifecycle (import, evidence, AI judges, gaps), and risk treatment (lifecycle, matrix/KRIs, remediation loop) — all behind tenant-scoped services and OpenAPI.
Module architecture — React and OpenAPI sit on tenant-scoped VRM, compliance, and risk services; external ratings, email, and LLM judges plug in via ports; Compose + Grafana cover on-prem ops
Compliance AI sequence — every collection attempt is audited; LLM verdicts persist; low confidence routes to human review before gap and compliance-rate updates
Component map by capability slice (major building blocks)
End-to-end flow
Lifecycle — VRM creates scored suppliers; compliance collects and judges evidence; risk treatment drives residual and gated closure
Indicative effort share across gated milestones (illustrative)
Illustrative p95 latency targets for vendor list/filter APIs as catalog size grows
Recommended stack
Recommendation: stay inside the established Python + SQLModel + PostgreSQL 16 + Alembic + React hooks platform; add VRM/compliance/risk as domain modules; keep external ratings and LLM judges behind ports and adapters; ship an on-prem Docker Compose profile with Grafana — without introducing unapproved dependencies.
| Layer | Technology | Why |
|---|---|---|
| Backend | Python, SQLModel, asyncpg | Matches existing services/repositories; async I/O for provider and LLM calls |
| Schema | PostgreSQL 16 + Alembic | Tenant-scoped tables, indexes for 500+ vendors, migration discipline per milestone |
| API | REST + OpenAPI | Documented contracts for enterprise clients and UI |
| Frontend | React (hooks) + CSS animations | Aligns with platform UI conventions; RTL-ready patterns for AR/EN |
| AuthZ | Multi-tenant isolation + RBAC | Non-negotiable for GRC SaaS |
| Integrations | Ports/adapters (ratings, email, LLM) | Swap SecurityScorecard/BitSight or models without rewriting domain |
| AI stages | LLM validation & assessment jobs | Persisted verdicts + confidence gate; prompts owned by product |
| Storage | Object storage for evidence | Certification files and uploads with expiry metadata |
| Deploy | Docker Compose on-prem profile | Clean-VM install for enterprise buyers |
| Observability | Grafana | Existing ops stack; milestone health and queue depth |
| Quality | pytest + lint + CI green | Acceptance criterion at every gate |
Why ports/adapters for ratings and LLM? Provider APIs and model prompts will change; domain rules for inherent risk, gaps, and treatment must not. Adapters return typed DTOs; services own scoring and state machines.
Why keep scoring semantics with the product owner? GRC liability sits with the platform’s risk methodology. Engineering would make tiers, weights, matrices, and prompts configurable — defaults and final wording stay proposal-only until the owner accepts them.
Why Compose on-prem instead of a separate Kubernetes fork? A documented Compose profile matches air-gapped / single-VM buyer reality and reuses the same images the team already runs.
Illustrative tenant-scoped vendor query pattern (pagination + index-friendly filters):
# Pseudocode — extend existing repository; never cross tenant_id
async def list_vendors(
session: AsyncSession,
tenant_id: UUID,
*,
tier: str | None,
cursor: UUID | None,
limit: int = 50,
) -> list[Vendor]:
stmt = (
select(Vendor)
.where(Vendor.tenant_id == tenant_id)
.order_by(Vendor.created_at.desc(), Vendor.id.desc())
.limit(limit)
)
if tier:
stmt = stmt.where(Vendor.risk_tier == tier)
if cursor:
stmt = stmt.where(Vendor.id < cursor)
return (await session.execute(stmt)).scalars().all()
Component design
1 — Vendor profile & inherent risk engine
- Input: Onboarding payload (contacts, contracts, criticality, data-access attributes); tenant tier config
- Output: Vendor aggregate; inherent score with factor explainability; assigned risk tier
- QA gate: Same-day score on create; unit tests for weight/threshold edge cases; no cross-tenant reads
2 — Questionnaire & notification service
- Input: Framework template (ISO 27001, SOC 2, NIST CSF, CIS); vendor recipients; reminder cadence
- Output: Dispatched questionnaires; response tracking; informational vs action-required notifications
- QA gate: Reminder jobs idempotent; overdue actions visible on ops dashboard
3 — Security-ratings adapter & signal pipeline
- Input: Provider credentials (env); vendor identifiers; polling schedule
- Output: Normalized scores; events for score drops, breaches, CVEs; four-category alerts
- QA gate: Adapter contract tests with sandbox fixtures; domain unaffected when provider mocked
4 — Evidence orchestrator & AI judges
- Input: Control requirements; integration/stub/manual legs; LLM prompts (owner-approved)
- Output: Auditable attempts; persisted AI verdicts; confidence-gate routing; gap candidates
- QA gate: Every attempt stored; low-confidence never auto-closes controls
5 — Framework importer
- Input: XLSX/CSV with row-level schema
- Output: Framework + controls indistinguishable from seeded frameworks in downstream flows
- QA gate: Invalid rows rejected with line errors; re-import idempotent by natural key
6 — Risk lifecycle, matrix & KRIs
- Input: Draft risks; client Likelihood × Impact matrix; KRI thresholds
- Output: Register IDs; draft → review → approval (resend/reject); heat maps; green/amber/red KRI breaches
- QA gate: State machine tests; matrix changes versioned per tenant
7 — Treatment → residual loop
| Step | Responsibility | Inputs | Outputs |
|---|---|---|---|
| AI treatment recommend | Suggest treatments from gap/risk context | Gap, controls, prior evidence | Recommendation record pending approval |
| Approval | Owner accepts/rejects | Recommendation | Approved treatment plan |
| Remediation actions | Auto-create tasks + evidence submit | Approved plan | Action checklist + artifacts |
| AI re-test | Re-validate evidence | Submitted artifacts | Verdict + confidence |
| Residual + closure | Recalculate residual; gate gap close | Verdict, matrix | Updated residual; closed or reopened gap |
8 — On-prem Compose & runbook
- Input: Images, env templates, reverse-proxy config, object-storage binding
- Output: Compose profile; clean-VM install steps; smoke checks; Grafana datasource notes
- QA gate: Fresh VM install completes against runbook without undocumented steps
Indicative build effort distribution by phase (% of total hours)
Implementation plan
Phase 1 — Domain foundation & vendor inherent risk (weeks 1–2)
Change-map Alembic migrations for vendor profiles, tenant risk-tier config, and inherent-risk factor tables. Extend repositories with tenant filters and cursor pagination. Implement create-time inherent assessment with explainability payloads. RBAC on vendor routes. pytest coverage for scoring edges and isolation.
Risk: Scoring semantics debated mid-build. Rollback: Feature-flag VRM routes; keep migrations reversible; product owner freezes defaults before Phase 2 UI.
Phase 2 — Questionnaires, ratings, dashboards, on-prem (weeks 2–4)
Framework questionnaire templates with dispatch/reminders/response tracking. One security-ratings adapter + signal pipeline and four-category alerts. Evidence repository with certification-expiry jobs. Ops/executive dashboards and PDF/XLSX export. OpenAPI docs. Performance pass at 500+ vendors. Docker Compose on-prem profile + clean-VM runbook. Milestone 1 acceptance against written criteria.
Risk: Provider sandbox delays. Rollback: Ship adapter with recorded fixtures; live credentials wired when available without blocking dashboards.
Phase 3 — Framework import & evidence orchestrator (weeks 5–6)
XLSX/CSV importer with row-level validation. Evidence orchestrator legs (integration, stub, manual) with auditable attempts stored in object storage metadata + DB. Integration tests for import parity with seeded frameworks.
Risk: Messy client spreadsheets. Rollback: Strict schema + error report download; reject file rather than partial silent import.
Phase 4 — AI validation stages & gap automation (weeks 6–7)
AI evidence validation and control assessment stages with persisted verdicts. Configurable confidence gate to human review. Automatic gap creation, owner assignment, compliance-rate recalculation. Two-class notification model with due-date cadence. Milestone 2 acceptance.
Risk: Prompt drift vs owner intent. Rollback: Prompts versioned; low confidence defaults to human queue; AI auto-path disabled until prompt review signed.
Phase 5 — Risk lifecycle, matrix & KRIs (weeks 8–9)
Risk dashboard (KPIs, inherent/residual heat map, department drill-downs). Five-stage lifecycle with register IDs and resend/reject. Client-configurable L×I matrix. KRIs with breach tracking. Gap-to-risk AI search/create/update with owner approval.
Risk: Matrix changes invalidate historical scores. Rollback: Version matrices; freeze historical inherent/residual; recompute only on explicit tenant action.
Phase 6 — Treatment loop, scoring history & hard gate (weeks 9–10)
AI treatment recommendation → approval → remediation actions → evidence submit → AI re-test → residual recalculation → gated gap closure. Extend compliance scoring to domain/control with score history. Full regression, lint, pytest green. Milestone 3 acceptance and hypercare notes.
Risk: Closure gates too loose. Rollback: Require human sign-off when residual above threshold; keep gaps open on failed re-test.
Reporting & ops
| Signal | Source | Cadence |
|---|---|---|
| Vendors by tier / overdue reassessments | VRM services | Daily ops dashboard |
| Questionnaire response SLA | Notification + questionnaire jobs | Daily; alert on action-required backlog |
| Ratings signal drops / CVE events | Adapter pipeline | Near real-time alerts |
| AI confidence distribution & review queue | AI stage logs | Daily; page if queue > SLA |
| Gap open/closed & compliance rate | Compliance services | Daily executive view |
| KRI breaches & residual heat map | Risk services | Daily / on breach |
| API p95 list/filter latency | App metrics → Grafana | Continuous; budget for 500+ vendors |
| Compose service health (on-prem) | Docker + Grafana | Continuous |
Ops cadence would include a weekly product review of scoring/prompt change maps, a daily AI human-review scrub during early rollout, and on-prem smoke checks after each Compose upgrade. Pages fire for provider outages, AI queue breach, and API latency SLO misses — not for every informational notification.
Proposed deliverables
Following the phased plan, a build would ship these artifacts:
- VRM module — vendor profiles, inherent risk with explainability, tenant tier config
- Questionnaire engine for ISO 27001 / SOC 2 / NIST CSF / CIS with dispatch and reminders
- Security-ratings provider adapter + continuous monitoring signal pipeline
- Evidence repository, four-category alerts, certification-expiry jobs
- Operational and executive dashboards with PDF/XLSX export
- OpenAPI-documented REST API for VRM/compliance/risk surfaces
- Framework XLSX/CSV importer with row-level validation
- Evidence orchestrator + AI validation/assessment stages with confidence gate
- Gap automation, compliance-rate engine, two-class notifications
- Risk lifecycle, configurable matrix, KRIs, treatment → residual loop
- Docker Compose on-prem profile and clean-VM runbook
- pytest suites green per milestone; change maps and PR branches for review
Effort estimate
Indicative effort for a senior full-stack engineer extending an established codebase (assumes backlog clarity, 2-business-day review turnaround, and sandbox credentials on schedule):
| Scope | Hours (range) |
|---|---|
| Phase 1 — Foundation & inherent risk | 60–80 hrs |
| Phase 2 — Questionnaires, ratings, on-prem (M1) | 80–100 hrs |
| Phase 3 — Import & evidence orchestrator | 40–55 hrs |
| Phase 4 — AI stages & gaps (M2) | 45–60 hrs |
| Phase 5 — Risk lifecycle & KRIs | 50–65 hrs |
| Phase 6 — Treatment loop & hard gate (M3) | 45–60 hrs |
| Total (10-week gated plan) | 320–420 hrs |
| Ongoing maintenance (prompts, adapters, on-prem) | 12–20 hrs/month |
At ~32–40 hrs/week, delivery fits a 10-week calendar if milestone acceptance stays on the published review SLA. Payment-style gates (e.g. 40% / 25% / 35%) should map to Milestone 1–3 acceptance, not calendar weeks alone.
Glossary
| Term | Meaning |
|---|---|
| GRC | Governance, Risk & Compliance — platform category for policies, controls, and risk registers |
| VRM | Vendor Risk Management — lifecycle for third-party / supplier risk |
| Inherent risk | Risk level before treatments and compensating controls |
| Residual risk | Risk remaining after approved treatments and re-testing |
| KRI | Key Risk Indicator — metric with green/amber/red thresholds and breach tracking |
| Ports & adapters | Hexagonal pattern isolating domain from external provider SDKs |
| Confidence gate | Rule routing low-confidence AI verdicts to human review |
| Change map | Short written plan of files and before/after behavior required before structural changes |
| SQLModel | Python library combining SQLAlchemy and Pydantic-style models |
| On-prem Compose | Docker Compose deployment profile for customer-controlled VMs |