Skip to content

toolserver has no authentication — add IAM check (defense-in-depth; public exposure already closed) #6

Description

@man4ish

Severity: High (defense-in-depth — public exposure already closed separately)

toolserver has no authentication anywhere in its own code. Confirmed by
grepping the whole repo for iam|jwt|auth|bearer|api.key (zero hits outside
test fixtures and an unrelated DAVID-tool SOAP "authenticate" string) and the
full git log (no auth-related commits ever). The IAM_URL: http://auth-service:8001
env var set in omnibioai-studio/docker-compose.yml is dead config — nothing
in this repo reads it.

What's exploitable without it

  • POST /register_tools accepts a tool definition with a raw http.url,
    http.method, arbitrary headers, and body_mapno domain/IP
    allowlist
    . Anyone who can reach this service can register a "tool"
    pointing at any address.
  • POST /runs executes it for real: executor.submit() makes the actual
    outbound httpx request from inside the docker network (http_tool_executor.py),
    from a position alongside docker-socket-proxy, auth-service, mysql,
    neo4j, etc.
  • GET /runs/{id}/results reads the raw response back.

Chained: an unauthenticated SSRF-as-a-service with response exfiltration,
callable by anything that can reach toolserver:9090.

Status — public exposure already closed (2026-09-01)

The internet-facing path is fixed as of tonight, tracked separately, not what
this issue is about:

  1. tools.omnibioai.org removed from /etc/cloudflared/config.yml (no
    longer tunneled to toolserver:9090 directly).
  2. nginx-router.conf's /_svc/toolserver location gated with the same
    auth_request+JWT pattern /billing and /_svc/control already use —
    deployed and verified (401 on every unauthenticated request, including
    POST /register_tools).

Full writeup: see the session report (toolserver-auth-gap-report-2026-09-01.md)
if you have access to it, or the PR/commit history around that date in
omnibioai-studio.

What's still open — this issue

Neither fix above touches same-network callers: anything else on the
docker bridge network (a compromised or misconfigured sibling container, a
future service added without thinking about this) can still hit
toolserver:9090 directly with zero auth. The docker bridge network isn't
internet-reachable on its own, so this isn't urgent the way the public
exposure was — but it's real defense-in-depth for a deployment already
running with a fair number of exposed ports and several services still on
default/shared secrets (JWT_SECRET/AUTH_SECRET_KEY defaulting to
change-me, MYSQL_ROOT_PASSWORD/NEO4J_PASSWORD defaulting to omnibioai,
etc., per omnibioai-studio/docker-compose.yml) — one weak link elsewhere on
that network is enough to reach this if it stays unauthenticated.

Proposed fix

Add a require_permission("workflow.execute") FastAPI dependency to every
route in toolserver_app.py (at minimum /register_tools, /runs,
/validate — arguably /runs/{run_id}* and /capabilities too), doing a
local JWT decode against the shared AUTH_SECRET_KEY/JWT_SECRET. This
matches the pattern already established by every sibling service:

  • omnibioai-rag/ragbio/api/iam.pyrequire_permission/_verify
  • omnibioai-control-center/backend/src/control_center/core/auth.py
    require_permission
  • omnibioai-dev-hub's api/auth.py — same shared-secret JWT check

workflow.execute is already the permission api-gateway's own
SERVICE_PERMISSION_MAP expects for toolserver (app/core/router.py), so
this closes the loop rather than inventing a new permission name — same
"gateway-level coarse gate + service-level independent, finer check" pattern
omnibioai-rag already uses.

Needs: code change + rebuild/redeploy of the toolserver image. No urgency to
rush ahead of other work, but shouldn't get lost either.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions