DEV Community

Alex Kane
Alex Kane

Posted on

n8n for InsurTech SaaS Vendors: 5 Automations for NAIC, NYDFS §500, SOX, and GDPR Compliance

If you're building software for insurers, MGAs, or brokers, you already know the compliance matrix is unlike anything else in software.

NAIC Data Security Model Law #668 in 40+ states. State DOI licensing across every jurisdiction you touch. NYDFS §500 if any customer is a New York licensee. GDPR Art.28 if you process EU-domiciled policy data. OFAC sanctions screening on every bind. SOX ICFR if you're publicly traded. HIPAA if you touch health lines.

And here's the compliance problem nobody talks about: when your SaaS platform routes policyholder PII, claims data, or premium calculations through a cloud iPaaS like Zapier or Make, that data egresses your authorized environment.

For InsurTech SaaS vendors, that's not just a security issue — it's a regulatory one. NAIC Model Law #668 §4 requires your Information Security Program to control third-party service providers. Zapier is a third-party service provider. If it's processing policyholder NPI, it's in scope.

Self-hosted n8n keeps every automation inside your authorized environment. Here are five workflows your InsurTech platform needs.


Workflow 1: New Insurer Customer Onboarding Drip

Insurance buyers are not generic SaaS buyers. A Tier 1 national insurer has different compliance obligations than a regional carrier or an MGA. Your onboarding sequence should reflect that.

This workflow triggers on a POST /insurtech-customer-onboarding webhook when a new customer is provisioned. It detects the customer tier (TIER_1_INSURER / REGIONAL_CARRIER / MGA_MANAGING_GENERAL_AGENT / INDEPENDENT_BROKER / REINSURER) and compliance flags (NAIC_DATA_SECURITY_MODEL_LAW_AUDIT, NYDFS_500_APPLICABLE, GDPR_EU_POLICIES, SOX_ICFR_APPLICABLE, HIPAA_HEALTH_INSURER, OFAC_SANCTIONS_SCREENING). It sends a personalized Day 0 welcome with tier-specific NAIC / state DOI integration guidance, a Day 3 compliance-specific setup guide, and a Day 7 power-features email.

Why this matters: A Tier 1 insurer receiving a generic SaaS onboarding email immediately signals that your platform doesn't understand insurance compliance. A NYDFS-licensed carrier needs to know about your §500.17 incident reporting workflow on Day 0, not week 3.

