Skip to main content
NVIDIA OpenShell is an open-source runtime for AI agents. Each agent runs in a sandbox with default-deny networking, a per-binary Layer 7 policy that lists the hosts, methods and paths it may use, and a gateway that keeps API keys outside the sandbox. Every connection is either allowed by a rule you can read or denied and logged. DeepInfra is a first-party provider profile in the OpenShell repository, 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 the docker group, OpenShell v0.1.1, and a DeepInfra API key from the Dashboard. Pin the OpenShell version; commands change between releases.
A gateway starts with no profiles, so the first step for any provider is to import one. Four commands give you a sandbox that can reach DeepInfra and nothing else. --from-existing reads DEEPINFRA_API_KEY from your shell into the gateway’s credential store; it is never passed into the sandbox.
The profile allows one endpoint, 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:
Now the negative test. Nothing in the effective policy names 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 also drafts a rule proposal from every blocked connection and flushes it to the gateway about ten seconds later. A draft never changes the policy by itself; it waits for you:
Approve with 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.
Chat completions still work; any other path on the same host is denied at the request layer, with the rule named in the response:
When the agent needs embeddings, add - 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
The rule mirrors the narrowed profile. With the stock profile, write 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 host docs.internal.example stands in for yours; read-only admits GET, HEAD and OPTIONS only.
deepinfra-plus-internal.yaml
The three reasons tell the story: DeepInfra is allowed, the internal name is admitted by policy and fails only because the placeholder does not resolve upstream, and 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
Add the interpreter to binaries in your exported profile and apply it:
The policy adds Hermes’s install tree read-only; include_workdir makes /workspace writable.
hermes-policy.yaml
config.yaml
Create the sandbox, upload the configuration into Hermes’s home, and ask a one-shot question:
The log is the point: Hermes reached DeepInfra through the provider rule, and everything else it tried on startup, model metadata from 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 import fails with “already exists”. Import is create-only. Export, edit and openshell profile update deepinfra -f deepinfra.yaml, keeping resource_version, or openshell profile delete deepinfra and import again. profile lint on an exported file reports the same error; update validates on its own.
  • provider create --from-existing finds no credential. DEEPINFRA_API_KEY is 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 with openshell 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’s binaries (the sandbox log names the real path OpenShell saw, for example a Python interpreter), or the log shows credential_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.
  • 404 on a path like /v1/openai/v1/chat/completions. The client appended /v1 to the base URL. Set it to exactly https://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 sets HOME to the working directory and ignores the image’s HERMES_HOME, so the file belongs at <workdir>/.hermes/config.yaml.
  • policy set is rejected with “landlock policy cannot be changed on a live sandbox”. The file changed a startup section. Start from openshell policy get <sandbox> --base and change only network_policies.
  • sandbox create fails with “not writable by the sandbox identity” or “image-declared volume masks OCI WorkingDir”. The image’s WORKDIR must 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.