[{"data":1,"prerenderedAt":1281},["ShallowReactive",2],{"navigation_docs":3,"-reference-configuration-sandbox-network-policy":504,"-reference-configuration-sandbox-network-policy-surround":1276},[4,28,51,187,214,469],{"title":5,"path":6,"stem":7,"children":8},"Get started","\u002Fget-started","1.get-started",[9,12,16,20,24],{"title":10,"path":6,"stem":11},"Overview","1.get-started\u002Findex",{"title":13,"path":14,"stem":15},"Why Kraft","\u002Fget-started\u002Fwhy-kraft","1.get-started\u002F0.why-kraft",{"title":17,"path":18,"stem":19},"Install","\u002Fget-started\u002Finstall","1.get-started\u002F1.install",{"title":21,"path":22,"stem":23},"Your first work item","\u002Fget-started\u002Ffirst-work-item","1.get-started\u002F2.first-work-item",{"title":25,"path":26,"stem":27},"FAQ","\u002Fget-started\u002Ffaq","1.get-started\u002F3.faq",{"title":29,"path":30,"stem":31,"children":32},"Concepts","\u002Fconcepts","2.concepts",[33,35,39,43,47],{"title":10,"path":30,"stem":34},"2.concepts\u002Findex",{"title":36,"path":37,"stem":38},"How a work item runs","\u002Fconcepts\u002Fhow-a-work-item-runs","2.concepts\u002F1.how-a-work-item-runs",{"title":40,"path":41,"stem":42},"Caps and budgets","\u002Fconcepts\u002Fcaps-and-budgets","2.concepts\u002F2.caps-and-budgets",{"title":44,"path":45,"stem":46},"Why a permission gate","\u002Fconcepts\u002Fpermission-gate","2.concepts\u002F3.permission-gate",{"title":48,"path":49,"stem":50},"Vocabulary","\u002Fconcepts\u002Fvocabulary","2.concepts\u002F4.vocabulary",{"title":52,"path":53,"stem":54,"children":55},"Guides","\u002Fguides","3.guides",[56,58,96,113,134,183],{"title":10,"path":53,"stem":57},"3.guides\u002Findex",{"title":59,"path":60,"stem":61,"children":62,"page":95},"Day to day","\u002Fguides\u002Fday-to-day","3.guides\u002F1.day-to-day",[63,67,71,75,79,83,87,91],{"title":64,"path":65,"stem":66},"The setup wizard on first start","\u002Fguides\u002Fday-to-day\u002Ffirst-run","3.guides\u002F1.day-to-day\u002F2.first-run",{"title":68,"path":69,"stem":70},"File a work item","\u002Fguides\u002Fday-to-day\u002Ffile-a-work-item","3.guides\u002F1.day-to-day\u002F3.file-a-work-item",{"title":72,"path":73,"stem":74},"Use Kraft from your agent","\u002Fguides\u002Fday-to-day\u002Fagent-integration","3.guides\u002F1.day-to-day\u002F4.agent-integration",{"title":76,"path":77,"stem":78},"Reviewing a change","\u002Fguides\u002Fday-to-day\u002Freview-a-change","3.guides\u002F1.day-to-day\u002F5.review-a-change",{"title":80,"path":81,"stem":82},"Raise a cap on a stopped item","\u002Fguides\u002Fday-to-day\u002Fraise-a-cap","3.guides\u002F1.day-to-day\u002F6.raise-a-cap",{"title":84,"path":85,"stem":86},"Kraft for VS Code","\u002Fguides\u002Fday-to-day\u002Fvscode","3.guides\u002F1.day-to-day\u002F7.vscode",{"title":88,"path":89,"stem":90},"Kraft on a phone","\u002Fguides\u002Fday-to-day\u002Fkraft-on-a-phone","3.guides\u002F1.day-to-day\u002F8.kraft-on-a-phone",{"title":92,"path":93,"stem":94},"Get notified when an item needs you","\u002Fguides\u002Fday-to-day\u002Fnotifications","3.guides\u002F1.day-to-day\u002F9.notifications",false,{"title":97,"path":98,"stem":99,"children":100,"page":95},"Customize and automate","\u002Fguides\u002Fcustomize","3.guides\u002F2.customize",[101,105,109],{"title":102,"path":103,"stem":104},"Write your own chain","\u002Fguides\u002Fcustomize\u002Fwrite-your-own-chain","3.guides\u002F2.customize\u002F1.write-your-own-chain",{"title":106,"path":107,"stem":108},"Add a security review or a gate reviewer","\u002Fguides\u002Fcustomize\u002Fadd-review-agents","3.guides\u002F2.customize\u002F2.add-review-agents",{"title":110,"path":111,"stem":112},"Schedule or webhook work","\u002Fguides\u002Fcustomize\u002Fschedule-and-webhook-work","3.guides\u002F2.customize\u002F3.schedule-and-webhook-work",{"title":114,"path":115,"stem":116,"children":117,"page":95},"Agents and harnesses","\u002Fguides\u002Fharnesses","3.guides\u002F3.harnesses",[118,122,126,130],{"title":119,"path":120,"stem":121},"Switch a task to another harness","\u002Fguides\u002Fharnesses\u002Fswitch-harness","3.guides\u002F3.harnesses\u002F1.switch-harness",{"title":123,"path":124,"stem":125},"Add or override a harness","\u002Fguides\u002Fharnesses\u002Fadding-a-harness","3.guides\u002F3.harnesses\u002F2.adding-a-harness",{"title":127,"path":128,"stem":129},"Build a worker Kit","\u002Fguides\u002Fharnesses\u002Fworker-kit","3.guides\u002F3.harnesses\u002F3.worker-kit",{"title":131,"path":132,"stem":133},"Give a worker its login","\u002Fguides\u002Fharnesses\u002Fgive-a-worker-its-login","3.guides\u002F3.harnesses\u002F4.give-a-worker-its-login",{"title":135,"path":136,"stem":137,"children":138,"page":95},"Run the server","\u002Fguides\u002Frun","3.guides\u002F4.run",[139,143,147,151,155,159,163,167,171,175,179],{"title":140,"path":141,"stem":142},"Remote access","\u002Fguides\u002Frun\u002Fremote-access","3.guides\u002F4.run\u002F01.remote-access",{"title":144,"path":145,"stem":146},"Put a proxy in front of Kraft","\u002Fguides\u002Frun\u002Fput-a-proxy-in-front-of-kraft","3.guides\u002F4.run\u002F02.put-a-proxy-in-front-of-kraft",{"title":148,"path":149,"stem":150},"Restart Kraft without ending running agents","\u002Fguides\u002Frun\u002Frestart-kraft","3.guides\u002F4.run\u002F03.restart-kraft",{"title":152,"path":153,"stem":154},"Back up and restore the database","\u002Fguides\u002Frun\u002Fback-up-and-restore","3.guides\u002F4.run\u002F04.back-up-and-restore",{"title":156,"path":157,"stem":158},"Logs and disk space","\u002Fguides\u002Frun\u002Flogs-and-disk-space","3.guides\u002F4.run\u002F05.logs-and-disk-space",{"title":160,"path":161,"stem":162},"Run Kraft as a service","\u002Fguides\u002Frun\u002Frun-as-a-service","3.guides\u002F4.run\u002F06.run-as-a-service",{"title":164,"path":165,"stem":166},"Upgrade Kraft","\u002Fguides\u002Frun\u002Fupgrade-kraft","3.guides\u002F4.run\u002F07.upgrade-kraft",{"title":168,"path":169,"stem":170},"Upgrade your configuration","\u002Fguides\u002Frun\u002Fupgrade-your-configuration","3.guides\u002F4.run\u002F08.upgrade-your-configuration",{"title":172,"path":173,"stem":174},"Upgrade from 1.4","\u002Fguides\u002Frun\u002Fupgrade-from-1-4","3.guides\u002F4.run\u002F09.upgrade-from-1-4",{"title":176,"path":177,"stem":178},"Upgrade from 0.x or a release candidate","\u002Fguides\u002Frun\u002Fupgrade-from-0-x-or-a-release-candidate","3.guides\u002F4.run\u002F10.upgrade-from-0-x-or-a-release-candidate",{"title":180,"path":181,"stem":182},"Roll back to 1.4","\u002Fguides\u002Frun\u002Froll-back","3.guides\u002F4.run\u002F11.roll-back",{"title":184,"path":185,"stem":186},"Kraft Lite","\u002Fguides\u002Fkraft-lite","3.guides\u002F5.kraft-lite",{"title":188,"path":189,"stem":190,"children":191},"Troubleshooting","\u002Ftroubleshooting","4.troubleshooting",[192,194,198,202,206,210],{"title":10,"path":189,"stem":193},"4.troubleshooting\u002Findex",{"title":195,"path":196,"stem":197},"Why did my item stop?","\u002Ftroubleshooting\u002Fwhy-did-my-item-stop","4.troubleshooting\u002F1.why-did-my-item-stop",{"title":199,"path":200,"stem":201},"Stop reasons in detail","\u002Ftroubleshooting\u002Fstop-reasons-in-detail","4.troubleshooting\u002F2.stop-reasons-in-detail",{"title":203,"path":204,"stem":205},"Starting and reaching Kraft","\u002Ftroubleshooting\u002Fstarting-and-reaching-kraft","4.troubleshooting\u002F3.starting-and-reaching-kraft",{"title":207,"path":208,"stem":209},"Doctor failures","\u002Ftroubleshooting\u002Fdoctor-failures","4.troubleshooting\u002F4.doctor-failures",{"title":211,"path":212,"stem":213},"Sandbox and Kit stops","\u002Ftroubleshooting\u002Fsandbox-and-kit-stops","4.troubleshooting\u002F5.sandbox-and-kit-stops",{"title":215,"path":216,"stem":217,"children":218},"Reference","\u002Freference","5.reference",[219,221,259,281,285,375,393,419,423,427,461,465],{"title":10,"path":216,"stem":220},"5.reference\u002Findex",{"title":222,"path":223,"stem":224,"children":225},"Web UI","\u002Freference\u002Fweb-ui","5.reference\u002F00.web-ui\u002Findex",[226,227,231,235,239,243,247,251,255],{"title":10,"path":223,"stem":224},{"title":228,"path":229,"stem":230},"Sidebar, search, and keyboard","\u002Freference\u002Fweb-ui\u002Fsidebar-search-and-keyboard","5.reference\u002F00.web-ui\u002F0.sidebar-search-and-keyboard",{"title":232,"path":233,"stem":234},"The board","\u002Freference\u002Fweb-ui\u002Fboard","5.reference\u002F00.web-ui\u002F1.board",{"title":236,"path":237,"stem":238},"An item's page","\u002Freference\u002Fweb-ui\u002Fitem-page","5.reference\u002F00.web-ui\u002F2.item-page",{"title":240,"path":241,"stem":242},"Fix loops and test scopes","\u002Freference\u002Fweb-ui\u002Ffix-loops-and-test-scopes","5.reference\u002F00.web-ui\u002F3.fix-loops-and-test-scopes",{"title":244,"path":245,"stem":246},"Config before an item starts","\u002Freference\u002Fweb-ui\u002Fconfig-before-start","5.reference\u002F00.web-ui\u002F4.config-before-start",{"title":248,"path":249,"stem":250},"The review page","\u002Freference\u002Fweb-ui\u002Freview-page","5.reference\u002F00.web-ui\u002F5.review-page",{"title":252,"path":253,"stem":254},"Templates and Settings","\u002Freference\u002Fweb-ui\u002Ftemplates-and-settings","5.reference\u002F00.web-ui\u002F6.templates-and-settings",{"title":256,"path":257,"stem":258},"Analytics","\u002Freference\u002Fweb-ui\u002Fanalytics","5.reference\u002F00.web-ui\u002F7.analytics",{"title":260,"path":261,"stem":262,"children":263},"CLI","\u002Freference\u002Fcli","5.reference\u002F01.cli\u002Findex",[264,265,269,273,277],{"title":10,"path":261,"stem":262},{"title":266,"path":267,"stem":268},"Item verbs","\u002Freference\u002Fcli\u002Fitem","5.reference\u002F01.cli\u002F2.item",{"title":270,"path":271,"stem":272},"View verbs","\u002Freference\u002Fcli\u002Fview","5.reference\u002F01.cli\u002F3.view",{"title":274,"path":275,"stem":276},"Repo verbs","\u002Freference\u002Fcli\u002Frepo","5.reference\u002F01.cli\u002F4.repo",{"title":278,"path":279,"stem":280},"Admin verbs","\u002Freference\u002Fcli\u002Fadmin","5.reference\u002F01.cli\u002F5.admin",{"title":282,"path":283,"stem":284},"Work item statuses","\u002Freference\u002Fstatuses","5.reference\u002F02.statuses",{"title":286,"path":287,"stem":288,"children":289},"Configuration","\u002Freference\u002Fconfiguration","5.reference\u002F03.configuration\u002Findex",[290,291,309,313,317,321,325,329,333,337,371],{"title":10,"path":287,"stem":288},{"title":292,"path":293,"stem":294,"children":295},"repos.yaml","\u002Freference\u002Fconfiguration\u002Frepos","5.reference\u002F03.configuration\u002F02.repos\u002Findex",[296,297,301,305],{"title":10,"path":293,"stem":294},{"title":298,"path":299,"stem":300},"How connect proposes commands","\u002Freference\u002Fconfiguration\u002Frepos\u002Fconnect-proposals","5.reference\u002F03.configuration\u002F02.repos\u002F1.connect-proposals",{"title":302,"path":303,"stem":304},"detectors.yaml","\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors","5.reference\u002F03.configuration\u002F02.repos\u002F2.detectors",{"title":306,"path":307,"stem":308},"Workspaces","\u002Freference\u002Fconfiguration\u002Frepos\u002Fworkspaces","5.reference\u002F03.configuration\u002F02.repos\u002F3.workspaces",{"title":310,"path":311,"stem":312},"policy.yaml","\u002Freference\u002Fconfiguration\u002Fpolicy","5.reference\u002F03.configuration\u002F03.policy",{"title":314,"path":315,"stem":316},"Library and chains","\u002Freference\u002Fconfiguration\u002Flibrary-and-chains","5.reference\u002F03.configuration\u002F04.library-and-chains",{"title":318,"path":319,"stem":320},"harnesses.yaml","\u002Freference\u002Fconfiguration\u002Fharnesses-file","5.reference\u002F03.configuration\u002F05.harnesses-file",{"title":322,"path":323,"stem":324},"access.yaml","\u002Freference\u002Fconfiguration\u002Faccess","5.reference\u002F03.configuration\u002F06.access",{"title":326,"path":327,"stem":328},"intake.yaml","\u002Freference\u002Fconfiguration\u002Fintake","5.reference\u002F03.configuration\u002F07.intake",{"title":330,"path":331,"stem":332},"notify.yaml","\u002Freference\u002Fconfiguration\u002Fnotify","5.reference\u002F03.configuration\u002F08.notify",{"title":334,"path":335,"stem":336},"theme.yaml","\u002Freference\u002Fconfiguration\u002Ftheme","5.reference\u002F03.configuration\u002F09.theme",{"title":338,"path":339,"stem":340,"children":341},"Sandboxed workers","\u002Freference\u002Fconfiguration\u002Fsandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002Findex",[342,343,347,351,355,359,363,367],{"title":10,"path":339,"stem":340},{"title":344,"path":345,"stem":346},"Resource limits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fresource-limits","5.reference\u002F03.configuration\u002F10.sandbox\u002F1.resource-limits",{"title":348,"path":349,"stem":350},"Callbacks from a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcallbacks","5.reference\u002F03.configuration\u002F10.sandbox\u002F2.callbacks",{"title":352,"path":353,"stem":354},"Network policy","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fnetwork-policy","5.reference\u002F03.configuration\u002F10.sandbox\u002F3.network-policy",{"title":356,"path":357,"stem":358},"Credentials","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcredentials","5.reference\u002F03.configuration\u002F10.sandbox\u002F4.credentials",{"title":360,"path":361,"stem":362},"Kits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fkits","5.reference\u002F03.configuration\u002F10.sandbox\u002F5.kits",{"title":364,"path":365,"stem":366},"sandbox.yaml","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fsandbox-yaml","5.reference\u002F03.configuration\u002F10.sandbox\u002F6.sandbox-yaml",{"title":368,"path":369,"stem":370},"Git in a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fgit-in-a-sandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002F7.git-in-a-sandbox",{"title":372,"path":373,"stem":374},"Environment variables","\u002Freference\u002Fconfiguration\u002Fenvironment-variables","5.reference\u002F03.configuration\u002F11.environment-variables",{"title":376,"path":377,"stem":378,"children":379},"Chain file keys","\u002Freference\u002Fchain-nodes","5.reference\u002F04.chain-nodes\u002Findex",[380,381,385,389],{"title":10,"path":377,"stem":378},{"title":382,"path":383,"stem":384},"Subprocess tasks","\u002Freference\u002Fchain-nodes\u002Fsubprocess-tasks","5.reference\u002F04.chain-nodes\u002F2.subprocess-tasks",{"title":386,"path":387,"stem":388},"Fix loop and judge","\u002Freference\u002Fchain-nodes\u002Ffix-loop","5.reference\u002F04.chain-nodes\u002F3.fix-loop",{"title":390,"path":391,"stem":392},"Result file","\u002Freference\u002Fchain-nodes\u002Fresult-file","5.reference\u002F04.chain-nodes\u002F4.result-file",{"title":394,"path":395,"stem":396,"children":397},"Agent harnesses","\u002Freference\u002Fharnesses","5.reference\u002F05.harnesses\u002Findex",[398,399,403,407,411,415],{"title":10,"path":395,"stem":396},{"title":400,"path":401,"stem":402},"Unattended runs","\u002Freference\u002Fharnesses\u002Funattended-runs","5.reference\u002F05.harnesses\u002F2.unattended-runs",{"title":404,"path":405,"stem":406},"Agent profiles","\u002Freference\u002Fharnesses\u002Fagent-profiles","5.reference\u002F05.harnesses\u002F3.agent-profiles",{"title":408,"path":409,"stem":410},"Harness definition files","\u002Freference\u002Fharnesses\u002Fharness-files","5.reference\u002F05.harnesses\u002F4.harness-files",{"title":412,"path":413,"stem":414},"Fallback and escalation","\u002Freference\u002Fharnesses\u002Ffallback-and-escalation","5.reference\u002F05.harnesses\u002F5.fallback-and-escalation",{"title":416,"path":417,"stem":418},"Cost reporting","\u002Freference\u002Fharnesses\u002Fcost-reporting","5.reference\u002F05.harnesses\u002F6.cost-reporting",{"title":420,"path":421,"stem":422},"Permission gate","\u002Freference\u002Fpermissions","5.reference\u002F06.permissions",{"title":424,"path":425,"stem":426},"Inbound triggers","\u002Freference\u002Ftriggers","5.reference\u002F07.triggers",{"title":428,"path":429,"stem":430,"children":431},"HTTP API","\u002Freference\u002Fhttp-api","5.reference\u002F08.http-api\u002Findex",[432,433,437,441,445,449,453,457],{"title":10,"path":429,"stem":430},{"title":434,"path":435,"stem":436},"Filing, reading and changing work items","\u002Freference\u002Fhttp-api\u002Fwork-items","5.reference\u002F08.http-api\u002F2.work-items",{"title":438,"path":439,"stem":440},"Gates, run control, ending and retry","\u002Freference\u002Fhttp-api\u002Fgates-run-control-and-ending","5.reference\u002F08.http-api\u002F3.gates-run-control-and-ending",{"title":442,"path":443,"stem":444},"The work item object","\u002Freference\u002Fhttp-api\u002Fwork-item-object","5.reference\u002F08.http-api\u002F4.work-item-object",{"title":446,"path":447,"stem":448},"Budget, events, diff and documents","\u002Freference\u002Fhttp-api\u002Fbudget-and-events","5.reference\u002F08.http-api\u002F5.budget-and-events",{"title":450,"path":451,"stem":452},"Repos, chains, harnesses and the server","\u002Freference\u002Fhttp-api\u002Frepos-chains-harnesses-and-server","5.reference\u002F08.http-api\u002F6.repos-chains-harnesses-and-server",{"title":454,"path":455,"stem":456},"Drafts","\u002Freference\u002Fhttp-api\u002Fdrafts","5.reference\u002F08.http-api\u002F7.drafts",{"title":458,"path":459,"stem":460},"Ops for each draft area","\u002Freference\u002Fhttp-api\u002Fdraft-ops","5.reference\u002F08.http-api\u002F8.draft-ops",{"title":462,"path":463,"stem":464},"MCP tools","\u002Freference\u002Fmcp-tools","5.reference\u002F09.mcp-tools",{"title":466,"path":467,"stem":468},"Events","\u002Freference\u002Fevents","5.reference\u002F10.events",{"title":470,"path":471,"stem":472,"children":473},"Security and project","\u002Fproject","6.project",[474,476,480,484,488,492,496,500],{"title":10,"path":471,"stem":475},"6.project\u002Findex",{"title":477,"path":478,"stem":479},"Security","\u002Fproject\u002Fsecurity","6.project\u002F1.security",{"title":481,"path":482,"stem":483},"Data and privacy","\u002Fproject\u002Fdata-and-privacy","6.project\u002F2.data-and-privacy",{"title":485,"path":486,"stem":487},"What's new in 2.0","\u002Fproject\u002Fwhats-new","6.project\u002F3.whats-new",{"title":489,"path":490,"stem":491},"Status and support","\u002Fproject\u002Fstatus-and-support","6.project\u002F4.status-and-support",{"title":493,"path":494,"stem":495},"Architecture","\u002Fproject\u002Farchitecture","6.project\u002F5.architecture",{"title":497,"path":498,"stem":499},"Source map","\u002Fproject\u002Fsource-map","6.project\u002F6.source-map",{"title":501,"path":502,"stem":503},"Contributing","\u002Fproject\u002Fcontributing","6.project\u002F7.contributing",{"id":505,"title":352,"body":506,"description":1269,"extension":1270,"links":1271,"meta":1272,"navigation":1273,"path":353,"seo":1274,"stem":354,"__hash__":1275},"docs\u002F5.reference\u002F03.configuration\u002F10.sandbox\u002F3.network-policy.md",{"type":507,"value":508,"toc":1254},"minimark",[509,524,657,668,673,754,763,798,801,815,818,831,885,890,912,916,945,949,952,983,987,1006,1027,1037,1042,1053,1073,1083,1088,1092,1100,1111,1115,1138,1142,1156,1160,1163,1181,1190,1194,1225,1229,1250],[510,511,512,513,517,518,523],"p",{},"A ",[514,515,516],"code",{},"network"," policy limits which hosts a ",[519,520,522],"a",{"href":521},"\u002Fconcepts\u002Fvocabulary#sandbox","sandboxed"," task reaches. This page covers how to write the host lists, how Kraft enforces them, and where the policy stops.",[525,526,532],"pre",{"className":527,"code":528,"filename":529,"language":530,"meta":531,"style":531},"language-yaml shiki shiki-themes github-light-high-contrast github-light-high-contrast github-dark-high-contrast","repos:\n  - path: \u002Fhome\u002Fyou\u002Fcode\u002Fmy-service\n    sandbox:\n      kind: docker\n      image: ghcr.io\u002Facme\u002Fagent@sha256:...\n      network:\n        install: {allow: [registry.npmjs.org, pypi.org, files.pythonhosted.org]}\n        runtime: {allow: [api.github.com], deny: []}\n","config\u002Frepos.yaml","yaml","",[514,533,534,547,563,571,582,593,601,633],{"__ignoreMap":531},[535,536,539,543],"span",{"class":537,"line":538},"line",1,[535,540,542],{"class":541},"sb7M8","repos",[535,544,546],{"class":545},"s7iLA",":\n",[535,548,550,553,556,559],{"class":537,"line":549},2,[535,551,552],{"class":545},"  - ",[535,554,555],{"class":541},"path",[535,557,558],{"class":545},": ",[535,560,562],{"class":561},"semJd","\u002Fhome\u002Fyou\u002Fcode\u002Fmy-service\n",[535,564,566,569],{"class":537,"line":565},3,[535,567,568],{"class":541},"    sandbox",[535,570,546],{"class":545},[535,572,574,577,579],{"class":537,"line":573},4,[535,575,576],{"class":541},"      kind",[535,578,558],{"class":545},[535,580,581],{"class":561},"docker\n",[535,583,585,588,590],{"class":537,"line":584},5,[535,586,587],{"class":541},"      image",[535,589,558],{"class":545},[535,591,592],{"class":561},"ghcr.io\u002Facme\u002Fagent@sha256:...\n",[535,594,596,599],{"class":537,"line":595},6,[535,597,598],{"class":541},"      network",[535,600,546],{"class":545},[535,602,604,607,610,613,616,619,622,625,627,630],{"class":537,"line":603},7,[535,605,606],{"class":541},"        install",[535,608,609],{"class":545},": {",[535,611,612],{"class":541},"allow",[535,614,615],{"class":545},": [",[535,617,618],{"class":561},"registry.npmjs.org",[535,620,621],{"class":545},", ",[535,623,624],{"class":561},"pypi.org",[535,626,621],{"class":545},[535,628,629],{"class":561},"files.pythonhosted.org",[535,631,632],{"class":545},"]}\n",[535,634,636,639,641,643,645,648,651,654],{"class":537,"line":635},8,[535,637,638],{"class":541},"        runtime",[535,640,609],{"class":545},[535,642,612],{"class":541},[535,644,615],{"class":545},[535,646,647],{"class":561},"api.github.com",[535,649,650],{"class":545},"], ",[535,652,653],{"class":541},"deny",[535,655,656],{"class":545},": []}\n",[510,658,659,660,662,663,667],{},"With ",[514,661,516],{}," set, a sandboxed task reaches only what its lists allow. Without it, a sandboxed task has the runtime's default network and can reach anything, the cloud metadata address included, so Kraft refuses the launch (see ",[519,664,666],{"href":665},"#without-a-network-policy","Without a network policy",").",[669,670,672],"h2",{"id":671},"phases-and-host-lists","Phases and host lists",[674,675,676,692],"table",{},[677,678,679],"thead",{},[680,681,682,686,689],"tr",{},[683,684,685],"th",{},"Field",[683,687,688],{},"Type",[683,690,691],{},"Applies to",[693,694,695,718,734],"tbody",{},[680,696,697,703,711],{},[698,699,700],"td",{},[514,701,702],{},"install",[698,704,705,706,708,709],{},"mapping with ",[514,707,612],{}," and ",[514,710,653],{},[698,712,713,714,717],{},"The repository's ",[514,715,716],{},"setup_command",".",[680,719,720,725,731],{},[698,721,722],{},[514,723,724],{},"runtime",[698,726,705,727,708,729],{},[514,728,612],{},[514,730,653],{},[698,732,733],{},"Every task session: agents, commands, test scopes, reviews and escalations.",[680,735,736,744,751],{},[698,737,738,621,741],{},[514,739,740],{},"\u003Cphase>.allow",[514,742,743],{},"\u003Cphase>.deny",[698,745,746,747,750],{},"list of hosts, ",[514,748,749],{},"[]"," by default",[698,752,753],{},"The hosts the phase may, and may not, reach.",[510,755,756,757,759,760,762],{},"A host in ",[514,758,612],{}," or ",[514,761,653],{}," is written as:",[764,765,766,776,789],"ul",{},[767,768,769,771,772,775],"li",{},[514,770,647],{},", which names that host exactly, or ",[514,773,774],{},"api.github.com:443",", which names it on one port.",[767,777,778,781,782,785,786,788],{},[514,779,780],{},"*.example.com",", which covers exactly one label in front of ",[514,783,784],{},"example.com",", not ",[514,787,784],{}," itself.",[767,790,791,759,794,797],{},[514,792,793],{},"*",[514,795,796],{},"**",", which cover everything.",[510,799,800],{},"CIDRs are not accepted.",[510,802,803,804,807,808,811,812,814],{},"Deny wins over allow. A phase that is missing or has empty lists allows nothing, so ",[514,805,806],{},"network: {runtime: {}}"," denies everything. Only ",[514,809,810],{},"network: {}"," with no phase at all is the same as no ",[514,813,516],{},". The lists are part of the sandbox, so a chain, node or task cannot change them.",[669,816,666],{"id":817},"without-a-network-policy",[510,819,820,821,823,824,826,827,830],{},"A launch into a sandbox with no ",[514,822,516],{}," is refused, whatever the harness. The task stops as a configuration error before anything runs, and the session's log names the repository and both fixes: add a ",[514,825,516],{}," policy, or set ",[514,828,829],{},"unrestricted_network: true"," on the sandbox.",[525,832,834],{"className":527,"code":833,"filename":529,"language":530,"meta":531,"style":531},"repos:\n  - path: \u002Fhome\u002Fyou\u002Fcode\u002Fmy-service\n    sandbox:\n      kind: docker\n      image: ghcr.io\u002Facme\u002Fagent@sha256:...\n      unrestricted_network: true\n",[514,835,836,842,852,858,866,874],{"__ignoreMap":531},[535,837,838,840],{"class":537,"line":538},[535,839,542],{"class":541},[535,841,546],{"class":545},[535,843,844,846,848,850],{"class":537,"line":549},[535,845,552],{"class":545},[535,847,555],{"class":541},[535,849,558],{"class":545},[535,851,562],{"class":561},[535,853,854,856],{"class":537,"line":565},[535,855,568],{"class":541},[535,857,546],{"class":545},[535,859,860,862,864],{"class":537,"line":573},[535,861,576],{"class":541},[535,863,558],{"class":545},[535,865,581],{"class":561},[535,867,868,870,872],{"class":537,"line":584},[535,869,587],{"class":541},[535,871,558],{"class":545},[535,873,592],{"class":561},[535,875,876,879,881],{"class":537,"line":595},[535,877,878],{"class":541},"      unrestricted_network",[535,880,558],{"class":545},[535,882,884],{"class":883},"ssYy9","true\n",[510,886,887,889],{},[514,888,829],{}," says you accept that the worker's network is not restricted and that gates are not enforced: Kraft sets up no channel, and nothing keeps the container from dialing the host.",[510,891,892,893,896,897,900,901,903,904,907,908,911],{},"The launch then runs, and Kraft logs a warning at each one. ",[514,894,895],{},"kraft admin doctor"," reports the sandbox's ",[514,898,899],{},"egress"," row as a warning instead of a failure. The key is refused together with ",[514,902,516],{},", and by a ",[514,905,906],{},"kit"," sandbox. See ",[519,909,348],{"href":910},"\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcallbacks#without-network"," for what a task without a channel does differently.",[669,913,915],{"id":914},"harness-hosts","Harness hosts",[510,917,918,919,921,922,926,927,930,931,933,934,937,938,941,942,944],{},"An agent session's ",[514,920,724],{}," allow list also gets the hosts its ",[519,923,925],{"href":924},"\u002Fconcepts\u002Fvocabulary#harness","harness"," file declares under ",[514,928,929],{},"network.requires",", and a ",[514,932,653],{}," still wins over them. Only ",[514,935,936],{},"api.anthropic.com"," (Claude) and ",[514,939,940],{},"api.openai.com"," (Codex) have been checked. The rest are unverified: if a CLI needs a host its harness does not list, allow it in ",[514,943,724],{},". OpenCode declares none, because its hosts depend on its provider.",[669,946,948],{"id":947},"always-denied","Always denied",[510,950,951],{},"Whatever the lists say, these are denied:",[764,953,954,957,967,977,980],{},[767,955,956],{},"loopback;",[767,958,959,960,621,963,966],{},"link-local (",[514,961,962],{},"169.254.0.0\u002F16",[514,964,965],{},"fe80::\u002F10",");",[767,968,969,970,621,973,976],{},"the unspecified (",[514,971,972],{},"0.0.0.0",[514,974,975],{},"::",") and multicast addresses;",[767,978,979],{},"cloud metadata names and addresses;",[767,981,982],{},"the host's own addresses, which are what its hostname resolves to.",[669,984,986],{"id":985},"how-network-policy-works","How network policy works",[510,988,989,990,993,994,996,997,1001,1002,1005],{},"Each session gets a relay container with no network of its own, from ",[514,991,992],{},"relay_image"," in ",[519,995,364],{"href":365},". The ",[519,998,1000],{"href":999},"\u002Fconcepts\u002Fvocabulary#worker","worker"," joins the relay's network namespace, so loopback is its only interface. The relay forwards ",[514,1003,1004],{},"127.0.0.1:3128"," there to a unix socket that belongs to that session alone, and the Kraft server serves the proxy on it.",[510,1007,1008,1009,708,1012,1015,1016,1019,1020,1023,1024,717],{},"The worker gets ",[514,1010,1011],{},"HTTP_PROXY",[514,1013,1014],{},"HTTPS_PROXY",", in both cases, set to ",[514,1017,1018],{},"http:\u002F\u002F127.0.0.1:3128",", an empty ",[514,1021,1022],{},"NO_PROXY",", and ",[514,1025,1026],{},"NODE_USE_ENV_PROXY=1",[510,1028,1029,1030,621,1032,708,1034,1036],{},"The server makes each allowed connection itself, through its own ",[514,1031,1014],{},[514,1033,1011],{},[514,1035,1022],{}," when it has them, so a proxy on the host's loopback works here. After a server restart, a running session's channel is reopened with the lists it launched under, not the current configuration.",[1038,1039,1041],"h3",{"id":1040},"docker-desktop-and-podman-machine","Docker Desktop and Podman machine",[510,1043,1044,1045,1048,1049,1052],{},"These run containers in a VM, where a container cannot connect to a host unix socket. Kraft checks once per runtime whether a container can connect to a host socket. When it cannot, and the runtime reports that it runs in a VM (Docker Desktop's ",[514,1046,1047],{},"OperatingSystem",", Podman's ",[514,1050,1051],{},"ServiceIsRemote","), Kraft carries the channel in two hops instead:",[764,1054,1055,1058],{},[767,1056,1057],{},"The relay the worker joins, still with no network, forwards to a socket in a volume made for that session.",[767,1059,1060,1061,1064,1065,1068,1069,1072],{},"A second relay, on the runtime's default network, forwards that socket to one mutual-TLS listener the server keeps on ",[514,1062,1063],{},"127.0.0.1",", which it reaches as ",[514,1066,1067],{},"host.docker.internal"," (Docker) or ",[514,1070,1071],{},"host.containers.internal"," (Podman).",[510,1074,1075,1076,1078,1079,1082],{},"Both relays run ",[514,1077,992],{},". The listener trusts only a client certificate from Kraft's own CA, kept under ",[514,1080,1081],{},"run\u002Fca\u002F",", and takes the session from that certificate, one per session, which only the second relay mounts. The worker shares no network, volume or mount with it.",[510,1084,1085,1087],{},[514,1086,895],{}," names the transport in the repository's sandbox row and checks that the listener answers.",[669,1089,1091],{"id":1090},"how-addresses-are-checked","How addresses are checked",[510,1093,1094,1095,759,1097,1099],{},"Kraft checks the address a name resolves to, resolving it once on the host, and then connects to that checked address. Through an upstream proxy (the server's own ",[514,1096,1011],{},[514,1098,1014],{},"), Kraft still checks the address, but the upstream resolves the name again and connects to whatever it gets. If any address a name resolves to is denied, the whole name is refused.",[510,1101,1102,1103,1106,1107,1110],{},"An IPv4 address carried inside an IPv6 one (IPv4-mapped, IPv4-compatible, 6to4, NAT64 ",[514,1104,1105],{},"64:ff9b::\u002F96",") is checked as that IPv4 address as well. Any other non-public address (RFC 1918, IPv6 ULA, the shared ",[514,1108,1109],{},"100.64.0.0\u002F10"," range, reserved ranges) is reachable only through an allow entry naming its host exactly, never through a wildcard.",[669,1112,1114],{"id":1113},"refusals","Refusals",[510,1116,1117,1118,1121,1122,1125,1126,1129,1130,1133,1134,1137],{},"A refused request is answered ",[514,1119,1120],{},"403"," with a one-line reason. Kraft records one ",[514,1123,1124],{},"sandbox_egress_refused"," event (",[514,1127,1128],{},"{session_id, host, port, phase, reason}",") per session and host, so a retry loop does not flood the timeline: ",[514,1131,1132],{},"kraft view events --type sandbox_egress_refused",". After 100 hosts, one last event with ",[514,1135,1136],{},"suppressed: true"," says later refusals in that session are not recorded; they are still refused.",[669,1139,1141],{"id":1140},"clients-that-ignore-the-proxy","Clients that ignore the proxy",[510,1143,1144,1145,1148,1149,1152,1153,1155],{},"Anything that does not use ",[514,1146,1147],{},"HTTP(S)_PROXY",", such as git over SSH or a raw socket, has no route at all. A harness whose file declares ",[514,1150,1151],{},"proxy_aware: false"," (Cursor) is refused under a network policy as a configuration error before it starts. It runs in a sandbox only with ",[514,1154,829],{}," instead.",[669,1157,1159],{"id":1158},"it-fails-closed","It fails closed",[510,1161,1162],{},"A session that cannot get its route stops as a configuration error and runs nothing. This happens when:",[764,1164,1165,1168,1175,1178],{},[767,1166,1167],{},"the socket check does not run,",[767,1169,1170,1171,1174],{},"a container cannot connect to the socket on a runtime that does not report a VM (an SELinux denial, or the permissions on ",[514,1172,1173],{},"run\u002Fsn\u002F","),",[767,1176,1177],{},"the relay image is not pulled, or",[767,1179,1180],{},"a relay does not start.",[510,1182,1183,1185,1186,1189],{},[514,1184,895],{}," fails the repository's sandbox row for the first three, naming ",[514,1187,1188],{},"docker pull \u003Crelay_image>"," for a missing image, so pull it before filing work.",[669,1191,1193],{"id":1192},"network-policy-limits","Network policy limits",[764,1195,1196,1211],{},[767,1197,1198,1202,1203],{},[1199,1200,1201],"strong",{},"Docker Desktop and Podman machine: seven days per session."," A session's client certificate expires after seven days; a session that runs longer loses its route and fails closed.\n",[764,1204,1205,1208],{},[767,1206,1207],{},"The listener keeps its port across a server restart.",[767,1209,1210],{},"If another program has taken that port by then, the listener moves to a new one, and sessions started before the restart have no route until they are retried.",[767,1212,1213,1216,1217,1220,1221,1224],{},[1199,1214,1215],{},"Domain fronting."," The allow list is enforced on the name the client asks for and on the address Kraft dials. It does not see what travels inside the TLS connection. An allowed name on a shared CDN address can reach other names that address serves, by TLS SNI or the HTTP ",[514,1218,1219],{},"Host"," header. Kraft terminates TLS only for a managed ",[519,1222,1223],{"href":357},"credential","'s host.",[669,1226,1228],{"id":1227},"related","Related",[764,1230,1231,1239,1244],{},[767,1232,1233,1235,1236,717],{},[519,1234,338],{"href":339},": the other keys of ",[514,1237,1238],{},"sandbox",[767,1240,1241,1243],{},[519,1242,356],{"href":357},": the one case where Kraft terminates TLS.",[767,1245,1246,558,1248,717],{},[519,1247,364],{"href":365},[514,1249,992],{},[1251,1252,1253],"style",{},"html pre.shiki code .sb7M8, html code.shiki .sb7M8{--shiki-light:#024C1A;--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .s7iLA, html code.shiki .s7iLA{--shiki-light:#0E1116;--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .semJd, html code.shiki .semJd{--shiki-light:#032563;--shiki-default:#032563;--shiki-dark:#ADDCFF}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);}html pre.shiki code .ssYy9, html code.shiki .ssYy9{--shiki-light:#023B95;--shiki-default:#023B95;--shiki-dark:#91CBFF}",{"title":531,"searchDepth":549,"depth":549,"links":1255},[1256,1257,1258,1259,1260,1263,1264,1265,1266,1267,1268],{"id":671,"depth":549,"text":672},{"id":817,"depth":549,"text":666},{"id":914,"depth":549,"text":915},{"id":947,"depth":549,"text":948},{"id":985,"depth":549,"text":986,"children":1261},[1262],{"id":1040,"depth":565,"text":1041},{"id":1090,"depth":549,"text":1091},{"id":1113,"depth":549,"text":1114},{"id":1140,"depth":549,"text":1141},{"id":1158,"depth":549,"text":1159},{"id":1192,"depth":549,"text":1193},{"id":1227,"depth":549,"text":1228},"How the hosts a sandboxed task may reach are listed, how Kraft enforces them, and what the policy does not cover.","md",null,{},true,{"title":352,"description":1269},"Rp8CLag7Yxt8MXWhaXZAGPgx7_IWOekw6io5KKJqEoQ",[1277,1279],{"title":348,"path":349,"stem":350,"description":1278,"children":-1},"How a sandboxed worker reaches Kraft through a network policy's channel, which verbs it has there, and what is refused without one.",{"title":356,"path":357,"stem":358,"description":1280,"children":-1},"How a sandbox's credentials keep a secret out of the container while Kraft's proxy adds it to requests, and what that cannot do.",1791801262445]