{
  "name": "InsurTech Customer Onboarding Drip",
  "nodes": [
    {
      "id": "1",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {
        "path": "insurtech-customer-onboarding",
        "httpMethod": "POST"
      },
      "position": [
        240,
        300
      ]
    },
    {
      "id": "2",
      "name": "Log New Customer",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "append",
        "sheetId": "{{$env.CUSTOMERS_SHEET_ID}}",
        "range": "Sheet1!A:M",
        "values": {
          "values": [
            [
              "={{$json.customer_id}}",
              "={{$json.company_name}}",
              "={{$json.tier}}",
              "={{$json.primary_contact_email}}",
              "={{$json.compliance_flags}}",
              "={{$json.domicile_state}}",
              "={{$json.lines_of_business}}",
              "={{$json.eu_policies}}",
              "=NOW()",
              "onboarding",
              "",
              "",
              ""
            ]
          ]
        }
      },
      "position": [
        460,
        300
      ]
    },
    {
      "id": "3",
      "name": "Set Tier Flags",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const tier = $json.tier;\nconst flags = ($json.compliance_flags || '').split(',').map(f => f.trim());\nconst eu = $json.eu_policies === true || $json.eu_policies === 'true';\nconst nydfs = $json.domicile_state === 'NY' || flags.includes('NYDFS_500_APPLICABLE');\n\nconst tiers = {\n  TIER_1_INSURER: { label: 'Tier 1 National Insurer', d3Subject: 'Your Enterprise Onboarding \u2014 NAIC Data Security Model Law Integration Guide', d3Body: 'As a Tier 1 insurer, your NAIC #668 compliance obligations extend to all third-party service providers. This guide walks through how to configure our platform within your NAIC Data Security Program.' },\n  REGIONAL_CARRIER: { label: 'Regional Carrier', d3Subject: 'State DOI Integration Checklist for Regional Carriers', d3Body: 'Your state DOI license requires maintaining data residency controls. This checklist covers how our self-hosted deployment option satisfies state DOI data sovereignty requirements.' },\n  MGA_MANAGING_GENERAL_AGENT: { label: 'Managing General Agent', d3Subject: 'MGA Binding Authority & Data Flow Configuration Guide', d3Body: 'As an MGA, your binding authority agreements likely include data handling obligations to carrier partners. Here is how to configure data segmentation for each carrier relationship.' },\n  INDEPENDENT_BROKER: { label: 'Independent Broker', d3Subject: 'Broker Compliance Quick-Start \u2014 E&O and Client Data Protection', d3Body: 'Your E&O policy and state licensing require secure handling of client PII. Here is your 3-step setup to ensure client data never leaves your authorized environment.' },\n  REINSURER: { label: 'Reinsurer', d3Subject: 'Reinsurance Data Exchange & Regulatory Reporting Setup', d3Body: 'Reinsurance treaty data carries strict confidentiality obligations. This guide covers our encrypted data exchange configuration and regulatory reporting audit trail.' }\n};\n\nconst tierConfig = tiers[tier] || tiers['REGIONAL_CARRIER'];\n\nreturn [{\n  ...($json),\n  tier_label: tierConfig.label,\n  d0_subject: `Welcome to FlowKit \u2014 Your ${tierConfig.label} Setup Guide`,\n  d0_body: `Welcome aboard. Your account is provisioned for ${tierConfig.label} workflows.\\n\\nCompliance flags detected: ${flags.join(', ') || 'standard'}${eu ? '\\n\\nGDPR: EU-domiciled policy data detected \u2014 your DPA (Art. 28) addendum is attached.' : ''}${nydfs ? '\\n\\nNYDFS \u00a7500: Your NY license requires annual certification by Feb 15. We have pre-built the NYDFS \u00a7500.17 incident report workflow.' : ''}`,\n  d3_subject: tierConfig.d3Subject,\n  d3_body: tierConfig.d3Body,\n  d7_subject: `${tierConfig.label} \u2014 Week 1 Power Features`,\n  d7_body: `You have been live for one week. Here are the three features InsurTech teams in your tier activate first:\\n\\n1. NAIC Compliance Deadline Tracker \u2014 pre-loaded with your state DOI filing calendar\\n2. Policy API Health Monitor \u2014 catches outages before your DOI SLA timer starts\\n3. Incident Response Pipeline \u2014 NYDFS \u00a7500.17 and state breach notification clock automation`,\n  nydfs_flag: nydfs,\n  eu_flag: eu,\n  flags_list: flags\n}];\n"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "id": "4",
      "name": "Send Day 0 Welcome",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.primary_contact_email}}",
        "subject": "={{$json.d0_subject}}",
        "message": "={{$json.d0_body}}",
        "fromEmail": "support@flowkithq.com"
      },
      "position": [
        900,
        200
      ]
    },
    {
      "id": "5",
      "name": "Notify CS Slack",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#insurtech-cs",
        "text": "New InsurTech customer: {{$json.company_name}} ({{$json.tier_label}}) \u2014 {{$json.primary_contact_email}}. Flags: {{$json.compliance_flags}}"
      },
      "position": [
        900,
        400
      ]
    },
    {
      "id": "6",
      "name": "Wait 3 Days",
      "type": "n8n-nodes-base.wait",
      "parameters": {
        "amount": 3,
        "unit": "days"
      },
      "position": [
        1120,
        200
      ]
    },
    {
      "id": "7",
      "name": "Send Day 3 Compliance Guide",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.primary_contact_email}}",
        "subject": "={{$json.d3_subject}}",
        "message": "={{$json.d3_body}}",
        "fromEmail": "support@flowkithq.com"
      },
      "position": [
        1340,
        200
      ]
    },
    {
      "id": "8",
      "name": "Wait 4 More Days",
      "type": "n8n-nodes-base.wait",
      "parameters": {
        "amount": 4,
        "unit": "days"
      },
      "position": [
        1560,
        200
      ]
    },
    {
      "id": "9",
      "name": "Send Day 7 Power Features",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.primary_contact_email}}",
        "subject": "={{$json.d7_subject}}",
        "message": "={{$json.d7_body}}",
        "fromEmail": "support@flowkithq.com"
      },
      "position": [
        1780,
        200
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Log New Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log New Customer": {
      "main": [
        [
          {
            "node": "Set Tier Flags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Tier Flags": {
      "main": [
        [
          {
            "node": "Send Day 0 Welcome",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify CS Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Day 0 Welcome": {
      "main": [
        [
          {
            "node": "Wait 3 Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 3 Days": {
      "main": [
        [
          {
            "node": "Send Day 3 Compliance Guide",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Day 3 Compliance Guide": {
      "main": [
        [
          {
            "node": "Wait 4 More Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 4 More Days": {
      "main": [
        [
          {
            "node": "Send Day 7 Power Features",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 2: Policy Administration API Health Monitor

Insurance is SLA-dense. State DOI fair claims settlement statutes (California §790.03, Texas §542) set strict timelines from acknowledgment to payment. NAIC Market Conduct best practices flag latency as a claims handling deficiency. OFAC screening must happen before every bind — not after.

This workflow pings five critical endpoints every 5 minutes: policy_bind_api (NAIC Model Law #676 unfair trade practices risk), claims_adjudication_api (state DOI 15-day clock), premium_calculation_engine (rate filing deviation risk), ofac_screening_api (31 CFR §501 sanctions risk), and gdpr_consent_api (GDPR Art.6 lawful basis for EU policies). It uses $getWorkflowStaticData to debounce alerts to 30-minute windows — no alert storms during rolling restarts.

Why this matters: An OFAC screening API that's down for 20 minutes during a high-volume bind session means policies issued without required sanctions screening. That's a potential OFAC violation, not just an ops incident.

{
  "name": "Policy Administration API Health Monitor",
  "nodes": [
    {
      "id": "1",
      "name": "Every 5 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 5
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "id": "2",
      "name": "Load API Endpoints",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "return [\n  { name: 'policy_bind_api', url: process.env.POLICY_BIND_API_URL, tier: 'TIER_1_INSURER', regulation: 'NAIC Model Law #676 (unfair trade practices) \u2014 bind latency = carrier complaint risk', sla_minutes: 2 },\n  { name: 'claims_adjudication_api', url: process.env.CLAIMS_API_URL, tier: 'TIER_1_INSURER', regulation: 'State DOI fair claims settlement (CA \u00a7790.03, TX \u00a7542) \u2014 15-day acknowledgment clock', sla_minutes: 5 },\n  { name: 'premium_calculation_engine', url: process.env.PREMIUM_CALC_URL, tier: 'REGIONAL_CARRIER', regulation: 'State DOI rate filing approval \u2014 outage = unlicensed rate deviation risk', sla_minutes: 3 },\n  { name: 'ofac_screening_api', url: process.env.OFAC_API_URL, tier: 'ALL', regulation: 'OFAC SDN screening \u2014 binding without screening = potential sanctions violation (31 CFR \u00a7501)', sla_minutes: 1 },\n  { name: 'gdpr_consent_api', url: process.env.GDPR_CONSENT_URL, tier: 'EU_POLICIES', regulation: 'GDPR Art.6 lawful basis \u2014 processing EU-domiciled policies without consent API = Art.83 fine risk', sla_minutes: 2 }\n];\n"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "id": "3",
      "name": "Ping Each Endpoint",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "method": "GET",
        "url": "={{$json.url}}",
        "timeout": 10000,
        "continueOnFail": true
      },
      "position": [
        680,
        300
      ]
    },
    {
      "id": "4",
      "name": "Evaluate Status",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const ep = $input.item.json;\nconst status = $input.item.json.$response?.statusCode;\nconst ok = status >= 200 && status < 300;\nconst key = `last_alert_${ep.name}`;\nconst store = $getWorkflowStaticData('global');\nconst lastAlert = store[key] || 0;\nconst nowMs = Date.now();\nconst thirtyMin = 30 * 60 * 1000;\nconst shouldAlert = !ok && (nowMs - lastAlert > thirtyMin);\nif (shouldAlert) store[key] = nowMs;\nreturn [{ ...ep, ok, status, shouldAlert }];\n"
      },
      "position": [
        900,
        300
      ]
    },
    {
      "id": "5",
      "name": "Only Alertable",
      "type": "n8n-nodes-base.filter",
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{$json.shouldAlert}}",
              "value2": true
            }
          ]
        }
      },
      "position": [
        1120,
        300
      ]
    },
    {
      "id": "6",
      "name": "Alert Slack",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#insurtech-api-alerts",
        "text": "\u26a0\ufe0f *{{$json.name}}* DOWN (HTTP {{$json.status || 'timeout'}})\n*Tier:* {{$json.tier}}\n*Regulatory risk:* {{$json.regulation}}\nInvestigate immediately \u2014 SLA clock may be running."
      },
      "position": [
        1340,
        300
      ]
    }
  ],
  "connections": {
    "Every 5 Minutes": {
      "main": [
        [
          {
            "node": "Load API Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load API Endpoints": {
      "main": [
        [
          {
            "node": "Ping Each Endpoint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ping Each Endpoint": {
      "main": [
        [
          {
            "node": "Evaluate Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Status": {
      "main": [
        [
          {
            "node": "Only Alertable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Only Alertable": {
      "main": [
        [
          {
            "node": "Alert Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 3: InsurTech Compliance Deadline Tracker

Twelve deadline types cover the full InsurTech regulatory calendar:

Deadline Regulation Key Risk
NAIC_DATA_SECURITY_MODEL_LAW_AUDIT NAIC #668 §4.F Annual security program audit — most states require written report
NAIC_ANNUAL_STATEMENT_FILING State DOI (March 1) Late filing = DOI penalty + license at risk
NAIC_MARKET_CONDUCT_ANNUAL_REVIEW State DOI Market conduct deficiencies = exam trigger
STATE_DOI_LICENSE_RENEWAL Varies by state Lapsed license = unlicensed activity
SOX_302_QUARTERLY_CERTIFICATION SOX §302 CEO/CFO personal liability for late or false cert
SOX_404_ANNUAL_ICFR_REPORT SOX §404 Material weakness disclosure required
NYDFS_500_ANNUAL_CERTIFICATION NYDFS §500.17 Feb 15 hard deadline — no extensions
GDPR_ART28_DPA_ANNUAL_REVIEW GDPR Art.28 Expired DPA = Art.83(4) fine exposure
GDPR_DPIA_REVIEW GDPR Art.35 High-risk processing requires annual DPIA refresh
OFAC_SANCTIONS_LIST_QUARTERLY_REVIEW 31 CFR §501 SDN list updates require policy re-screening
SOC2_TYPE2_RENEWAL AICPA Enterprise buyers require current report
ANNUAL_PENETRATION_TEST NAIC #668 §4.F Documented pen test required in security program
{
  "name": "InsurTech Compliance Deadline Tracker",
  "nodes": [
    {
      "id": "1",
      "name": "Weekdays 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1-5"
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "id": "2",
      "name": "Load Deadlines",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "getAll",
        "sheetId": "{{$env.COMPLIANCE_SHEET_ID}}",
        "range": "InsurTechDeadlines!A:H"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "id": "3",
      "name": "Classify Urgency",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const rows = $input.all();\nconst now = new Date();\nconst results = [];\n\nconst DEADLINE_LABELS = {\n  NAIC_DATA_SECURITY_MODEL_LAW_AUDIT: 'NAIC Data Security Model Law #668 \u2014 Annual Security Program Audit',\n  NAIC_ANNUAL_STATEMENT_FILING: 'NAIC Annual Statement \u2014 State DOI Filing (March 1)',\n  NAIC_MARKET_CONDUCT_ANNUAL_REVIEW: 'NAIC Market Conduct Annual Statement',\n  STATE_DOI_LICENSE_RENEWAL: 'State DOI License Renewal',\n  SOX_302_QUARTERLY_CERTIFICATION: 'SOX \u00a7302 \u2014 CEO/CFO Quarterly Certification',\n  SOX_404_ANNUAL_ICFR_REPORT: 'SOX \u00a7404 \u2014 Annual ICFR Report (Auditor Attestation)',\n  NYDFS_500_ANNUAL_CERTIFICATION: 'NYDFS \u00a7500.17 \u2014 Annual Cybersecurity Certification (Feb 15)',\n  GDPR_ART28_DPA_ANNUAL_REVIEW: 'GDPR Art.28 \u2014 Data Processing Agreement Annual Review',\n  GDPR_DPIA_REVIEW: 'GDPR Art.35 \u2014 DPIA Annual Review for High-Risk Processing',\n  OFAC_SANCTIONS_LIST_QUARTERLY_REVIEW: 'OFAC SDN List \u2014 Quarterly Compliance Review',\n  SOC2_TYPE2_RENEWAL: 'SOC 2 Type II \u2014 Annual Audit Renewal',\n  ANNUAL_PENETRATION_TEST: 'Annual Penetration Test (NAIC #668 \u00a74.F requirement)'\n};\n\nfor (const row of rows) {\n  const d = row.json;\n  if (!d.deadline_type || !d.due_date || d.alert_sent_date === new Date().toISOString().slice(0,10)) continue;\n  const due = new Date(d.due_date);\n  const days = Math.round((due - now) / 86400000);\n  let urgency = null;\n  if (days < 0) urgency = 'OVERDUE';\n  else if (days <= 14) urgency = 'CRITICAL';\n  else if (days <= 30) urgency = 'URGENT';\n  else if (days <= 60) urgency = 'WARNING';\n  else if (days <= 90) urgency = 'NOTICE';\n  if (urgency) results.push({ ...d, urgency, days_until: days, label: DEADLINE_LABELS[d.deadline_type] || d.deadline_type });\n}\nreturn results;\n"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "id": "4",
      "name": "Route by Urgency",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "dataType": "string",
        "value1": "={{$json.urgency}}",
        "rules": {
          "rules": [
            {
              "value2": "OVERDUE",
              "output": 0
            },
            {
              "value2": "CRITICAL",
              "output": 1
            },
            {
              "value2": "URGENT",
              "output": 2
            },
            {
              "value2": "WARNING",
              "output": 3
            },
            {
              "value2": "NOTICE",
              "output": 4
            }
          ]
        }
      },
      "position": [
        900,
        300
      ]
    },
    {
      "id": "5",
      "name": "Slack OVERDUE",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#insurtech-compliance",
        "text": "\ud83d\udea8 *OVERDUE* \u2014 {{$json.label}}\nOwner: {{$json.owner_email}} | Due: {{$json.due_date}} ({{$json.days_until}} days ago)\nAction required immediately."
      },
      "position": [
        1120,
        100
      ]
    },
    {
      "id": "6",
      "name": "Gmail CRITICAL",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.owner_email}}",
        "cc": "={{$json.compliance_lead_email}}",
        "subject": "CRITICAL: {{$json.label}} due in {{$json.days_until}} days",
        "message": "This compliance deadline requires immediate action.\n\nDeadline: {{$json.label}}\nDue: {{$json.due_date}} ({{$json.days_until}} days)\nUrgency: CRITICAL\n\nPlease confirm completion or escalate immediately."
      },
      "position": [
        1120,
        220
      ]
    },
    {
      "id": "7",
      "name": "Gmail URGENT",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.owner_email}}",
        "subject": "URGENT: {{$json.label}} \u2014 {{$json.days_until}} days remaining",
        "message": "Deadline approaching.\n\nDeadline: {{$json.label}}\nDue: {{$json.due_date}} ({{$json.days_until}} days)\nUrgency: URGENT"
      },
      "position": [
        1120,
        340
      ]
    },
    {
      "id": "8",
      "name": "Gmail WARNING",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.owner_email}}",
        "subject": "Upcoming: {{$json.label}} \u2014 {{$json.days_until}} days",
        "message": "Heads-up on upcoming compliance deadline.\n\nDeadline: {{$json.label}}\nDue: {{$json.due_date}} ({{$json.days_until}} days)"
      },
      "position": [
        1120,
        460
      ]
    },
    {
      "id": "9",
      "name": "Slack NOTICE",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#insurtech-compliance",
        "text": "\ud83d\udccb *NOTICE* \u2014 {{$json.label}} due in {{$json.days_until}} days ({{$json.due_date}})"
      },
      "position": [
        1120,
        580
      ]
    }
  ],
  "connections": {
    "Weekdays 8 AM": {
      "main": [
        [
          {
            "node": "Load Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Deadlines": {
      "main": [
        [
          {
            "node": "Classify Urgency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Urgency": {
      "main": [
        [
          {
            "node": "Route by Urgency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Urgency": {
      "main": [
        [
          {
            "node": "Slack OVERDUE",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gmail CRITICAL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gmail URGENT",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gmail WARNING",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack NOTICE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 4: Insurance Incident & Breach Alert Pipeline

Eight incident types with regulatory-specific response timelines:

Incident Type SLA Regulation
STATE_DOI_BREACH_NOTIFICATION 72h NAIC Model Law #668 §5 — domicile state DOI + policyholder notice
NYDFS_500_MATERIAL_CYBERSECURITY_EVENT 72h NYDFS 23 NYCRR §500.17 — Superintendent notification
GDPR_BREACH_EU_POLICY_DATA 72h GDPR Art.33 — supervisory authority; Art.34 if high risk
HIPAA_PHI_BREACH 60 days 45 CFR §164.408 — HHS + media notice if >500 in state
OFAC_SANCTIONS_HIT 2h 31 CFR §501.604 — immediate voluntary disclosure; transaction hold
SOX_MATERIAL_WEAKNESS 96h SOX §302/§404 — 10-Q/10-K disclosure; possible 8-K
NAIC_MARKET_CONDUCT_AUDIT_INITIATED 48h Legal hold + records gathering
INSIDER_THREAT_CLAIMS_DATA 24h State insurance fraud bureau notification

The OFAC SLA is deliberately set at 2 hours — sanctions violations are strict liability, and delayed voluntary disclosure eliminates the primary penalty mitigation factor.

{
  "name": "Insurance Incident & Breach Alert Pipeline",
  "nodes": [
    {
      "id": "1",
      "name": "Incident Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {
        "path": "insurtech-incident",
        "httpMethod": "POST"
      },
      "position": [
        240,
        300
      ]
    },
    {
      "id": "2",
      "name": "Parse & Classify",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const inc = $json;\nconst INCIDENT_TYPES = {\n  STATE_DOI_BREACH_NOTIFICATION: {\n    label: 'State DOI Data Breach \u2014 Policyholder Notification Required',\n    sla_hours: 72,\n    regulation: 'NAIC Data Security Model Law #668 \u00a75 \u2014 72h notice to domicile state DOI; policyholder notice without unreasonable delay',\n    escalate_to: ['ciso@yourcompany.com','legal@yourcompany.com','compliance@yourcompany.com'],\n    slack_channel: '#security-incident'\n  },\n  NYDFS_500_MATERIAL_CYBERSECURITY_EVENT: {\n    label: 'NYDFS \u00a7500 Material Cybersecurity Event',\n    sla_hours: 72,\n    regulation: 'NYDFS 23 NYCRR \u00a7500.17 \u2014 72h notification to NYDFS Superintendent; annual cert may be affected',\n    escalate_to: ['ciso@yourcompany.com','legal@yourcompany.com'],\n    slack_channel: '#security-incident'\n  },\n  GDPR_BREACH_EU_POLICY_DATA: {\n    label: 'GDPR Breach \u2014 EU-Domiciled Policy Data',\n    sla_hours: 72,\n    regulation: 'GDPR Art.33 \u2014 72h notification to lead supervisory authority; Art.34 if high risk to policyholders',\n    escalate_to: ['dpo@yourcompany.com','legal@yourcompany.com'],\n    slack_channel: '#security-incident'\n  },\n  HIPAA_PHI_BREACH: {\n    label: 'HIPAA PHI Breach \u2014 Health Line of Business',\n    sla_hours: 1440,\n    regulation: 'HIPAA Breach Rule 45 CFR \u00a7164.408 \u2014 60-day HHS notification; media notice if >500 in state',\n    escalate_to: ['privacy@yourcompany.com','legal@yourcompany.com'],\n    slack_channel: '#security-incident'\n  },\n  OFAC_SANCTIONS_HIT: {\n    label: 'OFAC Sanctions Match \u2014 Potential Prohibited Transaction',\n    sla_hours: 2,\n    regulation: 'OFAC 31 CFR \u00a7501.604 \u2014 immediate voluntary disclosure; do not complete transaction; hold funds',\n    escalate_to: ['legal@yourcompany.com','compliance@yourcompany.com'],\n    slack_channel: '#compliance-urgent'\n  },\n  SOX_MATERIAL_WEAKNESS: {\n    label: 'SOX Material Weakness Identified \u2014 ICFR',\n    sla_hours: 96,\n    regulation: 'SOX \u00a7302/\u00a7404 \u2014 material weakness must be disclosed in next 10-Q/10-K; SEC 8-K if rapid disclosure required',\n    escalate_to: ['cfo@yourcompany.com','audit_committee@yourcompany.com'],\n    slack_channel: '#finance-critical'\n  },\n  NAIC_MARKET_CONDUCT_AUDIT_INITIATED: {\n    label: 'NAIC Market Conduct Audit Initiated',\n    sla_hours: 48,\n    regulation: 'State DOI market conduct exam \u2014 gather all requested records within notice period; legal hold',\n    escalate_to: ['legal@yourcompany.com','compliance@yourcompany.com'],\n    slack_channel: '#compliance-urgent'\n  },\n  INSIDER_THREAT_CLAIMS_DATA: {\n    label: 'Insider Threat \u2014 Claims or Policyholder Data',\n    sla_hours: 24,\n    regulation: 'State insurance fraud bureau notification required; NAIC #668 \u00a75 breach assessment needed',\n    escalate_to: ['ciso@yourcompany.com','hr@yourcompany.com','legal@yourcompany.com'],\n    slack_channel: '#security-incident'\n  }\n};\n\nconst config = INCIDENT_TYPES[inc.incident_type] || {\n  label: inc.incident_type,\n  sla_hours: 72,\n  regulation: 'Review applicable regulations',\n  escalate_to: ['compliance@yourcompany.com'],\n  slack_channel: '#compliance-urgent'\n};\n\nconst deadline = new Date(Date.now() + config.sla_hours * 3600000).toISOString();\n\nreturn [{ ...inc, ...config, deadline_iso: deadline }];\n"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "id": "3",
      "name": "Log to Incident DB",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "insert",
        "table": "insurtech_incidents",
        "columns": "incident_id,incident_type,label,regulation,sla_hours,deadline_iso,reporter,description,ts_reported",
        "values": "={{$json.incident_id}},={{$json.incident_type}},={{$json.label}},={{$json.regulation}},={{$json.sla_hours}},={{$json.deadline_iso}},={{$json.reporter}},={{$json.description}},NOW()"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "id": "4",
      "name": "Slack Immediate Alert",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "={{$json.slack_channel}}",
        "text": "\ud83d\udea8 *{{$json.label}}*\n*Incident ID:* {{$json.incident_id}}\n*SLA:* {{$json.sla_hours}}h (deadline: {{$json.deadline_iso}})\n*Regulation:* {{$json.regulation}}\n*Reporter:* {{$json.reporter}}\n*Description:* {{$json.description}}\n\nEscalating to: {{$json.escalate_to}}"
      },
      "position": [
        900,
        200
      ]
    },
    {
      "id": "5",
      "name": "Email Escalation List",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "={{$json.escalate_to.join(',')}}",
        "subject": "[INCIDENT] {{$json.label}} \u2014 SLA: {{$json.sla_hours}}h",
        "message": "Incident declared: {{$json.label}}\n\nIncident ID: {{$json.incident_id}}\nRegulatory requirement: {{$json.regulation}}\nSLA deadline: {{$json.deadline_iso}}\nReported by: {{$json.reporter}}\n\nDescription:\n{{$json.description}}\n\nImmediate action required. Reply-all to coordinate response.",
        "fromEmail": "incidents@flowkithq.com"
      },
      "position": [
        900,
        400
      ]
    }
  ],
  "connections": {
    "Incident Webhook": {
      "main": [
        [
          {
            "node": "Parse & Classify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Classify": {
      "main": [
        [
          {
            "node": "Log to Incident DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Incident DB": {
      "main": [
        [
          {
            "node": "Slack Immediate Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Email Escalation List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 5: Weekly InsurTech Platform KPI Dashboard

Monday 8 AM. Two Postgres queries — platform metrics (total customers by tier, ARR, new ARR, EU policy customers) and compliance events (DOI incidents, NYDFS §500 events, GDPR breaches, OFAC hits, overdue compliance items). Merged into an HTML table. CEO email, CISO and compliance team BCC.

The CISO BCC is intentional: insurance regulators increasingly review whether your CISO has visibility into platform KPIs alongside security metrics. The NAIC #668 security program requires senior management reporting. This workflow closes that governance gap automatically.

{
  "name": "Weekly InsurTech Platform KPI Dashboard",
  "nodes": [
    {
      "id": "1",
      "name": "Monday 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "id": "2",
      "name": "Query Platform Metrics",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(*) AS total_customers, COUNT(CASE WHEN tier='TIER_1_INSURER' THEN 1 END) AS tier1_count, COUNT(CASE WHEN tier='REGIONAL_CARRIER' THEN 1 END) AS carrier_count, COUNT(CASE WHEN tier='MGA_MANAGING_GENERAL_AGENT' THEN 1 END) AS mga_count, SUM(arr_usd) AS total_arr, SUM(CASE WHEN created_at >= NOW()-INTERVAL'7 days' THEN arr_usd ELSE 0 END) AS new_arr_7d, COUNT(CASE WHEN eu_policies=true THEN 1 END) AS eu_policy_customers FROM insurtech_customers WHERE status='active'"
      },
      "position": [
        460,
        200
      ]
    },
    {
      "id": "3",
      "name": "Query Compliance Events",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(CASE WHEN incident_type LIKE 'STATE_DOI%' THEN 1 END) AS doi_incidents, COUNT(CASE WHEN incident_type='NYDFS_500_MATERIAL_CYBERSECURITY_EVENT' THEN 1 END) AS nydfs_incidents, COUNT(CASE WHEN incident_type LIKE 'GDPR%' THEN 1 END) AS gdpr_incidents, COUNT(CASE WHEN incident_type='OFAC_SANCTIONS_HIT' THEN 1 END) AS ofac_hits, COUNT(CASE WHEN deadline_iso < NOW() AND resolved_at IS NULL THEN 1 END) AS overdue_incidents FROM insurtech_incidents WHERE ts_reported >= NOW()-INTERVAL'7 days'"
      },
      "position": [
        460,
        400
      ]
    },
    {
      "id": "4",
      "name": "Build KPI Report",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const m = $input.all()[0].json;\nconst c = $input.all()[1].json;\n\nconst html = `\n<h2>InsurTech Platform \u2014 Weekly KPI Report</h2>\n<p>Week ending ${new Date().toISOString().slice(0,10)}</p>\n<table border='1' cellpadding='6'>\n<tr><th>Metric</th><th>Value</th><th>Alert</th></tr>\n<tr><td>Total Active Customers</td><td>${m.total_customers}</td><td></td></tr>\n<tr><td>Tier 1 Insurers</td><td>${m.tier1_count}</td><td></td></tr>\n<tr><td>Regional Carriers</td><td>${m.carrier_count}</td><td></td></tr>\n<tr><td>MGAs</td><td>${m.mga_count}</td><td></td></tr>\n<tr><td>Total ARR (USD)</td><td>$${Number(m.total_arr).toLocaleString()}</td><td></td></tr>\n<tr><td>New ARR This Week</td><td>$${Number(m.new_arr_7d).toLocaleString()}</td><td></td></tr>\n<tr><td>EU Policy Customers (GDPR)</td><td>${m.eu_policy_customers}</td><td></td></tr>\n<tr><td>DOI Incidents (7d)</td><td>${c.doi_incidents}</td><td>${c.doi_incidents > 0 ? '\u26a0\ufe0f REVIEW' : '\u2705'}</td></tr>\n<tr><td>NYDFS \u00a7500 Events (7d)</td><td>${c.nydfs_incidents}</td><td>${c.nydfs_incidents > 0 ? '\ud83d\udea8 ACTION' : '\u2705'}</td></tr>\n<tr><td>GDPR Breaches (7d)</td><td>${c.gdpr_incidents}</td><td>${c.gdpr_incidents > 0 ? '\ud83d\udea8 ACTION' : '\u2705'}</td></tr>\n<tr><td>OFAC Sanctions Hits (7d)</td><td>${c.ofac_hits}</td><td>${c.ofac_hits > 0 ? '\ud83d\udea8 LEGAL HOLD' : '\u2705'}</td></tr>\n<tr><td>Overdue Compliance Items</td><td>${c.overdue_incidents}</td><td>${c.overdue_incidents > 0 ? '\u26a0\ufe0f ESCALATE' : '\u2705'}</td></tr>\n</table>`;\n\nreturn [{ html, m, c }];\n"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "id": "5",
      "name": "Email CEO + BCC CISO",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "to": "ceo@yourcompany.com",
        "bcc": "ciso@yourcompany.com,compliance@yourcompany.com",
        "subject": "Weekly InsurTech Platform KPI \u2014 {{new Date().toISOString().slice(0,10)}}",
        "message": "={{$json.html}}",
        "fromEmail": "reports@flowkithq.com"
      },
      "position": [
        900,
        300
      ]
    }
  ],
  "connections": {
    "Monday 8 AM": {
      "main": [
        [
          {
            "node": "Query Platform Metrics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Query Compliance Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Platform Metrics": {
      "main": [
        [
          {
            "node": "Build KPI Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Compliance Events": {
      "main": [
        [
          {
            "node": "Build KPI Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build KPI Report": {
      "main": [
        [
          {
            "node": "Email CEO + BCC CISO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Why InsurTech SaaS vendors self-host n8n

NAIC Data Security Model Law #668 — Third-party service provider scope. §4.D requires your Information Security Program to address the security practices of third-party service providers with access to NPI. Zapier, Make, and cloud iPaaS platforms are third-party service providers. If they process policyholder NPI, they are in scope for your NAIC §4.D oversight obligations — and you need a vendor risk assessment, contractual security requirements, and ongoing monitoring for each one.

SOX ITGC control gap. For publicly traded InsurTech SaaS companies, routing policy data through Zapier creates an IT General Control gap. ITGC access controls, change management, and availability controls must cover all systems processing SOX-significant data. A cloud iPaaS where your team can add automations without IT review is an ITGC deficiency — and your external auditor will flag it.

GDPR Art.28 — Data Processing Agreement chain. If your InsurTech platform processes EU-domiciled policy data and you use Zapier to route that data, Zapier becomes a sub-processor under GDPR Art.28. You need a DPA with Zapier, you need to list it in your own DPA with the customer, and any sub-processor breach must be reported up the chain. Self-hosted n8n eliminates the sub-processor from the chain entirely.

NYDFS §500.12 — Network segmentation. New York-licensed insurers using your platform are subject to NYDFS §500.12 network segmentation requirements. If your automation platform introduces an external data path, it may violate their segmentation architecture. Self-hosted n8n runs inside the customer's authorized environment.

Audit trail integrity. n8n workflow JSON is human-readable and git-committable. Every automation change is a versioned commit. For SOX ITGC, NAIC market conduct exams, and DOI licensing reviews, 'here is the git history of every automation change with author, timestamp, and diff' is a far stronger control narrative than 'we have logs in a third-party cloud tool.'


InsurTech SaaS buyer Q&A

Q: Our NAIC #668 security program requires annual penetration testing of all systems in scope. Does self-hosted n8n expand our pen test scope?
A: Yes, but you control the scope boundary. Self-hosted n8n runs inside your environment, so it's in scope for your annual pen test — but you define the network boundary. With cloud iPaaS, the vendor's infrastructure is also in scope, which you cannot pen test directly.

Q: We have NYDFS §500 obligations. Does n8n satisfy the MFA requirement for privileged access?
A: NYDFS §500.12 requires MFA for all remote access to nonpublic information. Self-hosted n8n behind your VPN + MFA stack satisfies this. You configure access controls; we don't hold the keys.

Q: Our state DOI requires a data residency attestation for policyholder data. Can we include n8n in that attestation?
A: Yes. Self-hosted n8n runs in your infrastructure. Your data residency attestation covers your environment. There is no data egress to a third-party cloud.

Q: We process EU-domiciled policies and need a GDPR Art.28 DPA for every sub-processor. Is n8n a sub-processor?
A: Self-hosted n8n is software, not a service. When you run it in your infrastructure, there is no data processing relationship with us. No DPA needed for the automation layer.

Q: Our SOX auditors flagged our Zapier usage as an ITGC gap. How do we demonstrate n8n solves this?
A: Show your auditors: (1) n8n is deployed inside your SOX environment, subject to your existing ITGC access and change management controls; (2) all workflow changes are git-committed with author, timestamp, and peer review; (3) no external cloud service has access to SOX-significant data. That's a complete ITGC narrative.


Ready-to-import workflows

All five workflows are available in the FlowKit n8n automation library at https://stripeai.gumroad.com.

Drop your questions in the comments — especially if you're working through NAIC #668 security program requirements or NYDFS §500 annual certification.

Top comments (0)