providers/deepinfra.yaml. With it attached, the agent’s environment holds only an opaque placeholder in DEEPINFRA_API_KEY. The gateway swaps in your real key on requests to api.deepinfra.com:443 and nowhere else, so the credential never enters the sandbox. The agent keeps the whole model catalog through the OpenAI-compatible API; the rest of the internet stays closed unless you open it.
Quick start
You need a Linux host with Docker Engine 28 or later and your user in thedocker group, OpenShell v0.1.1, and a DeepInfra API key from the Dashboard. Pin the OpenShell version; commands change between releases.
--from-existing reads DEEPINFRA_API_KEY from your shell into the gateway’s credential store; it is never passed into the sandbox.
api.deepinfra.com:443, for two client binaries, /usr/bin/curl and /usr/local/bin/curl. OpenShell’s default image has no curl, so the sandbox uses the official curlimages/curl image, and sleep infinity keeps it alive for the checks below. Run the profile’s own smoke test, the public model catalog with metadata in the curated agent order; jq runs on your host:
openshell profile lint -f deepinfra.yaml checks a profile you edited. openshell provider list-profiles and the older openshell provider profile import -f deepinfra.yaml --global spelling still work in v0.1.1. Import is create-only; to change an imported profile, export it, edit the file and run openshell profile update deepinfra -f deepinfra.yaml.Verify the boundary
Inside the sandbox,DEEPINFRA_API_KEY is a placeholder. A chat completion puts it in the Authorization header where the key would go, and the gateway resolves it on the way out because the destination is the one the profile binds the credential to:
example.com, so the sandbox refuses the connection before it leaves, and the log records both decisions with the binary and the reason (trimmed to the policy lines here; openshell logs di-smoke --tail streams it live):
openshell rule approve di-smoke --chunk-id <chunk> only when that access is intended; otherwise openshell rule reject di-smoke --chunk-id <chunk> --reason "...".
Pin the API surface
OpenShell v0.1.1 has no local inference endpoint and no model router; the managed inference route was removed before 0.1.0. The agent calls DeepInfra’s native URL,https://api.deepinfra.com/v1/openai, exactly as it would outside the sandbox. What changes is what it holds: a placeholder instead of the key, and a policy that admits only that host.
There is also no per-model allowlist. The profile does not select a model, and L7 rules inspect method, path and query string, not the JSON body where model lives. The model is whatever the agent’s configuration says. What you can pin at the gateway is the API surface. Export the profile, replace its access: read-write preset with explicit rules, and apply the update; running sandboxes reload it within about ten seconds.
- allow: { method: POST, path: /v1/openai/embeddings } to the list.
Write the sandbox policy
A sandbox enforces its effective policy: the base policy you set plus one layer per attached provider. So far the sandbox ran on OpenShell’s restrictive default with the provider layer as its only network rule. This complete base policy states the same contract explicitly,api.deepinfra.com:443 for curl and nothing else. The filesystem and landlock sections repeat what OpenShell applied at startup; a live replacement must keep them unchanged.
deepinfra-only.yaml
access: read-write in place of rules, but do not mix the two: OpenShell unions overlapping rules, so a read-write base rule would reopen the paths the profile closed. Network rules reload live:
openshell policy get di-smoke --full now lists both deepinfra_api and _provider_deepinfra; the chat completion still succeeds and example.com is still refused.
Allow one internal endpoint
The common production variant is DeepInfra plus one approved internal service, with the open internet still denied. Add a second rule to the same file and apply it again. The placeholder hostdocs.internal.example stands in for yours; read-only admits GET, HEAD and OPTIONS only.
deepinfra-plus-internal.yaml
example.com is refused by policy. An internal name that resolves to a private address works with an exact hostname; a wildcard such as *.internal.example also needs allowed_ips, see OpenShell’s network rules.
Run Hermes Agent in the sandbox
curl proves the boundary; an agent is what you run behind it. Hermes Agent has DeepInfra built in, so its configuration is two lines, and the placeholder the sandbox holds in DEEPINFRA_API_KEY is exactly what the built-in provider reads. Two image facts need handling. Hermes is Python, so the process that opens connections is the interpreter, /usr/bin/python3.13 in this image, and it must be in the profile’s binaries. And OpenShell requires the image’s working directory to be writable by the sandbox user and not an image volume, sets HOME to that directory, and does not pass the image’s environment to processes, so a two-line derivative gives Hermes a home at /workspace/.hermes:
Dockerfile
binaries in your exported profile and apply it:
include_workdir makes /workspace writable.
hermes-policy.yaml
config.yaml
models.dev, GitHub, and its optional tirith command scanner from PyPI, was denied and recorded. For an interactive session, replace sleep infinity with hermes and drop --detach.
The same pattern works for Pi: build the image from OpenShell’s Run Pi with OpenRouter tutorial, list
/usr/local/bin/node in binaries, and use the provider block from our Pi page.NemoClaw, NVIDIA’s OpenClaw, Hermes and Deep Agents stack on OpenShell, routes inference through its own managed provider and rejects a direct deepinfra provider in openclaw.json. Choose the provider during NemoClaw onboarding, as described in its provider guide, instead of importing this profile there.What you configure and what DeepInfra provides
Choosing a model
Any chat model works through the gateway; the request is an ordinary chat completion. The models below were each run through the sandbox for this guide. Context lengths come from the catalog, which is public and also carries current pricing.To compare other models, list the catalog with context windows and pricing via
/v1/openai/models?filter=with_meta&sort_by=openshell. Each entry’s metadata block has context_length, max_tokens and per-million-token pricing; the id is what you pass as model. Reasoning models spend output tokens on thinking, so give them a max_tokens well above the visible answer.Troubleshooting
profile importfails with “already exists”. Import is create-only. Export, edit andopenshell profile update deepinfra -f deepinfra.yaml, keepingresource_version, oropenshell profile delete deepinfraand import again.profile linton an exported file reports the same error;updatevalidates on its own.provider create --from-existingfinds no credential.DEEPINFRA_API_KEYis not exported in the shell running the CLI.- DeepInfra is denied like any other host. The provider is not attached:
openshell sandbox provider list <sandbox>is empty. Attach it withopenshell sandbox provider attach <sandbox> deepinfra --wait, then start a new process; a running one keeps the environment it started with. - DeepInfra returns
401. The placeholder reached DeepInfra unresolved. The calling binary is not in the profile’sbinaries(the sandbox log names the real path OpenShell saw, for example a Python interpreter), or the log showscredential_endpoint_mismatch, meaning a base-policy rule admitted a host the profile does not bind the credential to. Fix the profile, not the network rule. 404on a path like/v1/openai/v1/chat/completions. The client appended/v1to the base URL. Set it to exactlyhttps://api.deepinfra.com/v1/openai; nothing in OpenShell rewrites it.- Hermes says “Model ” isn’t available on DeepInfra”. It did not find
config.yaml. OpenShell setsHOMEto the working directory and ignores the image’sHERMES_HOME, so the file belongs at<workdir>/.hermes/config.yaml. policy setis rejected with “landlock policy cannot be changed on a live sandbox”. The file changed a startup section. Start fromopenshell policy get <sandbox> --baseand change onlynetwork_policies.sandbox createfails with “not writable by the sandbox identity” or “image-declared volume masks OCI WorkingDir”. The image’sWORKDIRmust be a plain directory writable by its user. Derive an image that sets one, as in the Hermes section.
Learn more
OpenShell documentation
Installation, providers, policies and the policy schema reference.
DeepInfra provider profile
The pull request that added
providers/deepinfra.yaml to OpenShell.NemoClaw inference providers
Choosing an inference provider in NVIDIA’s NemoClaw stack.
Sandboxes
DeepInfra’s own isolated microVMs for running agent-written code.
Tested on 2026-09-27 with OpenShell v0.1.1 (Docker driver, Docker Engine 29.8.1, Ubuntu 24.04 x86_64),
curlimages/curl:8.22.0 and nousresearch/hermes-agent:v2026.9.24 (Hermes v0.21.5). OpenShell’s CLI and policy schema are still moving; re-check this page when you upgrade.