From bc7927323e34b852cf37d82495601e2bdeec0882 Mon Sep 17 00:00:00 2001 From: nilsmechtel Date: Sun, 27 Sep 2026 02:04:17 +0200 Subject: [PATCH 1/3] docs(worker): say that wildcard admin-users is open remote code execution Co-Authored-By: Claude Opus 5 (1M context) --- bioengine/worker/__main__.py | 8 ++++++-- bioengine/worker/worker.py | 21 +++++++++++++++++++ docs/deployment-guide.md | 4 +++- tests/worker/test_admin_users.py | 35 +++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/bioengine/worker/__main__.py b/bioengine/worker/__main__.py index 78219edc..e11fb015 100644 --- a/bioengine/worker/__main__.py +++ b/bioengine/worker/__main__.py @@ -110,8 +110,12 @@ def create_parser() -> argparse.ArgumentParser: type=str, nargs="+", metavar="EMAIL", - help="List of user emails/IDs with administrative privileges for worker management. " - "If not specified, defaults to the authenticated user from Hypha login.", + help="Space-separated list of user emails/IDs with administrative privileges for " + "worker management. If not specified, defaults to the authenticated user from " + "Hypha login. SECURITY: passing '*' authorizes every caller, including " + "unauthenticated anonymous ones, and the worker service is public — that grants " + "the whole internet 'run_code', i.e. arbitrary Python executed as the user " + "running this worker. Use named emails unless the host is meant to run untrusted code.", ) core_group.add_argument( "--workspace-dir", diff --git a/bioengine/worker/worker.py b/bioengine/worker/worker.py index e9f82f94..4d5b7d18 100644 --- a/bioengine/worker/worker.py +++ b/bioengine/worker/worker.py @@ -528,6 +528,25 @@ def _load_persisted_admin_users(self) -> None: ) self.admin_users[:] = persisted + def _warn_if_wildcard_admin_users(self) -> None: + """Warn that a wildcard admin list exposes ``run_code`` to anyone. + + The deployment guide says this too, but nobody reads it at roll time. + """ + if "*" not in self.admin_users: + return + + self.logger.warning( + "SECURITY: '*' is in this worker's admin users and the worker service is " + "registered with public visibility. Every caller that can reach the Hypha " + "server — including unauthenticated, anonymous ones — can therefore call " + "'run_code' and execute arbitrary Python as the operating system user " + f"running this process (uid {os.getuid()}), with this worker's filesystem, " + "credentials and Ray cluster. This is remote code execution open to the " + "internet, not merely open read access. Replace '*' with named admin " + "emails unless this host is genuinely meant to run untrusted code." + ) + def _persist_admin_users(self, admin_users: List[str]) -> None: """Write the admin users so the next restart overlays them on the seed. @@ -1335,6 +1354,8 @@ async def start(self, blocking: bool = True) -> str: # Completes initialization of AppsManager and CodeExecutor await self._connect_to_server(STARTUP_CONNECT_BUDGET_S) + self._warn_if_wildcard_admin_users() + # Check for running data server await self._discover_data_server() diff --git a/docs/deployment-guide.md b/docs/deployment-guide.md index 712912f5..1f500f91 100644 --- a/docs/deployment-guide.md +++ b/docs/deployment-guide.md @@ -93,9 +93,11 @@ apptainer exec \ | `--workspace` | auto | Hypha workspace name (auto-detected from token) | | `--server-url` | `https://hypha.aicell.io` | Hypha server URL | | `--token` | prompt | Hypha authentication token | -| `--admin-users` | current user | Comma-separated emails or `*` for all | +| `--admin-users` | current user | Space-separated emails, or `*` for all — see the warning below | | `--client-id` | auto | Unique service identifier | +> **`--admin-users '*'` is remote code execution open to the internet.** The worker's Hypha service is registered with public visibility, and a service's authorization gates invocation, not discovery. `run_code` is gated on the same admin list as every other admin operation and the wildcard is honoured there, so with `*` in the list **any caller that can reach the Hypha server — including an unauthenticated, anonymous one — can execute arbitrary Python as the operating system user running the worker**, with its filesystem, its credentials and its Ray cluster. In single-machine mode that is the host you started the worker on. The wildcard is not "skip maintaining an admin list"; it is "this machine runs untrusted code from strangers". Use named emails unless that is genuinely what you want. The worker logs a warning at startup whenever the wildcard is in effect. + The workspace directory defaults to `~/.bioengine` and is mounted into the container at `/.bioengine`. --- diff --git a/tests/worker/test_admin_users.py b/tests/worker/test_admin_users.py index 6dcd0531..b0a47586 100644 --- a/tests/worker/test_admin_users.py +++ b/tests/worker/test_admin_users.py @@ -8,6 +8,7 @@ restart, when the ``--admin-users`` startup flag is replayed verbatim. """ +import inspect import json import pytest @@ -36,11 +37,16 @@ def _bare_worker(tmp_path, admin_users, **attrs): class _Logger: def __init__(self): self.records = [] + self.warnings = [] def _record(self, message): self.records.append(str(message)) - info = warning = error = debug = _record + def warning(self, message): + self.warnings.append(str(message)) + self._record(message) + + info = error = debug = _record async def test_a_granted_admin_can_immediately_call_admin_methods(tmp_path): @@ -309,3 +315,30 @@ def __getattr__(self, name): assert registered["list_admin_users"] == worker.list_admin_users assert registered["add_admin_user"] == worker.add_admin_user assert registered["remove_admin_user"] == worker.remove_admin_user + + +async def test_a_wildcard_admin_list_warns_that_anyone_can_run_code(tmp_path): + """The wildcard reads as a permissions shortcut; it is open remote execution.""" + worker = _bare_worker(tmp_path, ["admin@example.org", "*"]) + + worker._warn_if_wildcard_admin_users() + + assert len(worker.logger.warnings) == 1 + warning = worker.logger.warnings[0] + assert "run_code" in warning + assert "anonymous" in warning + + +async def test_a_named_admin_list_does_not_warn(tmp_path): + worker = _bare_worker(tmp_path, ["admin@example.org"]) + + worker._warn_if_wildcard_admin_users() + + assert worker.logger.warnings == [] + + +def test_the_wildcard_warning_is_wired_into_startup(): + """A warning nobody calls is the same as no warning.""" + assert "_warn_if_wildcard_admin_users" in inspect.getsource( + BioEngineWorker.start + ) From 9a5fe8b84341f29d2967cd0b8defe0aade5cbdd8 Mon Sep 17 00:00:00 2001 From: nilsmechtel Date: Sun, 27 Sep 2026 02:49:27 +0200 Subject: [PATCH 2/3] test(worker): prove the wildcard warning runs at startup, not just in start() The getsource grep passed against a warning moved after the shutdown wait, where production (blocking=True) would only reach it on the way down. Drive start() instead and end it at the step after the call site. Also widen and correct the warning itself: it named only run_code, but deploy_app and upload_app are the same unqualified check, and stop_worker / stop_all_apps / delete_app hand anonymous callers destruction. The uid it printed is only the executing uid in single-machine mode. Co-Authored-By: Claude Opus 5 (1M context) --- bioengine/worker/__main__.py | 10 ++++---- bioengine/worker/worker.py | 17 ++++++++------ docs/deployment-guide.md | 14 ++++++++--- tests/worker/test_admin_users.py | 40 ++++++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/bioengine/worker/__main__.py b/bioengine/worker/__main__.py index e11fb015..127901ff 100644 --- a/bioengine/worker/__main__.py +++ b/bioengine/worker/__main__.py @@ -112,10 +112,12 @@ def create_parser() -> argparse.ArgumentParser: metavar="EMAIL", help="Space-separated list of user emails/IDs with administrative privileges for " "worker management. If not specified, defaults to the authenticated user from " - "Hypha login. SECURITY: passing '*' authorizes every caller, including " - "unauthenticated anonymous ones, and the worker service is public — that grants " - "the whole internet 'run_code', i.e. arbitrary Python executed as the user " - "running this worker. Use named emails unless the host is meant to run untrusted code.", + "Hypha login. SECURITY: passing '*' makes every caller that can reach the Hypha " + "server a full admin, including unauthenticated anonymous ones, because the " + "worker service is public. That lets anyone run arbitrary Python on this " + "deployment ('run_code', 'deploy_app', 'upload_app') and destroy it " + "('stop_worker', 'stop_all_apps'). Use named emails unless this deployment is " + "meant to run untrusted code.", ) core_group.add_argument( "--workspace-dir", diff --git a/bioengine/worker/worker.py b/bioengine/worker/worker.py index 4d5b7d18..29f4b2f8 100644 --- a/bioengine/worker/worker.py +++ b/bioengine/worker/worker.py @@ -529,7 +529,7 @@ def _load_persisted_admin_users(self) -> None: self.admin_users[:] = persisted def _warn_if_wildcard_admin_users(self) -> None: - """Warn that a wildcard admin list exposes ``run_code`` to anyone. + """Warn that a wildcard admin list exposes code execution to anyone. The deployment guide says this too, but nobody reads it at roll time. """ @@ -539,12 +539,15 @@ def _warn_if_wildcard_admin_users(self) -> None: self.logger.warning( "SECURITY: '*' is in this worker's admin users and the worker service is " "registered with public visibility. Every caller that can reach the Hypha " - "server — including unauthenticated, anonymous ones — can therefore call " - "'run_code' and execute arbitrary Python as the operating system user " - f"running this process (uid {os.getuid()}), with this worker's filesystem, " - "credentials and Ray cluster. This is remote code execution open to the " - "internet, not merely open read access. Replace '*' with named admin " - "emails unless this host is genuinely meant to run untrusted code." + "server — including unauthenticated, anonymous ones — is therefore a full " + "admin of this worker. They can run arbitrary Python on this deployment " + "via 'run_code', 'deploy_app' or 'upload_app', with whatever filesystem, " + "credentials and network access its Ray cluster is given; in " + "single-machine mode that is this host, as the user running this process. " + "They can also destroy it via 'stop_worker', 'stop_all_apps' or " + "'delete_app'. This is remote code execution open to the internet, not " + "merely open read access. Replace '*' with named admin emails unless this " + "deployment is genuinely meant to run untrusted code." ) def _persist_admin_users(self, admin_users: List[str]) -> None: diff --git a/docs/deployment-guide.md b/docs/deployment-guide.md index 1f500f91..d7f03691 100644 --- a/docs/deployment-guide.md +++ b/docs/deployment-guide.md @@ -11,6 +11,16 @@ BioEngine supports three deployment modes. The easiest way to generate deploymen --- +## Who can control the worker + +`--admin-users` takes a space-separated list of emails or user IDs and defaults to the account whose token started the worker. Admins can perform every admin operation on the worker, in every deployment mode. + +> **`--admin-users '*'` is remote code execution open to the internet.** The worker's Hypha service is registered with public visibility, and a service's authorization gates invocation, not discovery. Almost every admin operation is gated on the admin list with the wildcard honoured, so with `*` in the list **any caller that can reach the Hypha server — including an unauthenticated, anonymous one — is a full admin of your worker**. They can run arbitrary Python on the deployment through `run_code`, `deploy_app` or `upload_app`, with whatever filesystem, credentials and network access its Ray cluster is given — in single-machine mode that is the host you started the worker on, as the user who started it. They can also destroy it through `stop_worker`, `stop_all_apps` or `delete_app`. The wildcard is not "skip maintaining an admin list"; it is "this deployment runs untrusted code from strangers". Use named emails unless that is genuinely what you want. The worker logs a warning at startup whenever the wildcard is in effect. + +The one exception is editing the admin list itself: a caller who is only covered by `*` cannot call `add_admin_user` or `remove_admin_user`, so a stranger cannot make the grant permanent or lock you out. + +--- + ## Mode 1: Single Machine Runs a local Ray cluster on one machine. Good for workstations, development, and small-scale analysis. @@ -93,11 +103,9 @@ apptainer exec \ | `--workspace` | auto | Hypha workspace name (auto-detected from token) | | `--server-url` | `https://hypha.aicell.io` | Hypha server URL | | `--token` | prompt | Hypha authentication token | -| `--admin-users` | current user | Space-separated emails, or `*` for all — see the warning below | +| `--admin-users` | current user | Space-separated emails, or `*` for all — see [Who can control the worker](#who-can-control-the-worker) | | `--client-id` | auto | Unique service identifier | -> **`--admin-users '*'` is remote code execution open to the internet.** The worker's Hypha service is registered with public visibility, and a service's authorization gates invocation, not discovery. `run_code` is gated on the same admin list as every other admin operation and the wildcard is honoured there, so with `*` in the list **any caller that can reach the Hypha server — including an unauthenticated, anonymous one — can execute arbitrary Python as the operating system user running the worker**, with its filesystem, its credentials and its Ray cluster. In single-machine mode that is the host you started the worker on. The wildcard is not "skip maintaining an admin list"; it is "this machine runs untrusted code from strangers". Use named emails unless that is genuinely what you want. The worker logs a warning at startup whenever the wildcard is in effect. - The workspace directory defaults to `~/.bioengine` and is mounted into the container at `/.bioengine`. --- diff --git a/tests/worker/test_admin_users.py b/tests/worker/test_admin_users.py index b0a47586..ac80acc4 100644 --- a/tests/worker/test_admin_users.py +++ b/tests/worker/test_admin_users.py @@ -8,8 +8,9 @@ restart, when the ``--admin-users`` startup flag is replayed verbatim. """ -import inspect +import asyncio import json +from types import SimpleNamespace import pytest @@ -337,8 +338,37 @@ async def test_a_named_admin_list_does_not_warn(tmp_path): assert worker.logger.warnings == [] -def test_the_wildcard_warning_is_wired_into_startup(): - """A warning nobody calls is the same as no warning.""" - assert "_warn_if_wildcard_admin_users" in inspect.getsource( - BioEngineWorker.start +class _Reached(Exception): + """Ends a start() once the point under test has been passed.""" + + +async def test_the_wildcard_warning_is_emitted_during_startup(tmp_path): + """A warning nobody calls is the same as no warning. + + Ending start() at the step after the call site is what pins it to startup: + production runs blocking=True, so a warning placed later in start() would + not reach an operator until the worker shuts down. + """ + + async def _noop(*_args, **_kwargs): + return None + + async def _reached(*_args, **_kwargs): + raise _Reached + + worker = _bare_worker( + tmp_path, + ["admin@example.org", "*"], + heartbeat_file=tmp_path / "worker_heartbeat.json", + _shutdown_event=asyncio.Event(), + ray_cluster=SimpleNamespace(start=_noop), + _connect_to_server=_noop, + _discover_data_server=_reached, + _stop=_noop, ) + + with pytest.raises(_Reached): + await worker.start(blocking=True) + + assert len(worker.logger.warnings) == 1 + assert "run_code" in worker.logger.warnings[0] From 1ef2cdabf260070ad97e41e530f7f247f0eeced5 Mon Sep 17 00:00:00 2001 From: Nils Mechtel <49943582+nilsmechtel@users.noreply.github.com> Date: Sun, 27 Sep 2026 03:12:07 +0200 Subject: [PATCH 3/3] chore(release): bump version to 0.16.27 --- bioengine/_version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bioengine/_version.py b/bioengine/_version.py index 2c13dcad..a64a172f 100644 --- a/bioengine/_version.py +++ b/bioengine/_version.py @@ -13,4 +13,4 @@ Must stay in lock-step with ``pyproject.toml``'s ``version`` field. The ``version-check.yml`` CI workflow enforces the match. """ -__version__ = "0.16.26" +__version__ = "0.16.27" diff --git a/pyproject.toml b/pyproject.toml index 4170131e..43b101b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "bioengine" -version = "0.16.26" +version = "0.16.27" description = "BioEngine — CLI and SDK for deploying and calling AI model services on BioEngine workers" requires-python = ">=3.11" authors = [