Your defense SaaS platform just processed a contractor's Technical Data Package. That TDP contains CUI — Controlled Unclassified Information. The DFARS 252.204-7012(m)(1) 72-hour clock just started. Your incident response automation should already be running.
But does it know the difference between a CUI breach (72h to DC3) and an ITAR unlicensed disclosure (voluntary disclosure to DDTC, no fixed deadline but criminal risk at $1M + 20 years)? Does it know that NDAA §889 requires you to notify the Contracting Officer within 24 hours of discovering a prohibited component?
This guide shows five production-ready n8n workflows for SpaceTech and Defense SaaS vendors, including full JSON you can import today.
Who This Is For
These automations are built for SaaS companies selling into defense and space:
- Launch vehicle operations platforms (tracking ITAR USML Cat IV/XV)
- Defense supply chain software (DFARS 252.204-7012 CUI handlers)
- Dual-use AI/ML platforms bridging commercial and DoD
- UAS/autonomous systems vendors (ITAR USML Cat VIII)
- Space data analytics companies (EAR CCL ECCN classifications)
- Any SaaS with CMMC Level 2 requirements in their contract
| Customer Tier | Typical Profile | Key Compliance Obligations |
|---|---|---|
| PRIME_DEFENSE_CONTRACTOR_SAAS | Top-5 defense prime selling SaaS to DoD | CMMC L2+, DFARS 7012, ITAR, EAR, FedRAMP Mod |
| SPACE_LAUNCH_SAAS_VENDOR | Launch vehicle ops, sat-ops software | ITAR USML Cat IV/XV, FAA Part 460, FCC Part 25 |
| DIB_MIDMARKET_SAAS | Mid-size Tier-2/3 defense supply chain | CMMC L2, DFARS 7012, NIST 800-171, NDAA §889 |
| DUAL_USE_TECH_SAAS | Commercial-to-defense bridge (AI, ML, sensors) | EAR CCL ECCN 3E002+, CMMC L1, NDAA §889 |
| AUTONOMOUS_SYSTEMS_SAAS | Drone/UAS/autonomous ground vehicle software | ITAR USML Cat VIII/XI, FAA Part 107, NDAA §889 |
| DEFENSE_INTELLIGENCE_SAAS | IC-adjacent analytics/data platforms | ITAR, EAR, FISMA High, ICD 503, CJIS |
| SPACETECH_STARTUP_SAAS | Startups entering defense/space market | ITAR registration (22 CFR §122.1), EAR classification, CMMC roadmap |
Why Self-Hosted n8n for Defense and Space
Using Zapier or Make.com to route defense-related data creates a deemed export problem. When your workflow automation platform is a US-based cloud SaaS, every non-US employee of that vendor who can theoretically access your automation logs may constitute an unlicensed export of ITAR-controlled technical data.
Self-hosted n8n eliminates this entirely:
| Risk Factor | Zapier/Make | Self-Hosted n8n |
|---|---|---|
| CUI data in cloud SaaS logs | Yes — DFARS 7012 finding | No — stays in your enclave |
| ITAR deemed export via cloud vendor | Possible | Not applicable |
| CMMC L2 vendor risk finding | CC9.2 | Closed — no external SaaS |
| Audit trail for DC3 report | Not guaranteed | Git-versioned JSON |
| FedRAMP boundary expansion | CC9.2 scope issue | In-boundary by design |
Workflow 1: ITAR/EAR Export Authorization Monitor
Monitors all active ITAR/EAR licenses and agreements. Alerts export control officers before any expiry creates an unlicensed export.
Tracks: DSP-5, DSP-73, TAA (Technical Assistance Agreement), MLA (Manufacturing License Agreement), CCL export licenses
Triggers at: EXPIRED → CRITICAL (≤14d) → URGENT (≤45d) → WARNING (≤90d) → NOTICE (≤120d)
{
"name": "ITAR/EAR Export Authorization Monitor",
"nodes": [
{
"id": "a1b2c3d4-0001-0001-0001-000000000001",
"name": "Daily 7AM Check",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * 1-5"
}
]
}
}
},
{
"id": "a1b2c3d4-0001-0001-0001-000000000002",
"name": "Read Authorizations",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
300
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT id, auth_type, auth_number, country, technology_category, expiry_date, responsible_ecc_officer, customer_tier, CURRENT_DATE::text AS today, (expiry_date - CURRENT_DATE) AS days_remaining FROM export_authorizations WHERE expiry_date IS NOT NULL AND (expiry_date - CURRENT_DATE) <= 120 AND status = 'ACTIVE' ORDER BY expiry_date ASC"
}
},
{
"id": "a1b2c3d4-0001-0001-0001-000000000003",
"name": "Classify Urgency",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"jsCode": "const items = $input.all();\nconst results = [];\nfor (const item of items) {\n const d = item.json;\n const days = parseInt(d.days_remaining);\n let urgency, slackChannel, escalate;\n if (days < 0) {\n urgency = 'EXPIRED';\n slackChannel = '#export-control-urgent';\n escalate = true;\n } else if (days <= 14) {\n urgency = 'CRITICAL';\n slackChannel = '#export-control-urgent';\n escalate = true;\n } else if (days <= 45) {\n urgency = 'URGENT';\n slackChannel = '#export-control';\n escalate = false;\n } else if (days <= 90) {\n urgency = 'WARNING';\n slackChannel = '#export-control';\n escalate = false;\n } else {\n urgency = 'NOTICE';\n slackChannel = '#export-control';\n escalate = false;\n }\n const authTypeLabel = {\n 'DSP5': 'DSP-5 Export License',\n 'DSP73': 'DSP-73 Temporary Export',\n 'TAA': 'Technical Assistance Agreement',\n 'MLA': 'Manufacturing License Agreement',\n 'AES_EEI': 'EAR Electronic Export Info',\n 'CCL_LICENSE': 'CCL Export License'\n }[d.auth_type] || d.auth_type;\n results.push({ json: { ...d, urgency, slackChannel, escalate, authTypeLabel, daysRemaining: days } });\n}\nreturn results.filter(r => r.json.urgency !== 'NOTICE' || true);"
}
},
{
"id": "a1b2c3d4-0001-0001-0001-000000000004",
"name": "Slack Export Control",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
900,
220
],
"parameters": {
"authentication": "oAuth2",
"resource": "message",
"operation": "post",
"channel": "={{ $json.slackChannel }}",
"text": "={{ $json.urgency }} \u2014 Export Authorization {{ $json.auth_number }} ({{ $json.authTypeLabel }}) for {{ $json.country }} expires {{ $json.expiry_date }} ({{ $json.daysRemaining }} days). ECC Officer: {{ $json.responsible_ecc_officer }}. Auth type: {{ $json.auth_type }}. Tier: {{ $json.customer_tier }}."
}
},
{
"id": "a1b2c3d4-0001-0001-0001-000000000005",
"name": "Log to Postgres",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
900,
380
],
"parameters": {
"operation": "insert",
"schema": "public",
"table": "export_auth_alerts",
"columns": "auth_id,urgency,days_remaining,alert_sent_at",
"values": "={{ $json.id }},={{ $json.urgency }},={{ $json.daysRemaining }},={{ new Date().toISOString() }}"
}
}
],
"connections": {
"Daily 7AM Check": {
"main": [
[
{
"node": "Read Authorizations",
"type": "main",
"index": 0
}
]
]
},
"Read Authorizations": {
"main": [
[
{
"node": "Classify Urgency",
"type": "main",
"index": 0
}
]
]
},
"Classify Urgency": {
"main": [
[
{
"node": "Slack Export Control",
"type": "main",
"index": 0
},
{
"node": "Log to Postgres",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 2: DFARS 252.204-7012 CUI 72-Hour Incident Pipeline
When a CUI incident hits your platform, this workflow fires immediately — classifies the incident type, calculates the regulatory deadline, alerts your CISO, and opens a logged record for the DC3 report.
Incident types handled:
-
CUI_UNAUTHORIZED_ACCESS/CUI_DATA_EXFILTRATION→ 72h to DC3 (DFARS 252.204-7012(m)(1)) -
ITAR_UNLICENSED_DISCLOSURE→ DDTC voluntary disclosure (22 CFR §127.12) -
NDAA_889_PROHIBITED_ITEM→ 24h to Contracting Officer -
CLASSIFIED_SPILL→ Immediate FSO notification (DoD 5200.01 Vol 3)
{
"name": "DFARS 252.204-7012 CUI 72-Hour Incident Pipeline",
"nodes": [
{
"id": "b2c3d4e5-0002-0002-0002-000000000001",
"name": "CUI Incident Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"parameters": {
"httpMethod": "POST",
"path": "cui-incident",
"responseMode": "responseNode"
}
},
{
"id": "b2c3d4e5-0002-0002-0002-000000000002",
"name": "Classify Incident",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
300
],
"parameters": {
"jsCode": "const d = $input.first().json.body || $input.first().json;\nconst incidentTypes = {\n 'CUI_UNAUTHORIZED_ACCESS': { deadline: 72, regulation: 'DFARS 252.204-7012(m)(1)', reportTo: 'DC3' },\n 'CUI_DATA_EXFILTRATION': { deadline: 72, regulation: 'DFARS 252.204-7012(m)(1)', reportTo: 'DC3' },\n 'SYSTEM_COMPROMISE_WITH_CUI': { deadline: 72, regulation: 'DFARS 252.204-7012(m)(1)', reportTo: 'DC3' },\n 'ITAR_UNLICENSED_DISCLOSURE': { deadline: 0, regulation: '22 CFR \u00a7127.12 voluntary disclosure', reportTo: 'DDTC' },\n 'EAR_UNAUTHORIZED_EXPORT': { deadline: 0, regulation: '15 CFR \u00a7764.5', reportTo: 'BIS' },\n 'CMMC_CONTROL_FAILURE': { deadline: 72, regulation: 'DFARS 252.204-7021(c)(4)', reportTo: 'DIBNet' },\n 'NDAA_889_PROHIBITED_ITEM': { deadline: 24, regulation: 'NDAA \u00a7889(b)(1)', reportTo: 'Contracting Officer' },\n 'CLASSIFIED_SPILL': { deadline: 0, regulation: 'DoD 5200.01 Vol 3', reportTo: 'FSO' }\n};\nconst incType = d.incident_type || 'CUI_UNAUTHORIZED_ACCESS';\nconst cfg = incidentTypes[incType] || incidentTypes['CUI_UNAUTHORIZED_ACCESS'];\nconst now = new Date();\nconst deadlineTs = cfg.deadline > 0 ? new Date(now.getTime() + cfg.deadline * 3600 * 1000).toISOString() : 'IMMEDIATE';\nreturn [{ json: { ...d, incidentType: incType, deadlineHours: cfg.deadline, deadlineTimestamp: deadlineTs, regulation: cfg.regulation, reportTo: cfg.reportTo, detectedAt: now.toISOString(), incidentId: `CUI-${Date.now()}` } }];"
}
},
{
"id": "b2c3d4e5-0002-0002-0002-000000000003",
"name": "Alert CISO",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
680,
220
],
"parameters": {
"authentication": "oAuth2",
"resource": "message",
"operation": "post",
"channel": "#ciso-security-incidents",
"text": "DFARS CUI INCIDENT \u2014 ID: {{ $json.incidentId }}\\nType: {{ $json.incidentType }}\\nRegulation: {{ $json.regulation }}\\nReport to: {{ $json.reportTo }}\\nDeadline: {{ $json.deadlineHours }}h \u2192 {{ $json.deadlineTimestamp }}\\nSystem: {{ $json.affected_system }}\\nCustomer: {{ $json.customer_id }}\\nDetected: {{ $json.detectedAt }}"
}
},
{
"id": "b2c3d4e5-0002-0002-0002-000000000004",
"name": "Log Incident",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
680,
380
],
"parameters": {
"operation": "insert",
"schema": "public",
"table": "cui_incidents",
"columns": "incident_id,incident_type,regulation,report_to,deadline_hours,deadline_ts,affected_system,customer_id,detected_at,status",
"values": "={{ $json.incidentId }},={{ $json.incidentType }},={{ $json.regulation }},={{ $json.reportTo }},={{ $json.deadlineHours }},={{ $json.deadlineTimestamp }},={{ $json.affected_system }},={{ $json.customer_id }},={{ $json.detectedAt }},'OPEN'"
}
},
{
"id": "b2c3d4e5-0002-0002-0002-000000000005",
"name": "Respond 200",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
460,
460
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ received: true, incidentId: $json.incidentId, deadlineTs: $json.deadlineTimestamp }) }}"
}
}
],
"connections": {
"CUI Incident Webhook": {
"main": [
[
{
"node": "Classify Incident",
"type": "main",
"index": 0
},
{
"node": "Respond 200",
"type": "main",
"index": 0
}
]
]
},
"Classify Incident": {
"main": [
[
{
"node": "Alert CISO",
"type": "main",
"index": 0
},
{
"node": "Log Incident",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 3: CMMC 2.0 / NIST 800-171 Compliance Deadline Tracker
Runs every weekday morning and surfaces upcoming compliance deadlines before they become violations. DFARS 252.204-7021 requires flow-down to all subcontractors handling CUI — this workflow tracks your own obligations and those you manage on behalf of customers.
Deadline types tracked: CMMC C3PAO assessment, NIST 800-171 self-assessment + SPRS score update, ITAR registration renewal (22 CFR §122.1), EAR CCL license renewal, DFARS 7012 annual system review, NDAA §889 annual attestation, AECA compliance audit, SBIR/STTR milestones, SOC 2, FedRAMP ConMon, annual pentest, IR drill (NIST 800-171 3.6.3)
{
"name": "CMMC 2.0 / NIST 800-171 Compliance Deadline Tracker",
"nodes": [
{
"id": "c3d4e5f6-0003-0003-0003-000000000001",
"name": "Weekdays 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
}
},
{
"id": "c3d4e5f6-0003-0003-0003-000000000002",
"name": "Read Compliance Items",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
300
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT id, deadline_type, description, due_date, assigned_to, customer_tier, compliance_framework, (due_date - CURRENT_DATE) AS days_remaining FROM compliance_deadlines WHERE due_date IS NOT NULL AND (due_date - CURRENT_DATE) <= 90 AND status NOT IN ('COMPLETE','WAIVED') ORDER BY due_date ASC"
}
},
{
"id": "c3d4e5f6-0003-0003-0003-000000000003",
"name": "Classify Priority",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"jsCode": "const items = $input.all();\nconst seen = new Set();\nconst results = [];\nfor (const item of items) {\n const d = item.json;\n const days = parseInt(d.days_remaining);\n const key = `${d.id}-${new Date().toISOString().slice(0,10)}`;\n if (seen.has(key)) continue;\n seen.add(key);\n let priority, emoji, channel;\n const deadlineLabels = {\n 'CMMC_C3PAO_ASSESSMENT': 'CMMC L2 C3PAO Assessment (DFARS 252.204-7021)',\n 'NIST_800_171_SELF_ASSESSMENT': 'NIST 800-171 Self-Assessment + SPRS Update',\n 'ITAR_REGISTRATION_RENEWAL': 'ITAR Registration Renewal (22 CFR \u00a7122.1)',\n 'EAR_CCL_LICENSE_RENEWAL': 'EAR CCL Export License Renewal (15 CFR \u00a7750)',\n 'DFARS_7012_ANNUAL_REVIEW': 'DFARS 252.204-7012 Annual System Review',\n 'NDAA_889_ATTESTATION': 'NDAA \u00a7889 Annual Attestation to CO',\n 'AECA_COMPLIANCE_AUDIT': 'AECA Arms Export Compliance Audit',\n 'SBIR_PHASE_MILESTONE': 'SBIR/STTR Phase Milestone Report',\n 'SOC2_TYPE2_RENEWAL': 'SOC 2 Type II Renewal',\n 'FEDRAMP_CONMON_REVIEW': 'FedRAMP ConMon Monthly Review',\n 'PENTEST_ANNUAL': 'Annual Penetration Test',\n 'INCIDENT_RESPONSE_DRILL': 'IR Plan Annual Drill (NIST 800-171 3.6.3)'\n };\n if (days < 0) { priority='OVERDUE'; emoji='\ud83d\udea8'; channel='#compliance-critical'; }\n else if (days <= 7) { priority='CRITICAL'; emoji='\ud83d\udd34'; channel='#compliance-critical'; }\n else if (days <= 21) { priority='URGENT'; emoji='\ud83d\udfe0'; channel='#compliance-team'; }\n else if (days <= 45) { priority='WARNING'; emoji='\ud83d\udfe1'; channel='#compliance-team'; }\n else { priority='NOTICE'; emoji='\ud83d\udd35'; channel='#compliance-team'; }\n results.push({ json: { ...d, priority, emoji, channel, deadlineLabel: deadlineLabels[d.deadline_type] || d.deadline_type, daysRemaining: days } });\n}\nreturn results;"
}
},
{
"id": "c3d4e5f6-0003-0003-0003-000000000004",
"name": "Slack Compliance Team",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
900,
220
],
"parameters": {
"authentication": "oAuth2",
"resource": "message",
"operation": "post",
"channel": "={{ $json.channel }}",
"text": "={{ $json.emoji }} {{ $json.priority }} \u2014 {{ $json.deadlineLabel }}\\nDue: {{ $json.due_date }} ({{ $json.daysRemaining }} days)\\nAssigned: {{ $json.assigned_to }}\\nFramework: {{ $json.compliance_framework }}\\nCustomer tier: {{ $json.customer_tier }}"
}
},
{
"id": "c3d4e5f6-0003-0003-0003-000000000005",
"name": "Email Owner",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
900,
400
],
"parameters": {
"operation": "send",
"toList": "={{ $json.assigned_to }}",
"subject": "={{ $json.priority }}: {{ $json.deadlineLabel }} due {{ $json.due_date }} ({{ $json.daysRemaining }}d)",
"message": "<p>{{ $json.emoji }} <strong>{{ $json.priority }}</strong>: {{ $json.deadlineLabel }}</p><p>Due: {{ $json.due_date }} ({{ $json.daysRemaining }} days remaining)<br/>Framework: {{ $json.compliance_framework }}<br/>Customer tier: {{ $json.customer_tier }}</p><p>Action required: ensure evidence artifacts are collected and controls documented before the deadline.</p>"
}
}
],
"connections": {
"Weekdays 8AM": {
"main": [
[
{
"node": "Read Compliance Items",
"type": "main",
"index": 0
}
]
]
},
"Read Compliance Items": {
"main": [
[
{
"node": "Classify Priority",
"type": "main",
"index": 0
}
]
]
},
"Classify Priority": {
"main": [
[
{
"node": "Slack Compliance Team",
"type": "main",
"index": 0
},
{
"node": "Email Owner",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 4: NDAA §889 Banned Component & Supplier Screen
NDAA §889(b)(1) prohibits US government contractors from using or procuring equipment, systems, or services from Huawei, ZTE, Hytera Communications, Hangzhou Hikvision, and Dahua Technology — or their subsidiaries and affiliates. This webhook fires whenever a new supplier or hardware component is onboarded.
Screen logic: checks supplier name, domain, and component manufacturer against the §889(f)(3) prohibited entity list. PROHIBITED result requires 24-hour Contracting Officer notification under DFARS 252.204-7021(c)(5).
{
"name": "NDAA \u00a7889 Banned Component & Supplier Screen",
"nodes": [
{
"id": "d4e5f6a7-0004-0004-0004-000000000001",
"name": "New Supplier Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"parameters": {
"httpMethod": "POST",
"path": "supplier-screen",
"responseMode": "responseNode"
}
},
{
"id": "d4e5f6a7-0004-0004-0004-000000000002",
"name": "Screen Against \u00a7889 List",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
300
],
"parameters": {
"jsCode": "const d = $input.first().json.body || $input.first().json;\n// NDAA \u00a7889(f)(3) prohibited entities (Huawei, ZTE, Hytera, Hikvision, Dahua, affiliates)\nconst prohibitedEntities = [\n 'huawei','zte corporation','hytera communications','hangzhou hikvision','dahua technology',\n 'hikvision','dahua','hytera','seafar','panda international'\n];\nconst prohibitedDomains = ['huawei.com','zte.com.cn','hikvision.com','dahuasecurity.com'];\nconst supplierName = (d.supplier_name || '').toLowerCase();\nconst supplierDomain = (d.supplier_domain || '').toLowerCase();\nconst componentMfr = (d.component_manufacturer || '').toLowerCase();\nconst nameMatch = prohibitedEntities.find(e => supplierName.includes(e) || componentMfr.includes(e));\nconst domainMatch = prohibitedDomains.find(dom => supplierDomain.includes(dom));\nconst flagged = !!(nameMatch || domainMatch);\nconst screenId = `NDAA889-${Date.now()}`;\nreturn [{ json: {\n ...d,\n screenId,\n flagged,\n matchedEntity: nameMatch || domainMatch || null,\n screenedAt: new Date().toISOString(),\n regulation: 'NDAA \u00a7889(b)(1)(A)/(B) \u2014 2019 NDAA',\n riskLevel: flagged ? 'PROHIBITED' : 'CLEARED',\n contractorNotificationRequired: flagged\n} }];"
}
},
{
"id": "d4e5f6a7-0004-0004-0004-000000000003",
"name": "Flagged?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.1,
"position": [
680,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"id": "cond1",
"leftValue": "={{ $json.flagged }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
},
{
"id": "d4e5f6a7-0004-0004-0004-000000000004",
"name": "Alert Procurement",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.3,
"position": [
900,
200
],
"parameters": {
"authentication": "oAuth2",
"resource": "message",
"operation": "post",
"channel": "#procurement-compliance",
"text": "NDAA \u00a7889 PROHIBITED ENTITY DETECTED\\nScreen ID: {{ $json.screenId }}\\nSupplier: {{ $json.supplier_name }}\\nMatched: {{ $json.matchedEntity }}\\nRegulation: {{ $json.regulation }}\\nAction: DO NOT ONBOARD \u2014 notify Contracting Officer within 24h per DFARS 252.204-7021(c)(5)"
}
},
{
"id": "d4e5f6a7-0004-0004-0004-000000000005",
"name": "Log Screen Result",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
900,
400
],
"parameters": {
"operation": "insert",
"schema": "public",
"table": "supplier_screens",
"columns": "screen_id,supplier_name,flagged,matched_entity,risk_level,regulation,screened_at",
"values": "={{ $json.screenId }},={{ $json.supplier_name }},={{ $json.flagged }},={{ $json.matchedEntity || 'none' }},={{ $json.riskLevel }},={{ $json.regulation }},={{ $json.screenedAt }}"
}
},
{
"id": "d4e5f6a7-0004-0004-0004-000000000006",
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
460,
460
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ screenId: $json.screenId, riskLevel: $json.riskLevel, flagged: $json.flagged }) }}"
}
}
],
"connections": {
"New Supplier Webhook": {
"main": [
[
{
"node": "Screen Against \u00a7889 List",
"type": "main",
"index": 0
},
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
},
"Screen Against \u00a7889 List": {
"main": [
[
{
"node": "Flagged?",
"type": "main",
"index": 0
},
{
"node": "Log Screen Result",
"type": "main",
"index": 0
}
]
]
},
"Flagged?": {
"main": [
[
{
"node": "Alert Procurement",
"type": "main",
"index": 0
}
],
[]
]
}
}
}
Workflow 5: Weekly Defense Platform KPI Dashboard
Every Monday morning, sends a combined business + compliance health report to your CEO and CISO. Keeps leadership informed on MRR, prime contractor account penetration, and open CMMC/ITAR/NDAA items — in one email, not five spreadsheets.
{
"name": "Weekly Defense Platform KPI Dashboard",
"nodes": [
{
"id": "e5f6a7b8-0005-0005-0005-000000000001",
"name": "Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "e5f6a7b8-0005-0005-0005-000000000002",
"name": "Platform Metrics",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
220
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE status='ACTIVE') AS active_accounts, COUNT(*) FILTER (WHERE status='TRIAL') AS trial_accounts, SUM(mrr_usd) FILTER (WHERE status='ACTIVE') AS total_mrr, COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '7 days') AS new_this_week, COUNT(*) FILTER (WHERE status='CHURNED' AND updated_at >= NOW() - INTERVAL '7 days') AS churned_this_week, COUNT(*) FILTER (WHERE customer_tier='PRIME_DEFENSE_CONTRACTOR') AS prime_contractor_count FROM accounts"
}
},
{
"id": "e5f6a7b8-0005-0005-0005-000000000003",
"name": "Compliance Metrics",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
400
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE status='OPEN' AND deadline_type LIKE 'CMMC%') AS cmmc_open, COUNT(*) FILTER (WHERE status='OPEN' AND deadline_type LIKE 'ITAR%') AS itar_open, COUNT(*) FILTER (WHERE status='OPEN' AND deadline_type LIKE 'NDAA%') AS ndaa_open, COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '7 days') AS incidents_this_week, COUNT(*) FILTER (WHERE status='OPEN' AND (due_date - CURRENT_DATE) <= 30) AS critical_deadlines FROM compliance_deadlines WHERE status NOT IN ('COMPLETE','WAIVED')"
}
},
{
"id": "e5f6a7b8-0005-0005-0005-000000000004",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
680,
300
],
"parameters": {
"mode": "combineAll"
}
},
{
"id": "e5f6a7b8-0005-0005-0005-000000000005",
"name": "Build HTML Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
300
],
"parameters": {
"jsCode": "const p = $input.first().json;\nconst c = $input.last().json;\nconst mrr = parseFloat(p.total_mrr || 0).toFixed(0);\nconst html = `<h2>Defense SaaS Weekly KPI \u2014 ${new Date().toISOString().slice(0,10)}</h2><table border='1' cellpadding='6'><tr><th>Metric</th><th>Value</th></tr><tr><td>Active Accounts</td><td>${p.active_accounts}</td></tr><tr><td>Trial Accounts</td><td>${p.trial_accounts}</td></tr><tr><td>Total MRR</td><td>$${mrr}</td></tr><tr><td>New This Week</td><td>${p.new_this_week}</td></tr><tr><td>Churned This Week</td><td>${p.churned_this_week}</td></tr><tr><td>Prime Contractor Accounts</td><td>${p.prime_contractor_count}</td></tr><tr><td colspan='2'><strong>Compliance</strong></td></tr><tr><td>CMMC Open Items</td><td>${c.cmmc_open}</td></tr><tr><td>ITAR Open Items</td><td>${c.itar_open}</td></tr><tr><td>NDAA \u00a7889 Open Items</td><td>${c.ndaa_open}</td></tr><tr><td>Incidents This Week</td><td>${c.incidents_this_week}</td></tr><tr><td>Critical Deadlines \u226430d</td><td>${c.critical_deadlines}</td></tr></table>`;\nreturn [{ json: { html, reportDate: new Date().toISOString().slice(0,10) } }];"
}
},
{
"id": "e5f6a7b8-0005-0005-0005-000000000006",
"name": "Email Leadership",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1120,
300
],
"parameters": {
"operation": "send",
"toList": "ceo@yourcompany.com",
"ccList": "ciso@yourcompany.com,vp-compliance@yourcompany.com",
"subject": "Defense SaaS Weekly KPI \u2014 {{ $json.reportDate }}",
"message": "={{ $json.html }}"
}
}
],
"connections": {
"Monday 8AM": {
"main": [
[
{
"node": "Platform Metrics",
"type": "main",
"index": 0
},
{
"node": "Compliance Metrics",
"type": "main",
"index": 0
}
]
]
},
"Platform Metrics": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Compliance Metrics": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Build HTML Report",
"type": "main",
"index": 0
}
]
]
},
"Build HTML Report": {
"main": [
[
{
"node": "Email Leadership",
"type": "main",
"index": 0
}
]
]
}
}
}
Compliance Coverage Summary
| Regulation | Key Deadline | Workflow |
|---|---|---|
| DFARS 252.204-7012(m)(1) | 72h to DC3 after CUI incident | Workflow 2 |
| ITAR 22 CFR §127.12 | Voluntary disclosure, no fixed clock | Workflow 2 |
| NDAA §889(b)(1) | 24h to CO after prohibited item found | Workflow 4 |
| ITAR 22 CFR §122.1 | Registration renewal (annual) | Workflow 3 |
| CMMC 2.0 Level 2 C3PAO | Assessment cycle per contract | Workflow 3 |
| EAR CCL license expiry | Per license terms | Workflow 1 |
| NIST 800-171 SPRS update | Before each contract award | Workflow 3 |
Customizations to Add
-
SBIR/STTR tracking: Add
SBIR_PHASE_MILESTONEdeadline types with program office email routing -
Multi-program isolation: Add a
program_idfield and route alerts to program-specific Slack channels - DSP-83 nontransfer tracking: Log nontransfer/retransfer certificates alongside TAAs in Workflow 1
- SPRS score automation: After completing NIST 800-171 assessment, auto-calculate score and flag for PIEE submission
- Contract vehicle alerts: Add IDIQ/GWAC task order windows as deadline types in Workflow 3
All five workflows are available in the FlowKit n8n template store along with 10 other ready-to-run automations for SaaS operations.
Top comments (0)