Files
Drew Newberry 1905069948 feat(sandbox): expose services during creation (#3439)
* feat(sandbox): expose services during creation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(providers): refresh Codex credentials in gateway

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(cli): normalize create-time service URLs

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(server): roll back failed service exposure

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(example): simplify Codex provider setup

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(example): separate provider setup commands

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): harden create-time service exposure

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(example): bundle Codex provider profile

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(example): allow npm-installed Codex binary

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

---------

Signed-off-by: Drew Newberry <anewberry@nvidia.com>
2026-09-20 23:19:25 -07:00
..

Codex app server in an OpenShell sandbox

This example builds a sandbox image with Codex, runs its app server inside an OpenShell sandbox, exposes the WebSocket service through the local gateway, and connects a Codex client running on the host.

Use this example only with a local, loopback-bound OpenShell gateway. The app server does not use its own bearer-token authentication, and the exposed URL is reachable by other local processes.

Prerequisites

  • A running local OpenShell gateway backed by Docker
  • docker, openshell, the latest Codex client, and jq on the host
  • A host Codex login in $HOME/.codex/auth.json

Run the following commands from the example directory:

cd examples/codex-app-server

1. Build the image

This installs the latest published Codex version in the image. Keep the host client current as well to avoid app-server protocol incompatibilities.

docker build --pull --no-cache --tag openshell/codex-app-server:local --file Dockerfile .

2. Import the provider profile

The gateway starts with an empty provider-profile catalog. Validate and import the profile included with this example before creating the provider:

openshell provider profile lint --file codex.yaml
openshell provider profile import --file codex.yaml

3. Create the provider

These commands create a provider from the current host login, move the refresh token into gateway-only refresh material, and rotate the access token once. The sandbox receives opaque handles for only the access token and account ID; it never receives the refresh token. Run these commands once per workspace.

openshell provider create \
  --name codex \
  --type codex \
  --credential "CODEX_AUTH_ACCESS_TOKEN=$(jq -er '.tokens.access_token' "$HOME/.codex/auth.json")" \
  --credential "CODEX_AUTH_ACCOUNT_ID=$(jq -er '.tokens.account_id' "$HOME/.codex/auth.json")"
env "CODEX_AUTH_REFRESH_TOKEN=$(jq -er '.tokens.refresh_token' "$HOME/.codex/auth.json")" \
  openshell provider refresh configure codex \
    --credential-key CODEX_AUTH_ACCESS_TOKEN \
    --strategy oauth2-refresh-token \
    --material client_id=app_EMoamEEZ73f0CkXaXp7hrann \
    --secret-material-env refresh_token=CODEX_AUTH_REFRESH_TOKEN
openshell provider refresh rotate codex \
  --credential-key CODEX_AUTH_ACCESS_TOKEN

4. Launch the sandbox

openshell sandbox create \
  --name codex-app-server \
  --from openshell/codex-app-server:local \
  --expose 4500 \
  --detach \
  --no-tty \
  --provider codex \
  --output json \
  -- start-codex-app-server

The create result includes the exposed endpoint:

{
  "service_urls": {
    "": "http://default--codex-app-server.openshell.localhost:<gateway-port>/"
  }
}

Convert the returned URL to its WebSocket scheme and connect the local client, replacing <gateway-port> with the port from the create result:

codex --remote ws://default--codex-app-server.openshell.localhost:<gateway-port>/ --no-alt-screen

Clean up

openshell sandbox delete codex-app-server
openshell provider delete codex
openshell provider profile delete codex
docker image rm openshell/codex-app-server:local