[{"data":1,"prerenderedAt":1293},["ShallowReactive",2],{"content-developer\u002Femail-security":3,"surround-\u002Fdeveloper\u002Femail-security":1284},{"id":4,"title":5,"body":6,"description":1276,"extension":1277,"meta":1278,"navigation":1279,"path":1280,"seo":1281,"stem":1282,"__hash__":1283},"content\u002F3.developer\u002F13.email-security.md","Email Security",{"type":7,"value":8,"toc":1240},"minimark",[9,26,31,34,39,42,98,102,123,127,130,162,166,169,177,181,196,200,203,252,257,307,311,314,318,321,409,413,416,434,438,441,549,553,566,570,588,592,601,605,637,641,695,699,735,739,746,750,759,763,773,777,787,810,814,821,825,831,871,874,902,905,913,917,920,945,949,1037,1041,1047,1073,1077,1236],[10,11,12,13,17,18,21,22,25],"p",{},"All outbound email passes through multi-layered security scanning before delivery. The ",[14,15,16],"code",{},"@owlat\u002Femail-scanner"," package provides all scanning logic as a shared library, consumed by both ",[14,19,20],{},"apps\u002Fapi"," (Convex) and ",[14,23,24],{},"apps\u002Fmta",".",[27,28,30],"h2",{"id":29},"content-scanning","Content Scanning",[10,32,33],{},"Analyzes email subject and HTML body for malicious or unwanted content. All scanners are pure TypeScript with zero dependencies, safe for the Convex serverless runtime.",[35,36,38],"h3",{"id":37},"spam-keywords","Spam Keywords",[10,40,41],{},"40+ weighted patterns detect common spam phrases:",[43,44,45,61],"table",{},[46,47,48],"thead",{},[49,50,51,55,58],"tr",{},[52,53,54],"th",{},"Category",[52,56,57],{},"Examples",[52,59,60],{},"Severity",[62,63,64,76,87],"tbody",{},[49,65,66,70,73],{},[67,68,69],"td",{},"Financial scams",[67,71,72],{},"\"free money\", \"million dollars\", \"wire transfer\"",[67,74,75],{},"High (20 pts)",[49,77,78,81,84],{},[67,79,80],{},"Urgency tactics",[67,82,83],{},"\"act now\", \"limited time\", \"expires today\"",[67,85,86],{},"Medium (10 pts)",[49,88,89,92,95],{},[67,90,91],{},"Suspicious phrases",[67,93,94],{},"\"click here\", \"no obligation\", \"satisfaction guaranteed\"",[67,96,97],{},"Low (3 pts)",[35,99,101],{"id":100},"phishing-url-detection","Phishing URL Detection",[103,104,105,109,120],"ul",{},[106,107,108],"li",{},"URL shortener detection (bit.ly, t.co, goo.gl, etc.)",[106,110,111,112,115,116,119],{},"Anchor\u002Fhref domain mismatch (link text says ",[14,113,114],{},"paypal.com"," but links to ",[14,117,118],{},"evil.com",")",[106,121,122],{},"Suspicious URL patterns (IP addresses in URLs, excessive subdomains)",[35,124,126],{"id":125},"homoglyph-unicode-spoofing","Homoglyph \u002F Unicode Spoofing",[10,128,129],{},"Detects mixed-script characters used to impersonate legitimate domains:",[103,131,132,151,154],{},[106,133,134,135,138,139,142,143,146,147,150],{},"~50 confusable character mappings (Cyrillic ",[14,136,137],{},"а"," U+0430 vs Latin ",[14,140,141],{},"a"," U+0061, Greek ",[14,144,145],{},"ο"," U+03BF vs Latin ",[14,148,149],{},"o",", etc.)",[106,152,153],{},"Mixed-script detection in link text and URL hostnames",[106,155,156,157,161],{},"Severity: ",[158,159,160],"strong",{},"high"," (20 pts) — homoglyph spoofing is a strong phishing indicator",[35,163,165],{"id":164},"prohibited-content","Prohibited Content",[10,167,168],{},"Pattern matching for high-severity scam content:",[103,170,171,174],{},[106,172,173],{},"Advance fee fraud patterns (\"beneficiary\", \"next of kin\", \"unclaimed funds\")",[106,175,176],{},"Credential phishing (\"verify your account\", \"confirm your password\", \"update your payment\")",[35,178,180],{"id":179},"subject-line-analysis","Subject Line Analysis",[103,182,183,186],{},[106,184,185],{},"ALL CAPS abuse (>50% uppercase characters)",[106,187,188,189,192,193,119],{},"Excessive punctuation (3+ consecutive ",[14,190,191],{},"!"," or ",[14,194,195],{},"?",[35,197,199],{"id":198},"scoring","Scoring",[10,201,202],{},"All flags contribute to a composite score:",[43,204,205,217],{},[46,206,207],{},[49,208,209,211,214],{},[52,210,60],{},[52,212,213],{},"Points",[52,215,216],{},"Example",[62,218,219,230,241],{},[49,220,221,224,227],{},[67,222,223],{},"High",[67,225,226],{},"20",[67,228,229],{},"Homoglyph spoofing, credential phishing",[49,231,232,235,238],{},[67,233,234],{},"Medium",[67,236,237],{},"10",[67,239,240],{},"URL shorteners, spam keywords",[49,242,243,246,249],{},[67,244,245],{},"Low",[67,247,248],{},"3",[67,250,251],{},"Excessive punctuation, minor spam phrases",[10,253,254],{},[158,255,256],{},"Thresholds:",[43,258,259,272],{},[46,260,261],{},[49,262,263,266,269],{},[52,264,265],{},"Score",[52,267,268],{},"Level",[52,270,271],{},"Action",[62,273,274,285,296],{},[49,275,276,279,282],{},[67,277,278],{},"0–14",[67,280,281],{},"Clean",[67,283,284],{},"Allowed",[49,286,287,290,293],{},[67,288,289],{},"15–39",[67,291,292],{},"Suspicious",[67,294,295],{},"Allowed with warning stored",[49,297,298,301,304],{},[67,299,300],{},"40+",[67,302,303],{},"Blocked",[67,305,306],{},"Send rejected",[27,308,310],{"id":309},"file-validation","File Validation",[10,312,313],{},"Validates attachments and media uploads before storage or sending. Pure TypeScript, no external dependencies.",[35,315,317],{"id":316},"magic-bytes-detection","Magic Bytes Detection",[10,319,320],{},"Identifies real file type from binary headers (first 16 bytes), regardless of file extension:",[43,322,323,333],{},[46,324,325],{},[49,326,327,330],{},[52,328,329],{},"File Type",[52,331,332],{},"Magic Bytes",[62,334,335,346,356,367,378,388,398],{},[49,336,337,340],{},[67,338,339],{},"PE executable (.exe, .dll)",[67,341,342,345],{},[14,343,344],{},"4D 5A"," (MZ)",[49,347,348,351],{},[67,349,350],{},"ELF binary",[67,352,353],{},[14,354,355],{},"7F 45 4C 46",[49,357,358,361],{},[67,359,360],{},"MSI installer",[67,362,363,366],{},[14,364,365],{},"D0 CF 11 E0"," (OLE compound)",[49,368,369,372],{},[67,370,371],{},"PDF",[67,373,374,377],{},[14,375,376],{},"25 50 44 46"," (%PDF)",[49,379,380,383],{},[67,381,382],{},"PNG",[67,384,385],{},[14,386,387],{},"89 50 4E 47",[49,389,390,393],{},[67,391,392],{},"JPEG",[67,394,395],{},[14,396,397],{},"FF D8 FF",[49,399,400,403],{},[67,401,402],{},"ZIP\u002FDOCX\u002FXLSX",[67,404,405,408],{},[14,406,407],{},"50 4B 03 04"," (PK)",[35,410,412],{"id":411},"double-extension-detection","Double Extension Detection",[10,414,415],{},"Catches attacks that hide executable extensions after document extensions:",[103,417,418,424,429],{},[106,419,420,423],{},[14,421,422],{},"invoice.pdf.exe"," — detected and blocked",[106,425,426,423],{},[14,427,428],{},"report.docx.js",[106,430,431,423],{},[14,432,433],{},"photo.jpg.scr",[35,435,437],{"id":436},"extension-allowlist","Extension Allowlist",[10,439,440],{},"Permitted file types (everything else is blocked):",[43,442,443,452],{},[46,444,445],{},[49,446,447,449],{},[52,448,54],{},[52,450,451],{},"Extensions",[62,453,454,489,514,533],{},[49,455,456,459],{},[67,457,458],{},"Images",[67,460,461,464,465,464,468,464,471,464,474,464,477,464,480,464,483,464,486],{},[14,462,463],{},".jpg",", ",[14,466,467],{},".jpeg",[14,469,470],{},".png",[14,472,473],{},".gif",[14,475,476],{},".webp",[14,478,479],{},".svg",[14,481,482],{},".ico",[14,484,485],{},".bmp",[14,487,488],{},".tiff",[49,490,491,494],{},[67,492,493],{},"Documents",[67,495,496,464,499,464,502,464,505,464,508,464,511],{},[14,497,498],{},".pdf",[14,500,501],{},".doc",[14,503,504],{},".docx",[14,506,507],{},".odt",[14,509,510],{},".rtf",[14,512,513],{},".txt",[49,515,516,519],{},[67,517,518],{},"Spreadsheets",[67,520,521,464,524,464,527,464,530],{},[14,522,523],{},".xls",[14,525,526],{},".xlsx",[14,528,529],{},".csv",[14,531,532],{},".ods",[49,534,535,538],{},[67,536,537],{},"Archives",[67,539,540,464,543,464,546],{},[14,541,542],{},".zip",[14,544,545],{},".gz",[14,547,548],{},".tar",[35,550,552],{"id":551},"mime-type-allowlist","MIME Type Allowlist",[10,554,555,556,464,559,464,562,565],{},"Validates declared content types against an allowlist of safe MIME types (e.g., ",[14,557,558],{},"image\u002F*",[14,560,561],{},"application\u002Fpdf",[14,563,564],{},"text\u002Fplain",").",[35,567,569],{"id":568},"integration-points","Integration Points",[103,571,572,580],{},[106,573,574,579],{},[158,575,576],{},[14,577,578],{},"emailWorker.ts"," — validates each attachment buffer before sending",[106,581,582,587],{},[158,583,584],{},[14,585,586],{},"mediaAssets.ts"," — validates uploads before storing to Convex file storage",[27,589,591],{"id":590},"url-reputation","URL Reputation",[10,593,594,595,25],{},"Checks URLs in email content against the ",[141,596,600],{"href":597,"rel":598},"https:\u002F\u002Fdevelopers.google.com\u002Fsafe-browsing\u002Fv4\u002Flookup-api",[599],"nofollow","Google Safe Browsing API v4",[35,602,604],{"id":603},"how-it-works","How It Works",[606,607,608,611,614,621,624,627],"ol",{},[106,609,610],{},"Extract all URLs from the email HTML content",[106,612,613],{},"Normalize and hash URLs (SHA-256)",[106,615,616,617,620],{},"Check cache (",[14,618,619],{},"urlReputationCache"," table) for known verdicts",[106,622,623],{},"Batch-check uncached URLs against Safe Browsing API (up to 500 per request)",[106,625,626],{},"Cache results (24h for clean, 1h for flagged)",[106,628,629,630,633,634],{},"Convert flagged URLs to ",[14,631,632],{},"ContentFlag"," entries with severity ",[14,635,636],{},"'high'",[35,638,640],{"id":639},"threat-types","Threat Types",[43,642,643,653],{},[46,644,645],{},[49,646,647,650],{},[52,648,649],{},"Threat",[52,651,652],{},"Description",[62,654,655,665,675,685],{},[49,656,657,662],{},[67,658,659],{},[14,660,661],{},"MALWARE",[67,663,664],{},"Sites hosting malicious software",[49,666,667,672],{},[67,668,669],{},[14,670,671],{},"SOCIAL_ENGINEERING",[67,673,674],{},"Phishing and deceptive sites",[49,676,677,682],{},[67,678,679],{},[14,680,681],{},"UNWANTED_SOFTWARE",[67,683,684],{},"Sites distributing unwanted software",[49,686,687,692],{},[67,688,689],{},[14,690,691],{},"POTENTIALLY_HARMFUL_APPLICATION",[67,693,694],{},"Mobile app threats",[35,696,698],{"id":697},"campaign-vs-transactional","Campaign vs Transactional",[43,700,701,711],{},[46,702,703],{},[49,704,705,708],{},[52,706,707],{},"Email Type",[52,709,710],{},"Behavior",[62,712,713,724],{},[49,714,715,718],{},[67,716,717],{},"Campaign sends",[67,719,720,723],{},[158,721,722],{},"Blocking gate"," — flagged URLs prevent the campaign from sending",[49,725,726,729],{},[67,727,728],{},"Transactional sends",[67,730,731,734],{},[158,732,733],{},"Graceful"," — flags stored for review, delivery not blocked",[35,736,738],{"id":737},"configuration","Configuration",[10,740,741,742,745],{},"Requires the ",[14,743,744],{},"GOOGLE_SAFE_BROWSING_API_KEY"," environment variable set in the Convex dashboard. The free tier allows 10,000 requests per day. When the API key is not configured, URL reputation checking is silently skipped.",[27,747,749],{"id":748},"clamav-malware-scanning","ClamAV Malware Scanning",[10,751,752,753,758],{},"Scans attachment binary data for known malware signatures using ",[141,754,757],{"href":755,"rel":756},"https:\u002F\u002Fwww.clamav.net\u002F",[599],"ClamAV"," running as a Docker sidecar alongside the MTA.",[35,760,762],{"id":761},"architecture","Architecture",[764,765,770],"pre",{"className":766,"code":768,"language":769},[767],"language-text","Convex emailWorker\n    │\n    │  POST \u002Fscan\u002Fattachment\n    │  (binary data + X-Filename header)\n    ▼\nMTA scan endpoint (src\u002Froutes\u002Fscan.ts)\n    │\n    ├─ File type validation (magic bytes, extensions)\n    │\n    └─ ClamAV scan (TCP INSTREAM protocol)\n        │\n        ▼\n    clamd (port 3310)\n","text",[14,771,768],{"__ignoreMap":772},"",[35,774,776],{"id":775},"instream-protocol","INSTREAM Protocol",[10,778,779,780,782,783,786],{},"The ",[14,781,16],{}," ClamAV client communicates with ",[14,784,785],{},"clamd"," over TCP using the INSTREAM protocol:",[606,788,789,795,798,801],{},[106,790,791,792],{},"Send ",[14,793,794],{},"zINSTREAM\\0",[106,796,797],{},"Send chunked binary data (4-byte big-endian length prefix + data)",[106,799,800],{},"Send zero-length terminator",[106,802,803,804,192,807],{},"Read verdict: ",[14,805,806],{},"stream: OK\\0",[14,808,809],{},"stream: \u003Cvirus_name> FOUND\\0",[35,811,813],{"id":812},"fail-open-design","Fail-Open Design",[10,815,816,817,820],{},"If ClamAV is unavailable (container not running, network error, timeout), the scan returns ",[14,818,819],{},"{ clean: true, skipped: true }"," and logs a warning. This prevents ClamAV outages from blocking all email delivery.",[35,822,824],{"id":823},"health-check","Health Check",[10,826,827,830],{},[14,828,829],{},"GET \u002Fscan\u002Fhealth"," returns the ClamAV connection status:",[764,832,836],{"className":833,"code":834,"language":835,"meta":772,"style":772},"language-json shiki shiki-themes github-light github-dark-dimmed","{ \"clamav\": \"connected\", \"version\": \"ClamAV 1.3.0\" }\n","json",[14,837,838],{"__ignoreMap":772},[839,840,843,847,851,854,858,860,863,865,868],"span",{"class":841,"line":842},"line",1,[839,844,846],{"class":845},"sYgZi","{ ",[839,848,850],{"class":849},"snmFh","\"clamav\"",[839,852,853],{"class":845},": ",[839,855,857],{"class":856},"s-HuK","\"connected\"",[839,859,464],{"class":845},[839,861,862],{"class":849},"\"version\"",[839,864,853],{"class":845},[839,866,867],{"class":856},"\"ClamAV 1.3.0\"",[839,869,870],{"class":845}," }\n",[10,872,873],{},"or",[764,875,877],{"className":833,"code":876,"language":835,"meta":772,"style":772},"{ \"clamav\": \"unavailable\", \"error\": \"Connection refused\" }\n",[14,878,879],{"__ignoreMap":772},[839,880,881,883,885,887,890,892,895,897,900],{"class":841,"line":842},[839,882,846],{"class":845},[839,884,850],{"class":849},[839,886,853],{"class":845},[839,888,889],{"class":856},"\"unavailable\"",[839,891,464],{"class":845},[839,893,894],{"class":849},"\"error\"",[839,896,853],{"class":845},[839,898,899],{"class":856},"\"Connection refused\"",[839,901,870],{"class":845},[35,903,738],{"id":904},"configuration-1",[10,906,907,908,912],{},"See ",[141,909,911],{"href":910},"\u002Fdeveloper\u002Fmta-system#clamav-sidecar-docker","MTA System > ClamAV Sidecar"," for Docker setup and environment variables.",[27,914,916],{"id":915},"feedback-loops","Feedback Loops",[10,918,919],{},"Spam complaints from ISP feedback loops are linked back to campaign content scan results:",[606,921,922,929,935,942],{},[106,923,924,925,928],{},"Resend\u002FMTA webhook delivers a ",[14,926,927],{},"complaint"," event",[106,930,931,934],{},[14,932,933],{},"resendWebhook.ts"," processes the complaint and looks up the campaign's content scan result",[106,936,937,938,941],{},"Complaint count is incremented on the ",[14,939,940],{},"contentScanResults"," record",[106,943,944],{},"This data enables future pattern learning and complaint rate tracking per campaign",[27,946,948],{"id":947},"integration-summary","Integration Summary",[43,950,951,967],{},[46,952,953],{},[49,954,955,958,961,964],{},[52,956,957],{},"Scanner",[52,959,960],{},"Where Called",[52,962,963],{},"Blocking?",[52,965,966],{},"On Failure",[62,968,969,988,1004,1019],{},[49,970,971,974,982,985],{},[67,972,973],{},"Content (spam + homoglyphs)",[67,975,976,464,979],{},[14,977,978],{},"emails.ts",[14,980,981],{},"transactionalEmails.ts",[67,983,984],{},"Yes",[67,986,987],{},"N\u002FA (pure TS, always runs)",[49,989,990,993,999,1001],{},[67,991,992],{},"File type validation",[67,994,995,464,997],{},[14,996,578],{},[14,998,586],{},[67,1000,984],{},[67,1002,1003],{},"Block (safe default)",[49,1005,1006,1009,1013,1016],{},[67,1007,1008],{},"URL reputation (Safe Browsing)",[67,1010,1011],{},[14,1012,978],{},[67,1014,1015],{},"Campaigns: yes, Transactional: no",[67,1017,1018],{},"Allow, skip silently",[49,1020,1021,1024,1032,1034],{},[67,1022,1023],{},"ClamAV malware scan",[67,1025,1026,1028,1029],{},[14,1027,578],{}," via MTA ",[14,1030,1031],{},"\u002Fscan\u002Fattachment",[67,1033,984],{},[67,1035,1036],{},"Allow, log warning (fail-open)",[27,1038,1040],{"id":1039},"package-structure","Package Structure",[764,1042,1045],{"className":1043,"code":1044,"language":769},[767],"packages\u002Femail-scanner\u002Fsrc\u002F\n├── content\u002F              # Content analysis (pure TS, Convex-safe)\n│   ├── index.ts          # scanContent() orchestrator\n│   ├── spamKeywords.ts   # 40+ weighted spam patterns\n│   ├── phishingUrls.ts   # URL shorteners, anchor\u002Fhref mismatch\n│   ├── homoglyphs.ts     # Unicode spoofing detection\n│   ├── prohibitedContent.ts  # Advance fee fraud, credential phishing\n│   └── subjectAnalysis.ts    # ALL CAPS, excessive punctuation\n├── files\u002F                # File type validation (pure TS)\n│   ├── index.ts          # validateFile() orchestrator\n│   ├── magicBytes.ts     # Binary header detection\n│   ├── doubleExtension.ts    # invoice.pdf.exe detection\n│   └── filePolicy.ts     # Allowlist\u002Fblocklist engine\n├── urls\u002F                 # URL reputation (uses fetch)\n│   ├── index.ts          # checkUrlReputation() orchestrator\n│   ├── safeBrowsing.ts   # Google Safe Browsing API v4 client\n│   └── cache.ts          # Abstract cache interface\n├── clamav\u002F               # ClamAV TCP client (Node.js net, MTA only)\n│   ├── index.ts          # createClamClient() factory\n│   ├── client.ts         # clamd INSTREAM protocol implementation\n│   └── pool.ts           # Connection pooling\n├── types.ts              # Shared types (ContentFlag, ScanResult, etc.)\n└── index.ts              # Barrel export (excludes clamav\u002F)\n",[14,1046,1044],{"__ignoreMap":772},[1048,1049,1052],"callout",{"title":1050,"type":1051},"ClamAV is Node.js only","info",[10,1053,779,1054,1057,1058,1061,1062,464,1065,1068,1069,1072],{},[14,1055,1056],{},"clamav\u002F"," module uses Node.js ",[14,1059,1060],{},"net"," for TCP connections and is only importable from the MTA. The ",[14,1063,1064],{},"content\u002F",[14,1066,1067],{},"files\u002F",", and ",[14,1070,1071],{},"urls\u002F"," modules are pure TS and work in both Convex and Node.js environments.",[27,1074,1076],{"id":1075},"key-files","Key Files",[43,1078,1079,1089],{},[46,1080,1081],{},[49,1082,1083,1086],{},[52,1084,1085],{},"File",[52,1087,1088],{},"Purpose",[62,1090,1091,1104,1117,1130,1143,1155,1165,1175,1185,1199,1209,1226],{},[49,1092,1093,1098],{},[67,1094,1095],{},[14,1096,1097],{},"packages\u002Femail-scanner\u002Fsrc\u002Fcontent\u002Findex.ts",[67,1099,1100,1103],{},[14,1101,1102],{},"scanContent()"," — main content scanning orchestrator",[49,1105,1106,1111],{},[67,1107,1108],{},[14,1109,1110],{},"packages\u002Femail-scanner\u002Fsrc\u002Ffiles\u002Findex.ts",[67,1112,1113,1116],{},[14,1114,1115],{},"validateFile()"," — file validation orchestrator",[49,1118,1119,1124],{},[67,1120,1121],{},[14,1122,1123],{},"packages\u002Femail-scanner\u002Fsrc\u002Furls\u002Findex.ts",[67,1125,1126,1129],{},[14,1127,1128],{},"checkUrlReputation()"," — URL reputation orchestrator",[49,1131,1132,1137],{},[67,1133,1134],{},[14,1135,1136],{},"packages\u002Femail-scanner\u002Fsrc\u002Fclamav\u002Findex.ts",[67,1138,1139,1142],{},[14,1140,1141],{},"createClamClient()"," — ClamAV client factory",[49,1144,1145,1150],{},[67,1146,1147],{},[14,1148,1149],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FcontentScanner.ts",[67,1151,1152,1153],{},"Thin re-export wrapper from ",[14,1154,16],{},[49,1156,1157,1162],{},[67,1158,1159],{},[14,1160,1161],{},"apps\u002Fapi\u002Fconvex\u002FemailWorker.ts",[67,1163,1164],{},"Attachment validation + ClamAV scan before sending",[49,1166,1167,1172],{},[67,1168,1169],{},[14,1170,1171],{},"apps\u002Fapi\u002Fconvex\u002FmediaAssets.ts",[67,1173,1174],{},"Upload file validation (extension + MIME type)",[49,1176,1177,1182],{},[67,1178,1179],{},[14,1180,1181],{},"apps\u002Fapi\u002Fconvex\u002Femails.ts",[67,1183,1184],{},"Content scanning + URL reputation in campaign send flow",[49,1186,1187,1192],{},[67,1188,1189],{},[14,1190,1191],{},"apps\u002Fapi\u002Fconvex\u002Fschema.ts",[67,1193,1194,1196,1197],{},[14,1195,619],{}," table, extended ",[14,1198,940],{},[49,1200,1201,1206],{},[67,1202,1203],{},[14,1204,1205],{},"apps\u002Fapi\u002Fconvex\u002FresendWebhook.ts",[67,1207,1208],{},"Complaint feedback loop integration",[49,1210,1211,1216],{},[67,1212,1213],{},[14,1214,1215],{},"apps\u002Fmta\u002Fsrc\u002Froutes\u002Fscan.ts",[67,1217,1218,1219,1221,1222,1225],{},"MTA ",[14,1220,1031],{}," and ",[14,1223,1224],{},"\u002Fscan\u002Fhealth"," endpoints",[49,1227,1228,1233],{},[67,1229,1230],{},[14,1231,1232],{},"apps\u002Fmta\u002Fdocker-compose.yml",[67,1234,1235],{},"ClamAV sidecar configuration",[1237,1238,1239],"style",{},"html pre.shiki code .sYgZi, html code.shiki .sYgZi{--shiki-default:#24292E;--shiki-dark:#ADBAC7}html pre.shiki code .snmFh, html code.shiki .snmFh{--shiki-default:#005CC5;--shiki-dark:#8DDB8C}html pre.shiki code .s-HuK, html code.shiki .s-HuK{--shiki-default:#032F62;--shiki-dark:#96D0FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":772,"searchDepth":1241,"depth":1241,"links":1242},2,[1243,1252,1259,1265,1272,1273,1274,1275],{"id":29,"depth":1241,"text":30,"children":1244},[1245,1247,1248,1249,1250,1251],{"id":37,"depth":1246,"text":38},3,{"id":100,"depth":1246,"text":101},{"id":125,"depth":1246,"text":126},{"id":164,"depth":1246,"text":165},{"id":179,"depth":1246,"text":180},{"id":198,"depth":1246,"text":199},{"id":309,"depth":1241,"text":310,"children":1253},[1254,1255,1256,1257,1258],{"id":316,"depth":1246,"text":317},{"id":411,"depth":1246,"text":412},{"id":436,"depth":1246,"text":437},{"id":551,"depth":1246,"text":552},{"id":568,"depth":1246,"text":569},{"id":590,"depth":1241,"text":591,"children":1260},[1261,1262,1263,1264],{"id":603,"depth":1246,"text":604},{"id":639,"depth":1246,"text":640},{"id":697,"depth":1246,"text":698},{"id":737,"depth":1246,"text":738},{"id":748,"depth":1241,"text":749,"children":1266},[1267,1268,1269,1270,1271],{"id":761,"depth":1246,"text":762},{"id":775,"depth":1246,"text":776},{"id":812,"depth":1246,"text":813},{"id":823,"depth":1246,"text":824},{"id":904,"depth":1246,"text":738},{"id":915,"depth":1241,"text":916},{"id":947,"depth":1241,"text":948},{"id":1039,"depth":1241,"text":1040},{"id":1075,"depth":1241,"text":1076},"Content scanning, attachment validation, URL reputation checking, and malware detection for outbound emails.","md",{},true,"\u002Fdeveloper\u002Femail-security",{"title":5,"description":1276},"3.developer\u002F13.email-security","ebqzHpe8x0z8BTr1CpP3jeKH3puzA9PMVU_-jxn_8fk",[1285,1289],{"title":1286,"path":1287,"stem":1288,"children":-1},"How Email Works","\u002Fdeveloper\u002Fhow-email-works","3.developer\u002F12.how-email-works",{"title":1290,"path":1291,"stem":1292,"children":-1},"Architecture Overview","\u002Fdeveloper\u002Farchitecture","3.developer\u002F2.architecture",1774391043086]