Compliance, written as software
A multi-standard ISO compliance platform that takes an organisation from gap assessment to certification readiness — with AI throughout, and a dedicated auditor toolkit that's actually nice to use.
What this is
§01Narrate is Tom's commercial ISO compliance SaaS. It is the largest project on this portfolio by a wide margin — 36 numbered modules, 50+ migration files, four distinct user-type experiences, and 19 supported standards with full cross-mapping between them.
Take an organisation from gap assessment to certification readiness, in one place, with AI on every surface that benefits from it — and an auditor experience that doesn't make external auditors hate you by week two.
- Audience
- Mid-market and enterprise companies pursuing ISO certification (27001, 42001, 9001, SOC 2 etc.), consultancies managing multiple client engagements, and the external auditors who eventually audit both.
- Business model
- Three tiers — Starter £399/mo, Growth £999/mo (or £9,990/yr), Scale on enquiry. Annual billing on Growth saves ~£1,998/yr. Multi-currency Stripe checkout (GBP base; USD, EUR, CAD, AUD, JPY, CHF, SGD, INR).
- Stack
- Next.js 14 (App Router) + TypeScript + Tailwind + Supabase (Postgres / Auth / Storage) + OpenAI (GPT-4o, GPT-4o-mini, Whisper) + Anthropic Claude + Azure OpenAI + Stripe + Resend + Vercel.
- Position
- Most compliance tools are either generic GRC platforms (broad, shallow) or single-standard tools (deep, narrow). Narrate is built around multi-standard cross-mapping — implementing one standard automatically credits you for overlapping controls in every other active standard.
Nineteen standards, cross-mapped
§02The product covers nineteen separate compliance regimes, each with its own control catalogue, 100–200+ document templates, and assessment workflow. The interesting bit isn't the count — it's what happens between them.
| ISO 42001 | AI Management System | Full |
| ISO 27001 | Information Security Management | Full |
| ISO 9001 | Quality Management | Full |
| ISO 27701 | Privacy Information Management | Full |
| ISO 14001 | Environmental Management | Full |
| ISO 45001 | Occupational Health & Safety | Full |
| ISO 22301 | Business Continuity | Full |
| ISO 31000 | Risk Management | Full |
| ISO 22000 | Food Safety | Full |
| ISO 50001 | Energy Management | Full |
| SOC 2 | Service Organisation Control | Full |
| EU AI Act | European AI Regulation | Full |
| GDPR | EU Data Protection | Full |
| Cyber Essentials | UK Cyber Security Cert | Full |
| PCI DSS | Payment Card Industry | Full |
| HIPAA | US Healthcare Data | Full |
| DORA | Digital Operational Resilience | Full |
| TISAX | Automotive Information Security | Full |
| NIST CSF 2.0 | Cybersecurity Framework | Full |
The cross-mapping engine
Most controls don't exist in isolation. ISO 27001 A.5.1 (Information Security Policies) maps to NIST CSF GV.PO-01, SOC 2 CC1.1, TISAX 1.1.1, and several others. Implementing it once and re-typing the evidence for every standard is the kind of busywork that drives compliance teams to quit.
The cross-mapping engine handles this automatically:
- Cross-standard mapping badges — controls show 'Also in: ISO 27001 · 2' with hover-listing of mapped IDs.
- Bidirectional auto-alignment — marking a control as Implemented in one standard credits mapped controls in every other active standard, with an 'Auto-aligned via [Standard] [Control]' badge so the audit trail is clean.
- Transitive mapping — TISAX → SOC 2 through shared ISO 27001 controls, via getAllLinkedControls() which resolves the full transitive graph rather than just direct edges.
- Cross-standard summary banner — 'X of Y controls already addressed by your ISO 27001 implementation' at the top of each standard's align page.
- 'Show only uncovered controls' filter — hide the auto-aligned ones and focus on what still needs hands.
- Override / opt-out — any auto-alignment can be manually overridden if the user disagrees with the mapping.
The mapping data is static and hand-verified against authoritative sources (VDA ISA 6.0, NIST crosswalks, ISO Annex SL alignments). It lives in lib/cross-standard-mappings.ts so it can be audited and updated without a migration.
Four user types, four experiences
§03The product serves four genuinely distinct audiences with different information needs, permission boundaries, and even login portals. Each gets a tailored experience rather than a flag-gated version of the same one.
Direct SaaS customers managing their own compliance. Scoped by company_id. Get the full module set: align, toolkit, evidence, tasks, CAPA, risk register, AI governance, training, calendar, reports, settings. Role-gated within company (Owner / Admin / Member).
Multi-client practitioners with a dedicated dashboard showing a client list with pipeline stages and health scores. Switch into any client to get the full company experience for that client, scoped by client_id. White-label branding, AI usage limits bypassed.
External audit firms invited via email with a 30-day access window. Dedicated login portal (/auditor/login). Get a different set of 11 modules optimised for auditing — read-only data plus private scratchpad, RFI workflow, temporal vault, smart sampler, and the audit pack export. See §05.
External client contacts invited by consultants. Magic-link login to a scoped portal at /client-portal/[clientId] with access to training and compliance progress for their organisation. Also where they approve consultant AI access requests.
The dual-scope data model
Underneath, every user-data table supports both company_id (for direct customers) and client_id (for consultant-managed organisations). Row-Level Security policies enforce both. Every company-user feature has a consultant equivalent at /consultant/client/[id]/...; every auditor module has both /auditor/company/[id]/ and /auditor/client/[id]/ variants. It doubles the route count but the data layer stays single-sourced.
The module catalogue
§04Thirty-six numbered modules, condensed into the families they actually fall into. Each company-user module also has a consultant mirror under /consultant/client/[id]/.
- Align — control-by-control gap assessment with cross-standard badges and auto-alignment
- Toolkit — 100–200+ documents per standard with status workflow, rich editor, PDF/Word/XLSX export
- Evidence — drag-drop upload, AI analysis (GPT-4o vision + OCR), mapping matrix export
- Evidence Harvester — GitHub, Jira, Confluence, SharePoint, webhook integrations
- Knowledge Base — searchable doc library with versioning and AI control mapping
- Governance Recorder — Whisper-transcribed meetings auto-mapped to ISO 27001 Clause 9.3
- Tasks — 3-step wizard, maker/checker verification, share tokens for external assignees
- CAPA Register — full NCR lifecycle, 5 Whys / Fishbone root cause analysis
- Risk Register — 5×5 matrix, inherent + residual scoring, treatment plans
- AI Governance — system inventory with DPIA / Bias / Security assessments and EU AI Act compliance tracking
- Compliance Calendar — recurring events, document review cycles, AI system review dates
- Internal Audit — planning, scheduling, finding documentation
- SoA — ISO 27001 6.1.3 Statement of Applicability
- Readiness — pre-audit self-assessment with category scoring
- Reports — 7 report types with branded PDF generation and AI executive summaries
- Training Portal — interactive course modules per standard with assignment tracking
- Policy Acknowledgments — magic-link sign-off for external users
- Audit Logs — immutable, exportable, powers the auditor Temporal Vault
- Narrative Generator — AI-powered control narrative generation with chat refinement
- Trust Centre — public compliance posture sharing at a custom slug
- Multi-Standard Unified Framework — combined score + cross-mapping insights across all active standards
- Compliance Autopilot — drift detection cron, auto-task creation
- Bring Your Own AI — OpenAI / Azure / Anthropic / custom endpoint with encrypted credentials
- Privacy Firewall — Standard / Redacted / Disabled modes
- External API — key-based auth at /api/v1/
- Consultant Branding — white-label colours, logo, portal title
- Settings & team — role-based access control, invitation flow
The Auditor Toolkit
§05Most compliance tools treat auditors as a footnote — read-only access bolted onto the main UI, maybe a signed-URL evidence export. Narrate's auditor portal is a separate experience built for external audit firms with eleven dedicated modules.
Why this matters commercially
When a Big Four audit firm walks into a Narrate-using customer, they don't need a tour of the customer's workspace. They open the auditor portal, see the eleven modules they need, work through them, and leave with a signed audit pack. The customer's subscription value goes up because their auditor wants them on Narrate. It's the demand-side moat.
The eleven modules
- 01Control Status (Align)
Read-only view of the customer's gap-assessment progress with per-control inline notes.
- 02Documents (Toolkit)
Read-only access to all policies, procedures, records, and forms.
- 03Evidence
Browse evidence files with 24-hour signed download URLs scoped to the auditor's session.
- 04Audit Trail
Immutable audit log access for the entire organisation — read-only but fully filterable.
- 05RFI Requests
Create Requests for Information linked to specific controls, set priority and due dates, review responses. Email notifications to company on creation; back the other way on publish.
- 06Private Scratchpad & Findings
Private notes the auditor can take while reviewing — strict RLS means only the creating auditor sees them. 'Publish Finding' converts a note into a Major NCR / Minor NCR / Observation / OFI in the customer's CAPA register with source='external_audit'.
- 07Temporal Vault
Point-in-time document viewing — reconstruct what any document looked like on any past date using the audit_logs old_values / new_values JSONB. Quick presets for 1 / 3 / 6 months ago. Yellow 'historical snapshot' banner so the auditor knows what they're reading.
- 08Smart Sampler
Random sampling from evidence, documents, tasks, audit logs, NCRs, risks. Uses PostgreSQL's ORDER BY RANDOM() LIMIT N for genuine random selection with session history tracking — auditors can show their sampling methodology to a peer reviewer.
- 09Traceability Visualizer
Three-column Risk → Control → Evidence chain view. Pick a control, see linked risks, linked policies, linked evidence, linked knowledge documents. Cross-references the entire data layer.
- 10Readiness Heatmap
CSS grid coloured by evidence freshness — green (<3mo), yellow (3–6mo), red (none or >6mo). Per-clause / per-section. Click a cell for a detail popover.
- 11Audit Pack Export
ZIP with all evidence files + XLSX mapping matrix + index.html table of contents + per-control _summary.txt. Optional filters for findings, RFIs, control filter, heatmap summary. Export logged to auditor_activity_logs with file count and checksum.
Every auditor module exists in both /auditor/company/[id]/ and /auditor/client/[id]/ flavours — so auditors of consultant-managed clients get the same experience. Shared helpers (verifyAccess(), logActivity()) reduce the boilerplate of the duplication.
AI as a surface, not a chatbot
§06The instinct with AI in B2B SaaS is to bolt a chatbot in the corner and call it a feature. Narrate has AI in twelve distinct surfaces, each doing something specific.
- Evidence Analysis
- GPT-4o vision + OCR over uploaded evidence files. Returns findings, recommendations, confidence score, recency check, control-fit assessment. Per-operation usage-metered.
- AI Compliance Copilot
- Per-control sparkle button. Returns urgency level, 3–5 specific action steps (each typed: evidence / document / process / task), suggested evidence document types, optional policy hint. Rendered as a collapsible in-card panel, not a modal — keeps the workflow in place.
- AI Audit Coach (deterministic)
- Dashboard widget surfacing top 3 red-status controls ordered by priority and risk score. No AI call — just reads already-loaded audit data. The 'AI Suggestions' button deep-links to the actual Copilot for that control.
- Gap Analysis
- Full org-wide gap analysis. NLP summary of strengths, weaknesses, and priority recommendations.
- Document AI
- Toolkit document rewriting and improvement suggestions, with a suggestion-application workflow.
- Narrator (assistant)
- Conversational AI for ad-hoc compliance queries grounded in company data. Respects the privacy firewall.
- Knowledge Analysis
- AI analysis of uploaded knowledge documents with automatic control mapping suggestions.
- Cross-Standard Mapping AI
- Map controls between standards (e.g. ISO 42001 → ISO 27001), identify overlapping requirements. Used to seed the static mappings file and for one-off explorations.
- AI Risk Assessment
- Structured DPIA / Bias & Fairness / Security questionnaires for AI systems. Scoring is calibrated; recommendations can be promoted directly to the Risk Register.
- Narrative Generator
- Generate control narratives from evidence, tasks, timeline. Chat interface for iterative refinement.
- Compliance Autopilot
- Cron job that detects compliance drift and auto-creates tasks. Stale evidence on green controls, unevidenced gaps on red controls, dedup against existing open tasks, summary email to admin. Configurable per company via feature_flags.
- Report Generation
- GPT-4o-mini executive narrative summaries baked into the 7 branded PDF report types.
Bring Your Own AI
§07Growth and Scale customers can configure their own AI provider instead of using Narrate's default OpenAI. Enterprises that already have approved AI vendors don't need to add a new one to their procurement list.
Supported providers
- OpenAI (direct API)
- Azure OpenAI (for orgs whose data residency rules require Azure-hosted models)
- Anthropic Claude
- Any OpenAI-compatible endpoint — covers local LLMs, regional providers, and emerging models
The factory pattern
Every AI call site in the application routes through a single factory function, getAIClient() in lib/ai/get-client.ts. Twelve call sites total. The resolution order:
- Privacy firewall check — if disabled_high_risk mode, throw
- Consultant approval check — for consultant-managed clients, AI is off by default until the client approves via magic link
- Tier check — Starter doesn't get BYOAI
- Custom provider config — if set, instantiate that provider
- Fall through to Narrate's default OpenAI key — the catch-all
Credentials are encrypted at rest using AES-256-GCM. Test connection in the settings UI before saving; revert button to roll back. Only admin-role users can configure provider settings.
Consultant approval workflow
A subtle bit: for consultant-managed clients, AI features are off by default. The consultant must explicitly request AI access via the client's settings page; the client receives a magic-link email and approves or rejects via /client-portal/ai-approval. An amber banner shows on the client overview page until approved. Reports generate without their AI narrative section when AI is disabled — the rest of the report still works.
The privacy firewall
§08AI features can leak data. Compliance customers care about this more than anyone. The privacy firewall is a three-mode gate that sits between every AI call site and the actual upstream call.
All AI features work normally. Data goes to whichever provider the customer's BYOAI config (or Narrate default) points at.
A PII regex engine scrubs emails, credit cards, SSNs, IP addresses, and phone numbers from any text before it leaves the server. The AI sees patterns and structure but not identities. The redactor lives in lib/privacy/redactor.ts.
All AI features are blocked entirely. The frontend components check via the usePrivacyMode() hook and render a disabled state. The server-side applyFirewall() in lib/privacy/apply-firewall.ts enforces it again — defence in depth.
Frontend and server both enforce the firewall, so a misbehaving client cannot bypass the customer's privacy setting. Settings live at /settings/privacy.
The data model
§09PostgreSQL via Supabase with Row-Level Security on every table. 50+ migration files managing the schema's evolution. The interesting choices:
Dual-scope (company_id + client_id) on every user-data table
Each row belongs to either a direct company or a consultant-managed client. RLS enforces both. The pattern doubles every route under /consultant/client/[id]/ but the data layer stays single-sourced. Tested in the Auditor Toolkit too — every module has /auditor/company/[id]/ and /auditor/client/[id]/ variants. Shared helpers in lib/auditor/ keep the API route duplication manageable.
Generated columns for computed risk scores
PostgreSQL GENERATED ALWAYS AS ... STORED for inherent_risk_level and residual_risk_level on the risk register. The score is always consistent with the underlying likelihood × impact, can't drift if a column is updated, and is index-able. The application code never has to remember to recompute.
JSONB everywhere there's flexibility
behavioral_controls on AI systems, linked_controls on AI systems (an array of cross-standard mappings), feature_flags on companies (subscription tier overrides plus runtime settings like autopilot config), corrective_action_details on NCRs, root_cause_analysis on NCRs, treatment_actions on risks, old_values / new_values on audit_logs. GIN indexes where queried. The trade-off — schema enforcement moves to TypeScript — is worth it for these specific cases.
Control linkage by text ID, not foreign key
Controls are referenced by their text identifier ('A.5.2', '7.5.1') rather than a numeric foreign key. This is a deliberate choice — it lets us re-seed the control catalogue without rewriting every link, and matches how compliance professionals actually talk about controls. Costs us referential integrity checks; gains us flexibility and clarity.
Magic-link tokens for external participants
Policy acknowledgments, AI approval requests, team invites, auditor invitations, public task views — all use single-use secure tokens with expiry. The external participant never needs a Narrate account. Implementations live in app/acknowledge/[token]/, /client-portal/ai-approval/, /tasks/[token]/view/, /auditor/accept-invite/.
audit_logs powers the Temporal Vault
Every change captures old_values and new_values as JSONB. Beyond standard compliance evidence, this is what makes the auditor Temporal Vault possible — point-in-time reconstruction is just replaying the audit log backward to any past date. The same table that handles 'who changed what' also handles 'show me what it looked like in October'.
Paywall security — migration 029
Same lesson as Dad & Baby: profiles.is_pro and equivalent paywall fields are now writable only by service-role webhook handlers. Pre-029, an authenticated user could PATCH their own subscription tier to Scale. Lock it down at the database, not the application. (Webhook flow: Stripe event → /api/stripe/webhook → service-role write → next request reads fresh state.)
Compliance Autopilot
§10One feature worth pulling out for its own treatment: an opt-in cron job that watches for compliance drift and creates tasks before a human notices.
What it does
On a schedule, for every company with autopilot_enabled: true:
- Load all audit_data sections across active standards
- Group evidence_files by control_id with their latest
created_at - Stale evidence: green controls whose latest evidence is older than the configured threshold (default 90 days) → create a task
- Unevidenced gaps: red controls with zero evidence → create a task
- Dedup — skip controls that already have an open task
- Insert
task_assignmentsrows with[Autopilot]prefix, assigned to admin, due in 30 days - Email summary to admin if anything was created
Settings are stored on companies.feature_flags JSONB — no schema migration needed. A "Run Now" button on the settings page bypasses the schedule for ad-hoc scans. The dashboard widget surfaces unresolved autopilot tasks separately from human-created ones so the noise is contained.
Pricing & where it goes next
§11Three direct-sales tiers plus a consultant partner programme. Stripe handles checkout, billing, and the portal. Multi-currency: GBP base, with USD / EUR / CAD / AUD / JPY / CHF / SGD / INR converted at checkout based on IP detection.
- Standards
- 2
- Seats
- 4
- Storage
- 10 GB
- AI credits
- 250 credits / mo
- BYOAI
- —
- Standards
- 5
- Seats
- 10
- Storage
- 50 GB
- AI credits
- 1,000 credits / mo
- BYOAI
- Yes
- Standards
- Unlimited
- Seats
- Unlimited
- Storage
- 500 GB
- AI credits
- Unlimited
- BYOAI
- Yes + SSO / SAML
What's shipped vs what's next
- All 36 numbered modules across company / consultant / auditor / client portal
- 19 standards with comprehensive cross-mapping
- 12 AI surfaces routing through a single factory
- 11-module Auditor Toolkit
- Bring Your Own AI with 4 provider types + consultant approval workflow
- Three-mode Privacy Firewall
- Compliance Autopilot drift detection
- Magic-link auth for external participants
- Stripe multi-currency checkout + Resend transactional emails
- Branded PDF reports (7 types) with AI executive summaries
- External API at /api/v1/ with key-based auth
- SSO / SAML for Scale tier customers
- More external integrations (ServiceNow, Asana)
- Public Trust Centre customisation
- Per-standard advanced training authoring
- More AI providers + cost dashboards
- Mobile companion app for evidence capture
- Customer-customisable cross-standard mappings