OpenAI Codex / Agents SDK
Give a self-hosted Codex or Agents SDK sandbox durable memory — mount an AIStor Memory Bucket (cortex) at /workspace, the workspace the agent works in and remembers through, so apply_patch edits survive teardown.
Status - Ready
Self-serve today: a working sandbox image, mount wrapper, credential template, one-command runner, and an external agent-worker smoke live in this repo. Codex Cloud (hosted) is not supported - see the note at the end.
AIStor Memory is the memory your agents keep: one mount of a MinIO AIStor Memory
Bucket (a cortex) that the agent both works in and remembers through. In
a self-hosted Codex (or OpenAI Agents SDK) sandbox, that memory is the
workspace — mounted at the agent's working directory, where the model's
edits become durable files rather than session residue, alongside the
memory files it reads (CLAUDE.md, AGENTS.md) and the annotations it
writes under .aimem/annot/.
Codex treats apply_patch as its canonical edit primitive and expects a
writable filesystem under that directory; the cortex mount provides
it. Because the workspace lives in a durable AIStor cortex, the agent's
actual files and edits survive sandbox teardown — any later session
re-mounts the same workspace at full fidelity, byte-for-byte, not a
summary.
Recommended boundary: agent worker outside the sandbox
Newer agent runtimes keep the model loop, approvals, tracing, and model API key
in a trusted worker. Only typed shell or filesystem tool calls cross into the
execution sandbox. The sandbox owns the AIStor Memory mount and narrow storage
credentials, while the worker never opens /workspace directly.
The repository's external_worker_smoke.py validates this split. It dispatches
typed list, read, and write calls from the CI worker into a separate sandbox
and asserts that OPENAI_API_KEY is absent there. The CI workflow removes and
recreates the sandbox, then invokes the script again to read the same
AIStor Memory-backed file. Its optional Agents SDK pass uses the identical tool bridge
for a real model call without danger-full-access.
The co-located image flow below remains useful for self-hosted Codex CLI and backward compatibility. For new orchestrators, use the split worker/executor boundary and adapt the tool transport to the sandbox provider's client or MCP.
Codex Cloud (the hosted offering) is not currently supported. Its 12-hour container-snapshot lifecycle is incompatible with a live FUSE daemon.
Integration shape
- Build the checked-in example image. It extends
ghcr.io/openai/codex-universalwithaimem, the setuidaimem-fusermounthelper, Codex CLI, and Python SDK dependencies. - The entrypoint mounts the bucket at
/workspace, waits for the mount, registersOPENAI_API_KEYwith Codex CLI when present, then execs the agent command from inside the mount. - Codex CLI and the Codex SDK must select the full-access sandbox
(
--sandbox danger-full-accesson the CLI;sandbox=Sandbox.full_accessin the Python SDK;sandboxMode: "danger-full-access"in the TypeScript SDK). Codex's built-in bubblewrap (bwrap) sandbox otherwise reconstructs the workspace mount namespace and shadows the FUSE mount. See openai/codex#14794, #15505.
Quick start
The bucket must be a cortex
aimem mounts only a Memory Bucket (cortex), never a plain S3 bucket.
Before you set AIMEM_BUCKET, create the cortex launcher-side with aimem cortex create my-project --endpoint-url https://aistor.example.com (or aimem cortex convert an existing bucket). At mount time aimem requires an explicit
endpoint URL and real signing credentials (AIMEM_ACCESS_KEY /
AIMEM_SECRET_KEY — anonymous or default-chain mounts are refused), then
verifies over the Memory API that the target is a cortex and that the AIStor
server is on a paid/Enterprise tier; a plain bucket fails with 'my-project' is not a Memory Bucket (cortex). See
Prerequisites.
Use the example context instead of recreating Dockerfiles or wrapper scripts by hand:
cd examples/openai-agents-sdk
cp .env.example .env
$EDITOR .env
./run-agentFill in these .env values:
| Variable | Required | Notes |
|---|---|---|
AIMEM_BUCKET | yes | Cortex to mount at /workspace (must already be a Memory Bucket) |
AIMEM_ENDPOINT | yes | MinIO AIStor endpoint URL (Enterprise / paid tier) |
AIMEM_ACCESS_KEY | yes | AIStor Memory S3 access key |
AIMEM_SECRET_KEY | yes | AIStor Memory S3 secret key |
OPENAI_API_KEY | yes | Used by Agents SDK, Codex CLI, and SDKs |
AIMEM_SESSION_TOKEN | no | Temporary credential token, when needed |
AIMEM_AGENT | no | Agent-memory warmup profile (default codex) |
AIMEM_WORKDIR | no | Mount path inside the container (default /workspace) |
AIMEM_LOCAL | no | Staging dir for open-for-write files (default /var/cache/aimem-staging) |
AIMEM_AGENT_MODEL | no | Model agent.py uses (default gpt-5-mini) |
AIMEM_SMOKE_MODEL | no | Model the Agents SDK / Codex SDK smoke scripts use (default gpt-5-mini) |
./run-agent builds aimem-openai-agents-sdk:latest if it is missing, mounts
the bucket at AIMEM_WORKDIR (/workspace by default), and runs
python /agent.py. That demo agent writes SUMMARY.md through AIStor Memory.
If you already export the variables in your shell, skip .env; run-agent
passes them through.
Run
Agents SDK Python — default entry point (run-agent with no args runs
python /agent.py):
./run-agentCodex CLI - same mounted workspace, with the bwrap bypass:
./run-agent codex exec --sandbox danger-full-access --skip-git-repo-check \
"summarize the repo"Agents SDK smoke:
./run-agent python /agent_smoke.pyCodex SDK smoke:
./run-agent python /codex_sdk_smoke.pyImage options
Pin an AIStor Memory release, then rebuild:
AIMEM_VERSION=RELEASE.<date> AIMEM_BUILD=1 ./run-agentBuild against local binaries, offline, or an unreleased build by dropping
Linux/amd64 aimem and aimem-fusermount into bin/, then rebuilding:
AIMEM_BUILD=1 ./run-agentOverride the Codex base image or SDK pins with environment variables:
CODEX_IMAGE=my-org/codex-base:latest \
OPENAI_AGENTS_VERSION=<version> \
OPENAI_CODEX_SDK_VERSION=0.1.0b2 \
AIMEM_BUILD=1 ./run-agentOPENAI_AGENTS_VERSION=latest is a release placeholder; pin it before cutting
the public image.
SDK shape
Codex SDK (Python) — same full-access requirement as the CLI (step 3), driven from your code; point the SDK at the Codex binary already in the image:
import os
from openai_codex import Codex, CodexConfig, Sandbox
config = CodexConfig(codex_bin="/usr/local/bin/codex")
with Codex(config) as codex:
codex.login_api_key(os.environ["OPENAI_API_KEY"])
thread = codex.thread_start(
sandbox=Sandbox.full_access, # required — see Integration shape step 3
cwd="/workspace", # the AIStor Memory mount
)
result = thread.run("Diagnose the test failure and propose a fix.")
print(result.final_response)The image installs openai-codex with --no-deps because
openai-codex==0.1.0b2 pins a Codex CLI wheel that is not published for glibc
Linux. The SDK is then configured to use /usr/local/bin/codex.
The TypeScript SDK (@openai/codex-sdk) is the same shape:
import { Codex } from "@openai/codex-sdk";
const codex = new Codex();
const thread = codex.startThread({
sandboxMode: "danger-full-access",
workingDirectory: "/workspace",
});
const turn = await thread.run("Diagnose the test failure and propose a fix.");
console.log(turn.finalResponse);Both SDKs spawn the same Codex binary that the CLI uses, so the full-access requirement (Integration shape step 3) applies identically.
What the agent sees
| Path | Mode | Notes |
|---|---|---|
/workspace/ | rw | Bucket-backed workspace; atomic upload on close |
/workspace/.aimem/annot/ | rw | Per-object annotation namespace |
/var/cache/aimem-staging/ | rw | Staging dir - random writes land here first |
Teaching the agent the workspace
On every mount, AIStor Memory installs the aimem skill into $HOME
automatically — $HOME/.agents/skills/aimem/
(read by Codex CLI and the SDKs) and $HOME/.claude/skills/aimem/ — so an agent
whose reasoning runs inside the sandbox picks it up with no extra steps. Set
AIMEM_INSTALL_SKILL=0 to opt out. Instruction files (CLAUDE.md, AGENTS.md,
.cursorrules) read from the mount also carry an in-memory preamble overlay.
When the model loop runs outside the sandbox — the recommended agent-worker boundary above — that worker never sees the mount or the installed skill. Load the same skill into the worker from the public repo instead:
npx skills add minio/skills/aimemSee the SKILLS section of the AIStor Memory overview for the full three-tier model.
FUSE availability
AIStor Memory opens /dev/fuse directly and forwards the device fd to the setuid-root
aimem-fusermount helper, which performs the privileged mount(2). The host
docker daemon must allow /dev/fuse and grant CAP_SYS_ADMIN; Docker Desktop,
GitHub Actions, and most production hosts do. The agent process itself runs
unprivileged inside the container.
Reference
- The complete build context lives in
examples/openai-agents-sdk/. TODO(release): link this to the public AIStor Memory repo or release bundle. - openai/codex - the Codex CLI.
ghcr.io/openai/codex-universal- base image.
Integrations
How agent sandboxes use AIStor Memory end-to-end — OpenAI Codex / Agents SDK, GitHub Codespaces, Daytona, E2B, Vercel Sandbox, Apple container, OpenShift, OpenSandbox, OpenShell, Devin. What's ready, what's coming, and what's vendor-blocked.
GitHub Codespaces
Give a Codespace agent durable memory on MinIO AIStor — the AIStor Memory devcontainer Feature mounts your cortex into any devcontainer.json host, published on GHCR and portable across every devcontainer.json runtime.