fix: add client-side validation for shell tool allowlist network policy#2947
fix: add client-side validation for shell tool allowlist network policy#2947giulio-leone wants to merge 2 commits intoopenai:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e487c2419b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if not is_given(tools): | ||
| return omit | ||
|
|
||
| validate_tools(tools) |
There was a problem hiding this comment.
Preserve iterable tools before validating
_make_tools accepts Iterable[ParseableToolParam], but validate_tools(tools) consumes that iterable before the conversion loop runs; when callers pass a one-shot iterator (for example, a generator), the subsequent for tool in tools loop is empty and the request is sent without any tools. This is a behavior regression introduced by the validation call and can silently disable tool execution.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in c7fc0a3 — tools is now materialised to a list before validate_tools() runs, so one-shot iterators are preserved for the conversion loop.
src/openai/lib/_validation.py
Outdated
| from typing import Any, Iterable, Optional | ||
|
|
||
| _PROTOCOL_RE = re.compile(r"^https?://", re.IGNORECASE) | ||
| _PATH_RE = re.compile(r"/.") |
There was a problem hiding this comment.
Reject trailing slash in allowlist domains
The path regex r"/." fails to match domains ending in a bare slash (for example "example.com/"), so these malformed entries pass client-side validation even though they are not bare domains. In that case users still hit the opaque server error this new validation is intended to prevent.
Useful? React with 👍 / 👎.
|
Friendly ping — CI is green, tests pass, rebased on latest. Ready for review whenever convenient. Happy to address any feedback. 🙏 |
Add client-side validation for network_policy.allowed_domains to catch common configuration errors (protocol prefixes, empty lists, paths in domains) before sending the request. These mistakes currently result in opaque 500 server errors. Also adds serialization regression tests proving the library sends the correct JSON payload for shell tool allowlist configurations. Fixes openai#2920
c7fc0a3 to
e24a1a6
Compare
Summary
This is a proactive security improvement, not a bug fix — there is no linked issue. Users configuring the shell tool's
allowed_domainsnetwork policy can accidentally pass malformed entries (protocol prefixes, URL paths, empty lists) that silently produce an opaque server-side 500 error. This PR adds client-side validation to catch these mistakes early with clear error messages, and adds serialization regression tests to lock down the correct wire format.Addresses #2920 (related server-side regression context).
Changes
Client-side validation (
src/openai/lib/_validation.py) — validatesallowed_domainsentries before the request is sent. Raises a clearValueErrorfor:minItems: 1in the spec)http://example.com→ suggestsexample.com)example.com/api)Serialization regression tests (
tests/test_shell_tool_allowlist.py, 24 tests) — prove the library sends the correct JSON for:domain_secretsmaybe_transformround-tripThe validation is wired into the existing
_make_tools()helper so it runs for both sync and asyncresponses.create()calls.Why This Matters
Without this validation, users who misconfigure their shell tool allowlist get a cryptic 500 error from the API with no indication of what they did wrong. The client-side check provides an actionable error message before the request is ever sent, reducing debugging time and preventing accidental command exposure through misconfigured allowlists.
Workaround for the server-side issue
Until the API regression is resolved, users can work around it by omitting the
network_policyfield or setting it to{"type": "disabled"}.