fix(api_server): add optional ADK_API_TOKEN Bearer auth middleware#5980
Conversation
ApiServer registers /run, /run_sse, and the session CRUD routes without per-route authentication. When the server is bound to a network-reachable address with no upstream auth layer, those routes reach in-process Python code execution (UnsafeLocalCodeExecutor.execute_code) and per-user session state without any caller identity check. This change adds an ASGI middleware that is a no-op when ADK_API_TOKEN is unset (preserving the current behavior for deployments that gate access upstream) and that requires a matching Authorization: Bearer <token> header on every non-public request when ADK_API_TOKEN is set. /health and /version remain open so liveness probes do not need credentials. The middleware mirrors the shape of the existing _OriginCheckMiddleware and _DefaultAppRewriteMiddleware in the same file. The fix is the smallest opt-in path that turns the existing unauth surface into authenticated endpoints without changing any user-facing API or breaking deployments that already wire their own auth. Refs: Google bug-tracker issue 509219988 (reporter request to provide a patch alongside the report).
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Collaborator
|
Response from ADK Triaging Agent Hello @Cross-Trade-XT, thank you for creating this PR! It looks like this PR is not fully following the contribution guidelines:
This information will help reviewers to review your PR more efficiently. Thanks! |
Author
This pull request was closed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in Bearer-token authentication middleware to
ApiServer. The middleware is a no-op whenADK_API_TOKENis unset (current behavior preserved for every existing deployment) and requires a matchingAuthorization: Bearer <token>header on every non-public request whenADK_API_TOKENis set./healthand/versionremain open so liveness probes do not need credentials.Why
ApiServerregisters the following routes without per-route authentication:POST /run,POST /run_sse— invoke the agent runner, which can reach in-process Python code execution viaUnsafeLocalCodeExecutor.execute_codeif the loaded agent wires that executor.POST/GET/PUT/DELETE /apps/{app_name}/users/{user_id}/sessions/{session_id}— per-user session state CRUD, where theuser_idis taken from the URL with no caller-identity binding._register_production_endpointsand the dev-server endpoints indev_server.py.The only middleware in front today is
CORSMiddleware+_OriginCheckMiddleware+_DefaultAppRewriteMiddleware— none of which authenticate the caller. When an operator binds the server to a network-reachable address (--host 0.0.0.0, container host, LAN demo, etc.) and the deployment has no upstream auth layer, any network-reachable caller hits those routes unauthenticated.This PR provides the smallest opt-in mitigation that turns the existing unauth surface into authenticated endpoints without breaking any current deployment.
How
New
_BearerAuthMiddlewareinsrc/google/adk/cli/api_server.pymirrors the shape of the existing_OriginCheckMiddlewareand_DefaultAppRewriteMiddlewareASGI middlewares in the same file.Behavior matrix:
ADK_API_TOKENenvAuthorizationheader/healthor/versionBearer <wrong-token>Bearer <correct-token>The middleware is wired in
ApiServer.get_fast_api_app()right after_DefaultAppRewriteMiddleware. No CLI, public-API, or config-schema changes.Tests
tests/unittests/cli/test_bearer_auth_middleware.pycovers each row of the matrix above by exercising the middleware directly through the ASGI protocol (no FastAPI test client needed). Token-unset, token-set-no-header, token-set-wrong-bearer, token-set-correct-bearer, token-set-public-paths (parameterised over/health+/version), non-HTTP scopes, and session-route guard.Backward compatibility
ADK_API_TOKENis unset by default, in which case the middleware is a pass-through. Every existing deployment continues to behave exactly as before. Adopting the new behavior is a one-line environment variable change at deploy time.Reference
Filed as a patch against Google bug-tracker issue 509219988 (the reviewing team there asked for a public patch alongside the report).