Skip to content

Sandbox tar extraction and 12 sandbox tests fail on Windows without symlink privilege #4852

Closed

Description

@iam-kira

Running the sandbox suite on Windows as a normal, non-elevated user:

tests/sandbox/test_tar_utils.py + test_workspace_paths.py:
12 failed, 93 passed, 15 skipped
All twelve fail with OSError: [WinError 1314] A required privilege is not held by the client. Windows permits symlink creation only for an elevated process or with Developer Mode enabled — neither is the default.

They split into two distinct problems.

  1. Product: safe_extract_tarfile cannot extract archives containing symlinks
    Seven of the failures originate in library code, not test setup:

tests/sandbox/test_tar_utils.py:75: in _safe_extract
src/agents/sandbox/util/tar_utils.py:468: in safe_extract_tarfile

E   OSError: [WinError 1314] A required privilege is not held by the client:
    '/usr/local/bin/python3' -> '...\link.txt'
tar_utils.py:468:

    for member in members:
        if not member.issym():
            continue
        rel_path = safe_tar_member_rel_path(member, allow_symlinks=True)
        if rel_path is None:
            continue
        dest = root_resolved / rel_path
        _prepare_replaceable_leaf(dest=dest, rel_path=rel_path, name=member.name)
        os.symlink(member.linkname, dest)

There is no platform handling anywhere in that file. So on an ordinary Windows machine, extracting any archive that contains a symlink member raises, aborting the extraction partway — after the regular files have already been written.

Affected tests, all exercising real extraction behaviour:

test_safe_extract_tarfile_can_rehydrate_existing_leaf_symlink
test_safe_extract_tarfile_can_replace_existing_leaf_file_with_symlink
test_safe_extract_tarfile_can_replace_existing_leaf_symlink_with_file
test_safe_extract_tarfile_can_replace_existing_leaf_symlink_with_directory
test_safe_extract_tarfile_rejects_preexisting_symlink_parent
test_safe_extract_tarfile_rejects_symlink_under_preexisting_symlink_parent
(and one more in the same file)

I have deliberately not proposed a patch for this half. The sandbox has security semantics around symlinks — safe_tar_member_rel_path(..., allow_symlinks=True), escape rejection, _prepare_replaceable_leaf — and the options each carry different meaning:

Skip symlink members on Windows. Extraction completes, but the result silently differs from the archive, which may matter for a sandbox that later validates paths.
Raise a clear, typed error. Honest, but still fails the operation.
Materialise as a copy of the target. Preserves content, changes escape semantics — a copy cannot point outside the root, so some of the existing protections become moot.
Which of those is right is a maintainer decision, not one I should make from outside.

  1. Tests: unguarded symlink creation in test setup
    The other five come from the tests themselves, e.g. tests/sandbox/test_workspace_paths.py:798:

os.symlink(target, workspace / "link.txt")
Nothing guards these, and there is no module-level skip or marker.

test_normalize_path_with_symlink_resolution
test_host_io_rejects_write_under_resolved_read_only_extra_path_grant
test_host_io_rejects_extra_path_grant_symlink_to_root
test_host_path_grant_rejects_symlink_to_root
test_host_path_grant_returns_validated_resolved_source

This half is straightforward and I am happy to submit a PR: a small symlink_or_skip() helper used at the affected call sites, so the tests skip with a clear reason where the platform refuses rather than erroring. That is the same approach psf/black uses for its symlink tests.

Why CI doesn't catch either
tests-windows in .github/workflows/tests.yml runs uv run pytest — the full suite, including tests/sandbox/ — on windows-latest, and it is green. GitHub's Windows runners can create symlinks; an ordinary user cannot. So both problems are invisible to CI on the very platform it covers, and appear only on a contributor's or user's machine.

Environment
Windows-11-10.0.26200-SP0
Python 3.13.15
openai-agents-python at HEAD, uv sync dev environment
Non-elevated shell, Developer Mode off

Reproduction

git clone https://github.com/openai/openai-agents-python
cd openai-agents-python
uv sync
uv run pytest tests/sandbox/test_tar_utils.py tests/sandbox/test_workspace_paths.py

Note: a wider tests/sandbox/ run also reports failures in test_docker.py, test_docker_network_mode.py and test_mount_security.py, but those are a missing docker module in my environment and are unrelated to this report.

Activity

  1. Hughhhhcoder commented on Sep 8, 2026

    @Hughhhhcoder
    Contributor

    The test-setup half is now fixed on main by #4853 (1e5f3ae3): the five workspace-path tests use a helper that skips only Windows WinError 1314 and re-raises other symlink errors. The remaining open part of this issue is therefore the product behavior of safe_extract_tarfile() when an archive contains symlinks on a Windows host without symlink privilege; that still needs the maintainer semantic choice described above.

  2. seratch commented on Sep 20, 2026

    @seratch
    Member

    Thanks for separating the test failures from the runtime question. #4853 addressed the workspace-path test setup. As discussed in #4948, safe_extract_tarfile() is used at runtime by UnixLocal, which explicitly does not support Windows; supported Windows backends do not use that host-side extraction path.

    I'm closing this mixed-scope issue on that basis. The remaining tar-test failures on Windows without symlink privileges should be tracked separately as test portability work. This does not mean every test in the original report is fixed, and it does not add Windows support to UnixLocal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions