Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.
A managed sandbox is a machine that OuterLayer starts for one build. The runner
stays on your machine. It needs no Docker, no KVM and no sandbox provider
account. It is the shortest way to a working runner on Linux or on a Mac.OuterLayer turns managed sandboxes on for an organization. Ask OuterLayer to do
this before you set up the runner.
What stays on your machine
The runner, its config file and its host key.
The agent’s credential and the repository tokens. They never enter the
sandbox.
The agent’s session. The runner keeps it and continues it on the next
job of the work item.
The sandbox has no direct network access. A build reaches the network through
the runner’s tunnel, so runner.build.allowHosts still applies.
Set up the runner
Run this command on a Linux machine, in WSL2 or on a Mac:
outerlayer runner init --sandbox
The command does not look at Docker or KVM. A machine that could run microVM
builds gets the same setup: the flag decides, not the machine.It writes this block into the config file:
Add --machine large for a larger sandbox. Small is 2 vCPU and 8 GiB of
memory. Large is 4 vCPU and 16 GiB.The rest of runner init is as it is for any runner. It asks for the runner
key and the agent’s credential, and it sets up the service. The machine still
needs the agent’s credential and 5 GB of free disk. A Linux machine or WSL2 also needs systemd. See
Set up your first host.After it writes the block, the command asks the gateway whether it provides
sandboxes to this runner. It prints one line with the answer:
The gateway provides sandboxes. Nothing more to do.
The gateway refuses for a reason that can pass. Managed sandboxes are off
for the organization. The line gives the reason. The
block stays, and the exit code is 0.
The check could not be made. The line says why. The block stays, and the
exit code is 0.
The gateway provides no sandboxes. A self-hosted gateway with no sandbox
provider settings answers this way. The command leaves no runner block,
sets up no service and exits with a code other than 0.
The build’s time in the sandbox counts as managed build-hours, at the size of
the sandbox. See
Builds in a managed sandbox.
On a Mac
A Mac can host this runner with no Docker and no Linux VM. Run the same
command:
outerlayer runner init --sandbox
The command asks no question about a Linux VM. It writes the same block, and
it keeps the runner running as a launch agent. The launch agent is the file
~/Library/LaunchAgents/ai.outerlayer.sandbox-runner.<unit name>.plist. The
default unit name is outerlayer-runner. The agent runs as you, and the
command needs no sudo.launchd starts the agent at login. It starts the runner again after a failure
and after an update. A runner that you stopped with outerlayer runner stop
stays stopped.The runner reads the agent’s credential from claude.env beside the config
file. The launch agent’s file holds no credential.Check the agent with outerlayer runner status. It prints a
launch agent line that says loaded or not loaded. To remove the agent,
run outerlayer runner uninstall --service.If launchd refuses to load the agent, as it does over SSH with no session at
the screen, the command says so and exits 0. It leaves the block and the file in
place. Run outerlayer runner install --service from a session at the Mac’s
screen to load the agent.
A build fails when the Mac sleeps. A sleeping Mac stops the runner, so the
runner stops renewing the build’s claim, and the claim runs out. Set a Mac that
hosts a runner to stay awake. OuterLayer does not do this for you.
The agent runs only while you are logged in. Set the Mac to log in at start.
Where it works
--sandbox works on Linux, WSL2 and macOS. It is refused on native Windows:
run the command in WSL2 there. It is also refused with --vm, and with a
config file that has a runnerVm block. Name another file with --config in
that case.
Limits
The sandbox ends with the build. The runner keeps no disk for the next
job on the work item, so each job clones and sets up again.
No schedule runs. A runner on managed sandboxes takes no run of a
schedule automation, because a run has no work item.
Restart the runner after you add or remove runner.sandbox.provider. A
runner that is running keeps the provider it started with.
When OuterLayer makes no sandbox for a build, the build is not failed.
The runner gives the item back, takes no work for 5 minutes, and then tries
again.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"OuterLayer","description":"An open-source software factory: issue in, reviewed and verified code out, on your agents, in your repos.","colors":{"primary":"#2065D1","light":"#4C8DEE","dark":"#1A55B8"},"logo":{"light":"https://mintcdn.com/outerlayer-stg/h46SL2WH_1X-gmFL/logo/light.svg?fit=max\u0026auto=format\u0026n=h46SL2WH_1X-gmFL\u0026q=85\u0026s=de563af4ba1bc24d13a1c4a7485a2182","dark":"https://mintcdn.com/outerlayer-stg/h46SL2WH_1X-gmFL/logo/dark.svg?fit=max\u0026auto=format\u0026n=h46SL2WH_1X-gmFL\u0026q=85\u0026s=13e7346de4086ea4a5f7e83a85e7a072"},"favicon":"https://mintcdn.com/outerlayer-stg/h46SL2WH_1X-gmFL/favicon.svg?fit=max\u0026auto=format\u0026n=h46SL2WH_1X-gmFL\u0026q=85\u0026s=adddaf2c470259ec7193c6bd26a95252","appearance":{"default":"system"},"background":{"color":{"light":"#FAFAF9","dark":"#131312"}},"navbar":{"links":[{"href":"/changelog","label":"Changelog"}],"primary":{"type":"button","label":"Open the app","href":"https://app.outerlayer.ai"}},"footer":{"socials":{"website":"https://www.outerlayer.ai"}},"fonts":{"family":"Geist"},"styling":{"codeblocks":"system","latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"outerlayer-stg","hasAudioNarration":false,"actualSubdomain":"outerlayer-stg","customDomains":["docs-stg.outerlayer.ai"],"gitSource":{"type":"github","owner":"outerlayerai","repo":"outerlayer","deployBranch":"main","contentDirectory":"apps/docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{},"buildId":"6af8d75d7fd385b08ebd76e4","clientVersion":"0.0.4143","searchFilterCounts":[{"language":"default","tag":"API reference","count":150},{"language":"default","tag":"Endpoints","count":148},{"language":"default","tag":"Documentation","count":54},{"language":"default","tag":"Work Items","count":44},{"language":"default","tag":"Apps","count":33},{"language":"default","tag":"CLI reference","count":14},{"language":"default","tag":"Work on an item","count":10},{"language":"default","tag":"Commands","count":10},{"language":"default","tag":"Org Management","count":9},{"language":"default","tag":"Run builds","count":8}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"custom.css","content":"@import url(\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600\u0026display=swap\");code,kbd,pre,samp,.font-mono{font-family:\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace}.status-icon{display:inline-block;width:1.05em;height:1.05em;margin-right:0.35em;vertical-align:-0.17em;color:#61656f}.status-icon-with_agent,.status-icon-not_picked_up{color:#b26a00}.status-icon-ready_for_review{color:#2e7d32}.status-icon-approved{color:#4f55c9}.status-icon-needs_attention{color:#c62828}.status-icon-dot{fill:#c2410c}.dark .status-icon{color:#9a9eab}.dark .status-icon-with_agent,.dark .status-icon-not_picked_up{color:#f0a742}.dark .status-icon-ready_for_review{color:#6cc070}.dark .status-icon-approved{color:#959bf2}.dark .status-icon-needs_attention{color:#f2827a}.dark .status-icon-dot{fill:#f08a4b}"}],"page":{"pagePath":"build-in-a-managed-sandbox","slug":"/build-in-a-managed-sandbox","pageMetadata":{"title":"Build in a managed sandbox","description":"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.","href":"/build-in-a-managed-sandbox"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`A managed sandbox is a machine that OuterLayer starts for one build. The runner\nstays on your machine. It needs no Docker, no KVM and no sandbox provider\naccount. It is the shortest way to a working runner on Linux or on a Mac.`}),`\n`,_jsx(_components.p,{children:`OuterLayer turns managed sandboxes on for an organization. Ask OuterLayer to do\nthis before you set up the runner.`}),`\n`,_jsx(Heading,{level:`2`,id:`what-stays-on-your-machine`,children:`What stays on your machine`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The runner,`}),` its config file and its host key.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The agent’s credential and the repository tokens.`}),` They never enter the\nsandbox.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The agent’s session.`}),` The runner keeps it and continues it on the next\njob of the work item.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The sandbox has no direct network access. A build reaches the network through\nthe runner’s tunnel, so `,_jsx(_components.code,{children:`runner.build.allowHosts`}),` still applies.`]}),`\n`,_jsx(Heading,{level:`2`,id:`set-up-the-runner`,children:`Set up the runner`}),`\n`,_jsx(_components.p,{children:`Run this command on a Linux machine, in WSL2 or on a Mac:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`outerlayer`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` runner`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` init`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --sandbox`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The command does not look at Docker or KVM. A machine that could run microVM\nbuilds gets the same setup: the flag decides, not the machine.`}),`\n`,_jsx(_components.p,{children:`It writes this block into the config file:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"runner\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"hooks\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"provision\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"builtin:sandbox\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"cleanup\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"builtin:sandbox\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"sandbox\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"provider\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"outerlayer\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"machine\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"small\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"docker\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Add `,_jsx(_components.code,{children:`--machine large`}),` for a larger sandbox. Small is 2 vCPU and 8 GiB of\nmemory. Large is 4 vCPU and 16 GiB.`]}),`\n`,_jsxs(_components.p,{children:[`The rest of `,_jsx(_components.code,{children:`runner init`}),` is as it is for any runner. It asks for the runner\nkey and the agent’s credential, and it sets up the service. The machine still\nneeds the agent’s credential and 5 GB of free disk. A Linux machine or WSL2 also needs systemd. See\n`,_jsx(_components.a,{href:`/set-up-a-host`,children:`Set up your first host`}),`.`]}),`\n`,_jsx(_components.p,{children:`After it writes the block, the command asks the gateway whether it provides\nsandboxes to this runner. It prints one line with the answer:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The gateway provides sandboxes.`}),` Nothing more to do.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The gateway refuses for a reason that can pass.`}),` Managed sandboxes are off\nfor the organization. The line gives the reason. The\nblock stays, and the exit code is 0.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The check could not be made.`}),` The line says why. The block stays, and the\nexit code is 0.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The gateway provides no sandboxes.`}),` A self-hosted gateway with no sandbox\nprovider settings answers this way. The command leaves no `,_jsx(_components.code,{children:`runner`}),` block,\nsets up no service and exits with a code other than 0.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Run `,_jsx(_components.a,{href:`/reference/cli-runner#outerlayer-runner-check`,children:_jsx(_components.code,{children:`outerlayer runner check`})}),`\nat any time to ask again.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-it-costs`,children:`What it costs`}),`\n`,_jsxs(_components.p,{children:[`The build’s time in the sandbox counts as managed build-hours, at the size of\nthe sandbox. See\n`,_jsx(_components.a,{href:`/billing-and-trials#builds-in-a-managed-sandbox`,children:`Builds in a managed sandbox`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`on-a-mac`,children:`On a Mac`}),`\n`,_jsx(_components.p,{children:`A Mac can host this runner with no Docker and no Linux VM. Run the same\ncommand:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`outerlayer`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` runner`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` init`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --sandbox`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The command asks no question about a Linux VM. It writes the same block, and\nit keeps the runner running as a launch agent. The launch agent is the file\n`,_jsx(_components.code,{children:`~/Library/LaunchAgents/ai.outerlayer.sandbox-runner.\u003cunit name>.plist`}),`. The\ndefault unit name is `,_jsx(_components.code,{children:`outerlayer-runner`}),`. The agent runs as you, and the\ncommand needs no `,_jsx(_components.code,{children:`sudo`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`launchd starts the agent at login. It starts the runner again after a failure\nand after an update. A runner that you stopped with `,_jsx(_components.code,{children:`outerlayer runner stop`}),`\nstays stopped.`]}),`\n`,_jsxs(_components.p,{children:[`The runner reads the agent’s credential from `,_jsx(_components.code,{children:`claude.env`}),` beside the config\nfile. The launch agent’s file holds no credential.`]}),`\n`,_jsxs(_components.p,{children:[`Check the agent with `,_jsx(_components.code,{children:`outerlayer runner status`}),`. It prints a\n`,_jsx(_components.code,{children:`launch agent`}),` line that says `,_jsx(_components.code,{children:`loaded`}),` or `,_jsx(_components.code,{children:`not loaded`}),`. To remove the agent,\nrun `,_jsx(_components.code,{children:`outerlayer runner uninstall --service`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`If launchd refuses to load the agent, as it does over SSH with no session at\nthe screen, the command says so and exits 0. It leaves the block and the file in\nplace. Run `,_jsx(_components.code,{children:`outerlayer runner install --service`}),` from a session at the Mac’s\nscreen to load the agent.`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`A build fails when the Mac sleeps. A sleeping Mac stops the runner, so the\nrunner stops renewing the build’s claim, and the claim runs out. Set a Mac that\nhosts a runner to stay awake. OuterLayer does not do this for you.`})}),`\n`,_jsx(_components.p,{children:`The agent runs only while you are logged in. Set the Mac to log in at start.`}),`\n`,_jsx(Heading,{level:`2`,id:`where-it-works`,children:`Where it works`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--sandbox`}),` works on Linux, WSL2 and macOS. It is refused on native Windows:\nrun the command in WSL2 there. It is also refused with `,_jsx(_components.code,{children:`--vm`}),`, and with a\nconfig file that has a `,_jsx(_components.code,{children:`runnerVm`}),` block. Name another file with `,_jsx(_components.code,{children:`--config`}),` in\nthat case.`]}),`\n`,_jsx(Heading,{level:`2`,id:`limits`,children:`Limits`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The sandbox ends with the build.`}),` The runner keeps no disk for the next\njob on the work item, so each job clones and sets up again.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`No schedule runs.`}),` A runner on managed sandboxes takes no run of a\n`,_jsx(_components.a,{href:`/schedule-automations`,children:`schedule automation`}),`, because a run has no work item.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Restart the runner`}),` after you add or remove `,_jsx(_components.code,{children:`runner.sandbox.provider`}),`. A\nrunner that is running keeps the provider it started with.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`When OuterLayer makes no sandbox for a build,`}),` the build is not failed.\nThe runner gives the item back, takes no work for 5 minutes, and then tries\nagain.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The keys of the `,_jsx(_components.code,{children:`runner.sandbox`}),` block are in the\n`,_jsx(_components.a,{href:`/reference/config-file#sandboxes-that-outerlayer-provides`,children:`config file reference`}),`.\nTo build in a sandbox from a provider account of your own, see\n`,_jsx(_components.a,{href:`/reference/config-file#a-sandbox-provider-account-of-your-own`,children:`A sandbox provider account of your own`}),`.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"Build in a managed sandbox","description":"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.","href":"/build-in-a-managed-sandbox"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What stays on your machine","slug":"what-stays-on-your-machine","depth":2,"children":[]},{"title":"Set up the runner","slug":"set-up-the-runner","depth":2,"children":[]},{"title":"What it costs","slug":"what-it-costs","depth":2,"children":[]},{"title":"On a Mac","slug":"on-a-mac","depth":2,"children":[]},{"title":"Where it works","slug":"where-it-works","depth":2,"children":[]},{"title":"Limits","slug":"limits","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"outerlayer-stg","siteName":"OuterLayer","title":"Build in a managed sandbox - OuterLayer","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-14T21:49:27.911Z","originalFileLocation":"build-in-a-managed-sandbox.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\">\u003cmeta data-mint-head name=\"application-name\" content=\"OuterLayer\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Build in a managed sandbox - OuterLayer\">\u003cmeta data-mint-head property=\"og:description\" content=\"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"OuterLayer\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://outerlayer-stg.mintlify.site/_mintlify/api/og/v2?division=Run+builds\u0026amp;title=Build+in+a+managed+sandbox\u0026amp;description=Run+a+runner+on+a+Linux+machine+or+a+Mac+with+no+Docker+and+no+KVM%2C+and+build+each+item+in+a+sandbox+that+OuterLayer+provides.\u0026amp;theme=206a5328bfa1382b45643f60\u0026amp;signature=54f35492809beaf730159ca794b4d1b5612205a650f099a4bbbaaf42ff67ef07\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Build in a managed sandbox - OuterLayer\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://outerlayer-stg.mintlify.site/_mintlify/api/og/v2?division=Run+builds\u0026amp;title=Build+in+a+managed+sandbox\u0026amp;description=Run+a+runner+on+a+Linux+machine+or+a+Mac+with+no+Docker+and+no+KVM%2C+and+build+each+item+in+a+sandbox+that+OuterLayer+provides.\u0026amp;theme=206a5328bfa1382b45643f60\u0026amp;signature=54f35492809beaf730159ca794b4d1b5612205a650f099a4bbbaaf42ff67ef07\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/outerlayer-stg/FkFLtaVKBgCUe_rr/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"OuterLayer\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2065D1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/build-in-a-managed-sandbox.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs-stg.outerlayer.ai/#organization\",\"name\":\"OuterLayer\",\"url\":\"https://docs-stg.outerlayer.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/outerlayer-stg/h46SL2WH_1X-gmFL/logo/light.svg?fit=max\u0026auto=format\u0026n=h46SL2WH_1X-gmFL\u0026q=85\u0026s=de563af4ba1bc24d13a1c4a7485a2182\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs-stg.outerlayer.ai#website\",\"name\":\"OuterLayer\",\"url\":\"https://docs-stg.outerlayer.ai\",\"publisher\":{\"@id\":\"https://docs-stg.outerlayer.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox#webpage\",\"url\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox\",\"name\":\"Build in a managed sandbox\",\"description\":\"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\",\"dateModified\":\"2026-11-14T21:49:27.911Z\",\"isPartOf\":{\"@id\":\"https://docs-stg.outerlayer.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Run builds\",\"item\":\"https://docs-stg.outerlayer.ai/run-work-on-your-machines\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build in a managed sandbox\",\"item\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox#article\",\"headline\":\"Build in a managed sandbox\",\"name\":\"Build in a managed sandbox\",\"description\":\"Run a runner on a Linux machine or a Mac with no Docker and no KVM, and build each item in a sandbox that OuterLayer provides.\",\"url\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox\",\"mainEntityOfPage\":{\"@id\":\"https://docs-stg.outerlayer.ai/build-in-a-managed-sandbox#webpage\"},\"dateModified\":\"2026-11-14T21:49:27.911Z\",\"publisher\":{\"@id\":\"https://docs-stg.outerlayer.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs-stg.outerlayer.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"OuterLayer\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"OuterLayer\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/build-in-a-managed-sandbox.md","siteName":"OuterLayer","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get started","pages":[{"title":"What OuterLayer is","href":""},{"title":"Quickstart","href":"/quickstart"},{"title":"Key concepts","href":"/concepts"}]},{"group":"Set up your factory","pages":[{"title":"Connect a repository","href":"/connect-repository"},{"title":"Connect an issue tracker","href":"/connect-a-tracker"},{"title":"Invite your team","href":"/invite-your-team"},{"title":"Roles and permissions","href":"/roles-and-permissions"},{"title":"Single sign-on","href":"/single-sign-on"},{"title":"Billing and trials","href":"/billing-and-trials"}]},{"group":"Keys and integrations","pages":[{"title":"API keys","href":"/api-keys"},{"title":"Use the MCP server","href":"/use-the-mcp-server"}]},{"group":"Work on an item","pages":[{"title":"The Work page","href":"/the-work-page"},{"title":"Write a spec with /spec","href":"/write-a-spec"},{"title":"Draft a spec on a work item","href":"/draft-a-spec"},{"title":"Review and merge","href":"/review-the-work"},{"title":"Review on GitHub","href":"/review-on-github"},{"title":"Code review","href":"/code-review"},{"title":"Prove the work","href":"/attach-evidence"},{"title":"Record a demo","href":"/record-a-demo"},{"title":"Findings","href":"/findings"},{"title":"Cost and throughput","href":"/cost-and-throughput"}]},{"group":"Automate","pages":[{"title":"Automations","href":"/automations"},{"title":"Webhook automations","href":"/webhook-automations"},{"title":"Schedule automations","href":"/schedule-automations"}]},{"group":"Configure a repository","pages":[{"title":"Set up agent instructions and skills","href":"/agent-context"},{"title":"Starter skills and the build","href":"/starter-skills"},{"title":"Policy and validators","href":"/policy-and-validators"},{"title":"Write a validator file","href":"/write-a-validator"},{"title":"Share instructions across repositories","href":"/share-instructions-across-repositories"}]},{"group":"Run builds","pages":[{"title":"Run work on your machines","href":"/run-work-on-your-machines"},{"title":"Set up your first host","description":"Install the runner on one Linux machine, give it its key and Claude's credential, and build your first item.","href":"/set-up-a-host"},{"title":"Build in a managed sandbox","href":"/build-in-a-managed-sandbox"},{"title":"Run the runner in a container","description":"Start the runner from the published image with one docker run, keep it running with Docker's restart policy, and operate it.","href":"/run-the-runner-in-a-container"},{"title":"Run the runner on a Mac","href":"/run-builds-on-macos"},{"title":"Run the runner on Windows","href":"/run-builds-on-windows"},{"title":"Run the runner as a service","href":"/run-a-host-as-a-service"},{"title":"Update a runner","href":"/update-a-runner"}]},{"group":"Prepare the build environment","pages":[{"title":"What a build gets","href":"/container-builds"},{"title":"Build a repository's image from its devcontainer file","href":"/build-image-from-devcontainer"},{"title":"Prepare builds with a setup script","href":"/build-setup"},{"title":"Destinations and secrets","href":"/destinations-and-secrets"},{"title":"Write your own hooks","href":"/write-your-own-hooks"}]},{"group":"Security and privacy","pages":[{"title":"Security and privacy","href":"/security-and-privacy"},{"title":"What leaves your machine","href":"/what-leaves-your-machine"},{"title":"Dashboard analytics and error reports","href":"/usage-analytics"},{"title":"Build isolation and limits","href":"/build-security"},{"title":"Platform admin access","href":"/platform-admin-access"},{"title":"GitHub App permissions and build tokens","href":"/github-app-and-build-tokens"}]},{"group":"Troubleshoot and upgrade","pages":[{"title":"Troubleshoot the CLI","href":"/troubleshooting"},{"title":"Troubleshoot builds","href":"/troubleshoot-builds"},{"title":"Debug a build in your own session","href":"/launch-a-session"},{"title":"Upgrade OuterLayer","href":"/upgrade"}]},{"group":"Self-host","hidden":true,"searchable":true,"pages":[{"title":"Self-host OuterLayer","href":"/self-host/index"}]},{"group":"Changelog","hidden":true,"searchable":true,"pages":[{"title":"Changelog","href":"/changelog"}]}]},{"tab":"CLI reference","pages":[{"title":"CLI reference","href":"/reference/cli"}]},{"tab":"API reference","pages":[{"title":"API reference","href":"/api-reference/introduction"}]}]},"basePath":"","title":"Build in a managed sandbox - OuterLayer","buildId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","deploymentId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","dynamics":[],"chunks":[]}