OpenAI publishes the Agents Python SDK. Sandbox mounts can attach
an Amazon S3 Files file system with mount -t s3files -o ….
Helper options are joined with commas. A comma in
extra_options or in mount_target_ip
becomes another -o token. Blaxel s3fs already rejected
that delimiter. S3 Files did not. The patch is in
PR 4894.
| Document | HB-AR-2026.3 / public source review, sandbox mounts |
|---|---|
| What this is | A research note and an opinion. OpenAI did not hire Hackerbane for this. |
| System | openai-agents-python, the official OpenAI Agents SDK |
| Scope | S3 Files in-container mount options joined into mount -o |
| Review commit | main @ 1d471a4 |
| Upstream | PR 4894 (open) |
| Date | 7 September 2026 |
| Author | Barney Chambers, Hackerbane |
If you have not used this SDK: it is OpenAI's library for
running agents that call tools. A sandbox session can attach
cloud storage so the agent sees files that live in S3. One
mount type is Amazon S3 Files. The helper inside the container
is mount -t s3files. Extra helper flags go in
-o, as a comma-separated list. That is how Linux
mount options work.
On main at commit 1d471a4 the SDK
built that list by joining every key and value:
rendered_options = ",".join(
key if value is None else f"{key}={value}" for key, value in options.items()
)
cmd.extend(["-o", rendered_options])
A comma already in a value is a new option. This is the same
class of miss the repo already closed for Blaxel s3fs.
test_rejects_blaxel_s3fs_endpoint_option_injection
refuses a comma in an endpoint field. S3 Files
extra_options and mount_target_ip
had no such check. Broad-credential acknowledgement still
let the comma through. That acknowledgement is about ambient
IAM, not about -o syntax.
I opened a patch. It is
PR 4894.
It reuses _value_contains_s3fs_option_delimiter
on the S3 Files fields that get joined. OpenAI did not hire
this review. The name on the cover names the project I read.
| # | ID | Action | Status on 7 Sep 2026 |
|---|---|---|---|
| 1 | MED-01 | Reject commas in S3 Files joined option fields the same way Blaxel already does. | Patch open. PR 4894. |
| 2 | INFO-01 | Linux UnixLocalSandboxClient.exec is host execution. Docs already say confinement is macOS sandbox-exec. |
On the record. Not this patch. |
This is not a full audit of the Agents SDK. I split the tree
and read the sandbox, mount, MCP, tool, and run-loop paths.
The finding I can prove with a unit test on current
main is the S3 Files option join. I did not
treat every documented trust boundary as a bug. I did not
review OpenAI's hosted agents product.
| In scope |
src/agents/sandbox/entries/mounts/patterns.py:
S3FilesMountPattern.apply.
src/agents/sandbox/_mount_security.py:
delimiter checks and
validate_manifest_mount_credential_boundaries.
Tests in tests/sandbox/test_mount_security.py.
|
|---|---|
| Out of scope | Hosted OpenAI agents. Docker and remote providers beyond the mount validator. MCP schema hardening. RunState integrity if an integrator stores it untrusted. Linux confinement design. |
| Method |
Read the code. Compare the Blaxel delimiter tests with
the S3 Files render path. Add tests that fail on
1d471a4 and pass with the patch.
|
| Retest |
uv run pytest tests/sandbox/test_mount_security.py::test_rejects_s3_files_mount_option_delimiter_injection tests/sandbox/test_mount_security.py::test_s3_files_require_broad_acknowledgement_before_ambient_iam_can_be_used tests/sandbox/test_mount_security.py::test_rejects_blaxel_s3fs_endpoint_option_injection -q
|
| ID | Severity | Title | Status |
|---|---|---|---|
| MED-01 | Medium | Comma in S3 Files options becomes extra mount -o |
Patch open (PR 4894) |
| INFO-01 | Informational | Linux UnixLocal exec is unconstrained host execution | Documented behaviour |
I called MED-01 Medium, not High, because the field is a mount option on a manifest the operator usually writes. It still matters when that manifest is assembled from more than one source: a shared template, a restored session, or an example someone else checked in. The check the repo already has for Blaxel does not run here.
src/agents/sandbox/entries/mounts/patterns.py · S3FilesMountPattern.apply
src/agents/sandbox/_mount_security.py · _configured_blaxel_s3fs_option_fields
apply copies extra_options, then
may add ro, mounttargetip,
accesspoint, and region. It joins
them with commas and passes one -o argument to
mount -t s3files. Linux treats each comma as a
new option. Blaxel s3fs already refuses a comma in the
fields it interpolates. S3 Files does not.
After acknowledging broad IAM, this manifest is accepted
on 1d471a4:
S3FilesMount(
file_system_id="fs-123",
extra_options={"mounttargetip": "10.0.0.1,ro"},
mount_strategy=InContainerMountStrategy(pattern=S3FilesMountPattern()),
)
The rendered command includes ro even though
the mount was not marked read-only. A comma in a key
("foo,ro": "1") or in
mount_target_ip does the same.
The patch walks those fields and
extra_options keys and values with the existing
delimiter helper, then uses the same
MountConfigError Blaxel already raises.
src/agents/sandbox/sandboxes/unix_local.py · _confined_exec_command
On macOS, exec is wrapped in sandbox-exec. On
Linux, _confined_exec_command returns the
command unchanged. File APIs still enforce the workspace.
Exec does not. The docs already say confinement depends on
the backend. I am not scoring that as a bug in this note.
I am recording it so a reader on Linux does not assume
macOS rules apply.
| When | What |
|---|---|
| 7 Sep 2026 |
Review commit 1d471a4. MED-01 confirmed.
Tests fail on that commit and pass with the patch.
|
| 7 Sep 2026 | Opened PR 4894. Still open when this note was written. |
To retest MED-01, run the command in section 2. Safe
extra_options={"tlsport": "4049"} must still
pass after broad-credential acknowledgement.
Read this before you treat anything above as advice.
This file is a public research note. OpenAI did not hire Hackerbane. There is no services agreement, statement of work, or client relationship behind it. The OpenAI name on the cover names the project I read. It is not a partnership badge.
What you have is an opinion about the files and commits named in section 2. It is not a certificate. It is not an endorsement of OpenAI, of the Agents SDK, or of the patch. It is not a claim that the rest of the SDK is safe, or that it is broken.
I am not telling you to merge, deploy, buy, or sell anything. This is not investment advice, legal advice, or a security guarantee. If you ship software, you own that risk. If you run the Agents SDK, you own that risk. If you load a manifest you did not write, you own that risk.
Hackerbane and I accept no liability for how anyone uses this note, for bugs it does not name, or for loss that follows from relying on it. Findings can be wrong, incomplete, or already stale the day after the review commit. Code added after that commit was not reviewed. A retest covers only the checks it names.
You may share this file. Sharing it does not create a contract and does not make the reader a client.
This note is provided as-is, as available, with all faults. To the maximum extent the law allows, Hackerbane disclaims every warranty, express or implied, including merchantability, fitness for a particular purpose, title, and non-infringement. No promise that this text is accurate, complete, or free of error, or that any error will be fixed.
Nobody may rely on this note as a professional engagement. It is not financial, tax, legal, or regulatory advice. No third party is a beneficiary of it.
| Critical | Someone could steal funds or hurt people with what I looked at. |
|---|---|
| High | The check you think you have does not work in the common case. |
| Medium | A real miss, less common in the output I care about here. |
| Low | Real, but limited, or it needs an unlikely setup. |
| Informational | On the record. Not scored as a bug. |
The coloured bars are labels. The word High or Medium is what counts.