[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"public-branding":3,"content-de-zero-trust-cloud-bots":8,"public-ads-config":807},{"siteName":4,"primaryColor":5,"accentColor":6,"faviconUrl":7,"logoUrl":7},"KiroCloud","#ffffff","#888888","",{"id":9,"title":10,"author":11,"body":12,"category":11,"description":23,"extension":793,"lastUpdated":11,"meta":794,"navigation":154,"order":795,"path":796,"readTime":11,"seo":797,"stem":805,"__hash__":806},"docs\u002Fdocs\u002Fde\u002Fzero-trust-cloud-bots.md","[object Object]",null,{"type":13,"value":14,"toc":787},"minimark",[15,20,24,37,40,45,84,93,95,99,106,537,539,543,550,751,753,757,760,780,783],[16,17,19],"h1",{"id":18},"zero-trust-architektur-für-cloud-bots-least-privilege-linux-sandbox-isolation","Zero-Trust Architektur für Cloud-Bots: Least-Privilege & Linux-Sandbox-Isolation",[21,22,23],"p",{},"Beim Betrieb einer Multi-Tenant Hosting-Plattform wie KiroCloud teilen sich hunderte fremde Bot-Prozesse dieselben physischen Server-Knoten. Wenn ein Benutzer schadhaften Code ausführt (z. B. einen Bot mit Path-Traversal, Krypto-Minern oder Reverse-Shells), darf dieser Prozess unter keinen Umständen auf benachbarte Bots, Systemdateien oder Datenbank-Credentials zugreifen können.",[21,25,26,27,31,32,36],{},"Das ",[28,29,30],"strong",{},"Zero-Trust-Sicherheitsmodell"," geht davon aus, dass jeder ausgeführte Prozess potentiell bösartig ist (",[33,34,35],"em",{},"\"Never Trust, Always Verify\"","). In diesem Leitfaden erläutern wir die Isolationsebenen moderner Cloud-Bot-Umgebungen.",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"_1-die-drei-säulen-der-zero-trust-bot-isolation","1. Die drei Säulen der Zero-Trust Bot-Isolation",[46,47,48,68,78],"ol",{},[49,50,51,54,55,59,60,63,64,67],"li",{},[28,52,53],{},"Dateisystem-Sandbox (Chroot & Linux Namespaces):"," Jeder Bot sieht ausschließlich sein eigenes Verzeichnis (",[56,57,58],"code",{},"\u002Fhome\u002Fkiro\u002Fbots\u002F{botId}","). System-Binaries (",[56,61,62],{},"\u002Fbin",", ",[56,65,66],{},"\u002Fusr",") werden nur schreibgeschützt (read-only) bereitgestellt.",[49,69,70,73,74,77],{},[28,71,72],{},"Netzwerk-Segmentierung (Egress Filtering):"," Bots dürfen ausschließlich ausgehende Verbindungen zu den Discord-API-Endpunkten und definierten Datenbank-Ports aufbauen. Der Zugriff auf interne Cloud-Management-Netzwerke (wie ",[56,75,76],{},"169.254.169.254"," oder interne Docker-Subnetze) ist auf Kernel-Ebene gesperrt.",[49,79,80,83],{},[28,81,82],{},"Flüchtige Zugangsdaten (Ephemeral Tokens):"," Zugriffstoken für Datenbanken und APIs besitzen kurze Lebensdauern (15 bis 60 Minuten) und werden automatisch erneuert.",[85,86,91],"pre",{"className":87,"code":89,"language":90},[88],"language-text","┌────────────────────────────────────────────────────────────────────────┐\n│                        Physischer Host-Server                          │\n├───────────────────────────────────┬────────────────────────────────────┤\n│  Sandbox A (Bot 1)                │  Sandbox B (Bot 2)                 │\n│  - PID Namespace (isoliert)       │  - PID Namespace (isoliert)        │\n│  - Mount Namespace (Read-Only OS) │  - Mount Namespace (Read-Only OS)  │\n│  - Cgroup RAM Cap: 512 MB         │  - Cgroup RAM Cap: 512 MB          │\n│  - Netfilter: Outbound Whitelist  │  - Netfilter: Outbound Whitelist   │\n└───────────────────────────────────┴────────────────────────────────────┘\n","text",[56,92,89],{"__ignoreMap":7},[38,94],{},[41,96,98],{"id":97},"_2-linux-namespaces-unprivileged-user-execution","2. Linux Namespaces & Unprivileged User Execution",[21,100,101,102,105],{},"Ein Bot-Prozess darf unter keinen Umständen als Root oder mit ",[56,103,104],{},"sudo","-Rechten ausgeführt werden. Beim Start eines Node.js-Workers wird der Prozess auf einen unprivilegierten System-Benutzer herabgestuft:",[85,107,111],{"className":108,"code":109,"language":110,"meta":7,"style":7},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { spawn } from 'node:child_process';\n\nexport function spawnSandboxedBot(botId: string, botEntrypoint: string) {\n  const botDir = `\u002Fvar\u002Fkiro\u002Fbots\u002F${botId}`;\n\n  const child = spawn('node', [botEntrypoint], {\n    cwd: botDir,\n    uid: 1005, \u002F\u002F Unprivilegierter System-Nutzer 'kiro-runner'\n    gid: 1005,\n    env: {\n      NODE_ENV: 'production',\n      PATH: '\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin',\n      BOT_ID: botId,\n    },\n    \u002F\u002F Trennung von Standard-Ein- und Ausgabe\n    stdio: ['ignore', 'pipe', 'pipe'],\n  });\n\n  child.stdout.on('data', (chunk) => {\n    \u002F\u002F Weiterleitung in den KiroCloud WebSocket Live-Log-Stream\n    broadcastBotLog(botId, chunk.toString());\n  });\n\n  return child;\n}\n","typescript",[56,112,113,149,156,200,228,233,270,283,301,313,323,340,357,370,376,382,420,430,435,476,482,507,516,521,531],{"__ignoreMap":7},[114,115,118,122,126,130,133,136,139,143,146],"span",{"class":116,"line":117},"line",1,[114,119,121],{"class":120},"s7zQu","import",[114,123,125],{"class":124},"sMK4o"," {",[114,127,129],{"class":128},"sTEyZ"," spawn",[114,131,132],{"class":124}," }",[114,134,135],{"class":120}," from",[114,137,138],{"class":124}," '",[114,140,142],{"class":141},"sfazB","node:child_process",[114,144,145],{"class":124},"'",[114,147,148],{"class":124},";\n",[114,150,152],{"class":116,"line":151},2,[114,153,155],{"emptyLinePlaceholder":154},true,"\n",[114,157,159,162,166,170,173,177,180,184,187,190,192,194,197],{"class":116,"line":158},3,[114,160,161],{"class":120},"export",[114,163,165],{"class":164},"spNyl"," function",[114,167,169],{"class":168},"s2Zo4"," spawnSandboxedBot",[114,171,172],{"class":124},"(",[114,174,176],{"class":175},"sHdIc","botId",[114,178,179],{"class":124},":",[114,181,183],{"class":182},"sBMFI"," string",[114,185,186],{"class":124},",",[114,188,189],{"class":175}," botEntrypoint",[114,191,179],{"class":124},[114,193,183],{"class":182},[114,195,196],{"class":124},")",[114,198,199],{"class":124}," {\n",[114,201,203,206,209,212,215,218,221,223,226],{"class":116,"line":202},4,[114,204,205],{"class":164},"  const",[114,207,208],{"class":128}," botDir",[114,210,211],{"class":124}," =",[114,213,214],{"class":124}," `",[114,216,217],{"class":141},"\u002Fvar\u002Fkiro\u002Fbots\u002F",[114,219,220],{"class":124},"${",[114,222,176],{"class":128},[114,224,225],{"class":124},"}`",[114,227,148],{"class":124},[114,229,231],{"class":116,"line":230},5,[114,232,155],{"emptyLinePlaceholder":154},[114,234,236,238,241,243,245,248,250,253,255,257,260,263,266,268],{"class":116,"line":235},6,[114,237,205],{"class":164},[114,239,240],{"class":128}," child",[114,242,211],{"class":124},[114,244,129],{"class":168},[114,246,172],{"class":247},"swJcz",[114,249,145],{"class":124},[114,251,252],{"class":141},"node",[114,254,145],{"class":124},[114,256,186],{"class":124},[114,258,259],{"class":247}," [",[114,261,262],{"class":128},"botEntrypoint",[114,264,265],{"class":247},"]",[114,267,186],{"class":124},[114,269,199],{"class":124},[114,271,273,276,278,280],{"class":116,"line":272},7,[114,274,275],{"class":247},"    cwd",[114,277,179],{"class":124},[114,279,208],{"class":128},[114,281,282],{"class":124},",\n",[114,284,286,289,291,295,297],{"class":116,"line":285},8,[114,287,288],{"class":247},"    uid",[114,290,179],{"class":124},[114,292,294],{"class":293},"sbssI"," 1005",[114,296,186],{"class":124},[114,298,300],{"class":299},"sHwdD"," \u002F\u002F Unprivilegierter System-Nutzer 'kiro-runner'\n",[114,302,304,307,309,311],{"class":116,"line":303},9,[114,305,306],{"class":247},"    gid",[114,308,179],{"class":124},[114,310,294],{"class":293},[114,312,282],{"class":124},[114,314,316,319,321],{"class":116,"line":315},10,[114,317,318],{"class":247},"    env",[114,320,179],{"class":124},[114,322,199],{"class":124},[114,324,326,329,331,333,336,338],{"class":116,"line":325},11,[114,327,328],{"class":247},"      NODE_ENV",[114,330,179],{"class":124},[114,332,138],{"class":124},[114,334,335],{"class":141},"production",[114,337,145],{"class":124},[114,339,282],{"class":124},[114,341,343,346,348,350,353,355],{"class":116,"line":342},12,[114,344,345],{"class":247},"      PATH",[114,347,179],{"class":124},[114,349,138],{"class":124},[114,351,352],{"class":141},"\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin",[114,354,145],{"class":124},[114,356,282],{"class":124},[114,358,360,363,365,368],{"class":116,"line":359},13,[114,361,362],{"class":247},"      BOT_ID",[114,364,179],{"class":124},[114,366,367],{"class":128}," botId",[114,369,282],{"class":124},[114,371,373],{"class":116,"line":372},14,[114,374,375],{"class":124},"    },\n",[114,377,379],{"class":116,"line":378},15,[114,380,381],{"class":299},"    \u002F\u002F Trennung von Standard-Ein- und Ausgabe\n",[114,383,385,388,390,392,394,397,399,401,403,406,408,410,412,414,416,418],{"class":116,"line":384},16,[114,386,387],{"class":247},"    stdio",[114,389,179],{"class":124},[114,391,259],{"class":247},[114,393,145],{"class":124},[114,395,396],{"class":141},"ignore",[114,398,145],{"class":124},[114,400,186],{"class":124},[114,402,138],{"class":124},[114,404,405],{"class":141},"pipe",[114,407,145],{"class":124},[114,409,186],{"class":124},[114,411,138],{"class":124},[114,413,405],{"class":141},[114,415,145],{"class":124},[114,417,265],{"class":247},[114,419,282],{"class":124},[114,421,423,426,428],{"class":116,"line":422},17,[114,424,425],{"class":124},"  }",[114,427,196],{"class":247},[114,429,148],{"class":124},[114,431,433],{"class":116,"line":432},18,[114,434,155],{"emptyLinePlaceholder":154},[114,436,438,441,444,447,449,452,454,456,459,461,463,466,469,471,474],{"class":116,"line":437},19,[114,439,440],{"class":128},"  child",[114,442,443],{"class":124},".",[114,445,446],{"class":128},"stdout",[114,448,443],{"class":124},[114,450,451],{"class":168},"on",[114,453,172],{"class":247},[114,455,145],{"class":124},[114,457,458],{"class":141},"data",[114,460,145],{"class":124},[114,462,186],{"class":124},[114,464,465],{"class":124}," (",[114,467,468],{"class":175},"chunk",[114,470,196],{"class":124},[114,472,473],{"class":164}," =>",[114,475,199],{"class":124},[114,477,479],{"class":116,"line":478},20,[114,480,481],{"class":299},"    \u002F\u002F Weiterleitung in den KiroCloud WebSocket Live-Log-Stream\n",[114,483,485,488,490,492,494,497,499,502,505],{"class":116,"line":484},21,[114,486,487],{"class":168},"    broadcastBotLog",[114,489,172],{"class":247},[114,491,176],{"class":128},[114,493,186],{"class":124},[114,495,496],{"class":128}," chunk",[114,498,443],{"class":124},[114,500,501],{"class":168},"toString",[114,503,504],{"class":247},"())",[114,506,148],{"class":124},[114,508,510,512,514],{"class":116,"line":509},22,[114,511,425],{"class":124},[114,513,196],{"class":247},[114,515,148],{"class":124},[114,517,519],{"class":116,"line":518},23,[114,520,155],{"emptyLinePlaceholder":154},[114,522,524,527,529],{"class":116,"line":523},24,[114,525,526],{"class":120},"  return",[114,528,240],{"class":128},[114,530,148],{"class":124},[114,532,534],{"class":116,"line":533},25,[114,535,536],{"class":124},"}\n",[38,538],{},[41,540,542],{"id":541},"_3-schutz-vor-path-traversal-in-dateimanagern","3. Schutz vor Path-Traversal in Dateimanagern",[21,544,545,546,549],{},"Wenn Nutzer Dateien über das Web-Dashboard hochladen oder editieren, muss jeder Pfad gegen Directory-Traversal-Angriffe (",[56,547,548],{},"..\u002F..\u002Fetc\u002Fpasswd",") verifiziert werden:",[85,551,553],{"className":108,"code":552,"language":110,"meta":7,"style":7},"import path from 'node:path';\n\nexport function resolveSafeBotPath(baseBotDir: string, userPath: string): string {\n  \u002F\u002F Normalisierung und Auflösung des absoluten Pfads\n  const resolved = path.resolve(baseBotDir, userPath);\n\n  \u002F\u002F Verifikation, dass der Pfad strikt innerhalb des Bot-Verzeichnisses liegt\n  if (!resolved.startsWith(baseBotDir + path.sep) && resolved !== baseBotDir) {\n    throw new Error('Sicherheitsverletzung: Zugriff außerhalb des Bot-Verzeichnisses verweigert (Path Traversal erkannt).');\n  }\n\n  return resolved;\n}\n",[56,554,555,574,578,612,617,646,650,655,706,730,735,739,747],{"__ignoreMap":7},[114,556,557,559,562,565,567,570,572],{"class":116,"line":117},[114,558,121],{"class":120},[114,560,561],{"class":128}," path ",[114,563,564],{"class":120},"from",[114,566,138],{"class":124},[114,568,569],{"class":141},"node:path",[114,571,145],{"class":124},[114,573,148],{"class":124},[114,575,576],{"class":116,"line":151},[114,577,155],{"emptyLinePlaceholder":154},[114,579,580,582,584,587,589,592,594,596,598,601,603,605,608,610],{"class":116,"line":158},[114,581,161],{"class":120},[114,583,165],{"class":164},[114,585,586],{"class":168}," resolveSafeBotPath",[114,588,172],{"class":124},[114,590,591],{"class":175},"baseBotDir",[114,593,179],{"class":124},[114,595,183],{"class":182},[114,597,186],{"class":124},[114,599,600],{"class":175}," userPath",[114,602,179],{"class":124},[114,604,183],{"class":182},[114,606,607],{"class":124},"):",[114,609,183],{"class":182},[114,611,199],{"class":124},[114,613,614],{"class":116,"line":202},[114,615,616],{"class":299},"  \u002F\u002F Normalisierung und Auflösung des absoluten Pfads\n",[114,618,619,621,624,626,629,631,634,636,638,640,642,644],{"class":116,"line":230},[114,620,205],{"class":164},[114,622,623],{"class":128}," resolved",[114,625,211],{"class":124},[114,627,628],{"class":128}," path",[114,630,443],{"class":124},[114,632,633],{"class":168},"resolve",[114,635,172],{"class":247},[114,637,591],{"class":128},[114,639,186],{"class":124},[114,641,600],{"class":128},[114,643,196],{"class":247},[114,645,148],{"class":124},[114,647,648],{"class":116,"line":235},[114,649,155],{"emptyLinePlaceholder":154},[114,651,652],{"class":116,"line":272},[114,653,654],{"class":299},"  \u002F\u002F Verifikation, dass der Pfad strikt innerhalb des Bot-Verzeichnisses liegt\n",[114,656,657,660,662,665,668,670,673,675,677,680,682,684,687,690,693,695,698,701,703],{"class":116,"line":285},[114,658,659],{"class":120},"  if",[114,661,465],{"class":247},[114,663,664],{"class":124},"!",[114,666,667],{"class":128},"resolved",[114,669,443],{"class":124},[114,671,672],{"class":168},"startsWith",[114,674,172],{"class":247},[114,676,591],{"class":128},[114,678,679],{"class":124}," +",[114,681,628],{"class":128},[114,683,443],{"class":124},[114,685,686],{"class":128},"sep",[114,688,689],{"class":247},") ",[114,691,692],{"class":124},"&&",[114,694,623],{"class":128},[114,696,697],{"class":124}," !==",[114,699,700],{"class":128}," baseBotDir",[114,702,689],{"class":247},[114,704,705],{"class":124},"{\n",[114,707,708,711,714,717,719,721,724,726,728],{"class":116,"line":303},[114,709,710],{"class":120},"    throw",[114,712,713],{"class":124}," new",[114,715,716],{"class":168}," Error",[114,718,172],{"class":247},[114,720,145],{"class":124},[114,722,723],{"class":141},"Sicherheitsverletzung: Zugriff außerhalb des Bot-Verzeichnisses verweigert (Path Traversal erkannt).",[114,725,145],{"class":124},[114,727,196],{"class":247},[114,729,148],{"class":124},[114,731,732],{"class":116,"line":315},[114,733,734],{"class":124},"  }\n",[114,736,737],{"class":116,"line":325},[114,738,155],{"emptyLinePlaceholder":154},[114,740,741,743,745],{"class":116,"line":342},[114,742,526],{"class":120},[114,744,623],{"class":128},[114,746,148],{"class":124},[114,748,749],{"class":116,"line":359},[114,750,536],{"class":124},[38,752],{},[41,754,756],{"id":755},"_4-least-privilege-datenbankzugriff","4. Least-Privilege Datenbankzugriff",[21,758,759],{},"Wenn ein Bot mit einer SQL-Datenbank interagiert, sollte niemals der PostgreSQL-Superuser verwendet werden:",[761,762,763,766,773],"ul",{},[49,764,765],{},"Eigene Datenbank und eigener Datenbanknutzer pro Bot",[49,767,768,769,772],{},"Keine Rechte für ",[56,770,771],{},"DROP DATABASE"," oder Manipulation von Systemtabellen",[49,774,775,776,779],{},"Maximale Verbindungslimits pro Bot (z. B. ",[56,777,778],{},"max_connections = 10","), um Denial-of-Service auf dem Datenbank-Server zu verhindern",[21,781,782],{},"Auf KiroCloud sorgt diese Architektur dafür, dass jeder Bot in einer vollständig isolierten Sandbox läuft – für maximale Stabilität und Sicherheit aller gehosteten Kunden-Instanzen.",[784,785,786],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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":7,"searchDepth":151,"depth":151,"links":788},[789,790,791,792],{"id":43,"depth":151,"text":44},{"id":97,"depth":151,"text":98},{"id":541,"depth":151,"text":542},{"id":755,"depth":151,"text":756},"md",{},0,"\u002Fdocs\u002Fde\u002Fzero-trust-cloud-bots",{"title":798,"description":23},{"Zero-Trust Architektur für Cloud-Bots":799,"description":800,"category":801,"order":158,"author":802,"readTime":803,"lastUpdated":804},"Least-Privilege & Linux-Sandbox-Isolation","Umfassender Leitfaden zum Aufbau von Zero-Trust Multi-Tenant Hostings für Discord Bots. Linux Namespaces, Cgroups, Ephemeral Tokens und Outbound-Filter.","security","Luca Lichtenwald","12 min","2026-10-09","docs\u002Fde\u002Fzero-trust-cloud-bots","JGyFQiJqJ7OA0jHML-cmBlPL1fKZeGoeC4AiLCJDBs8",{"enabled":154,"clientPubId":808,"docsSlotId":7,"newsSlotId":7,"guidesSlotId":7,"dashboardSlotId":7,"docsEnabled":154,"newsEnabled":154,"guidesEnabled":154,"dashboardEnabled":154},"ca-pub-9454065621077312"]