google / google/adk-python

`adk web --url_prefix` doesn't fix /docs and /openapi.json behind a reverse proxy

Aperta
#7,070 3 commenti 0 reazioni 1 assegnatario Rivendicata da @surajksharma07 Vedi su GitHub
request clarification web
Lingua principale
Python
Stelle
21.5k
Fork
4k
Merge medio
1g 14h
PR unite (30g)
37

Descrizione

## Description

When running `adk web` behind a reverse proxy that mounts the app under a path prefix (e.g. `https://host/agents/myagent/...`), the `--url_prefix` flag is documented as fixing exactly this case:

> Optional. URL path prefix when the application is mounted behind a reverse proxy or API gateway (e.g., '/api/v1', '/adk'). This ensures generated URLs and redirects work correctly when the app is not served at the root path.

In practice, `url_prefix` is currently only used for two things in `api_server.py`:
1. Setting `backendUrl` in the dev-ui's `runtime-config.json`.
2. Building the `/dev-ui/` redirect target.

It is never passed to the underlying `FastAPI` app as `root_path`. Since `FastAPI(lifespan=internal_lifespan)` is constructed with no `root_path`, Starlette generates `docs_url`/`openapi_url` and other reverse-generated URLs assuming the app is served at `/`.

## Repro

1. Run `adk web --url_prefix /agents/myagent ...` (or a full URL, as some deployments pass an absolute backend URL here).
2. Put the app behind a proxy that forwards `https://host/agents/myagent/*` to the pod, stripping the prefix before it reaches the app (so the app itself sees requests at `/`).
3. Visit `https://host/agents/myagent/docs`.
4. Swagger UI loads, but its embedded fetch of `/openapi.json` resolves against the bare domain root (`https://host/openapi.json`), not `https://host/agents/myagent/openapi.json` — so it 404s (or worse, hits an unrelated service sharing that domain).

## Suggested fix

Derive the FastAPI `root_path` from `url_prefix` and pass it into the `FastAPI(...)` constructor. `url_prefix` can be either a bare path or a full absolute URL (in our deployment we pass a full URL, since it's reused as the frontend's absolute `backendUrl`), so extracting just the path component via `urllib.parse.urlparse(url_prefix).path` handles both cases.

I've opened a draft PR with this fix: (link added below once created)

Happy to adjust the approach (e.g. supporting `X-Forwarded-Prefix` as a runtime alternative) if that's preferred over a startup-time flag.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.