From db40f21d9673aa878470890edb0650b979c06d0d Mon Sep 17 00:00:00 2001 From: Ryan Crabbe Date: Mon, 9 Mar 2026 14:43:08 -0700 Subject: [PATCH] fix: auto populate user id from authenticated caller preventing creation of unbound keys with no owner/budget, reject invalid team_id, block non admin users from removing user id when updating key --- .../key_management_endpoints.py | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/litellm/proxy/management_endpoints/key_management_endpoints.py b/litellm/proxy/management_endpoints/key_management_endpoints.py index 68f997e29cb..aec2c813ab3 100644 --- a/litellm/proxy/management_endpoints/key_management_endpoints.py +++ b/litellm/proxy/management_endpoints/key_management_endpoints.py @@ -1166,6 +1166,15 @@ async def generate_key_fn( verbose_proxy_logger.debug("entered /key/generate") + # Auto-populate user_id from authenticated user when not provided (non-admins only) + if data.user_id is None and user_api_key_dict.user_id is not None: + if ( + user_api_key_dict.user_role is None + or user_api_key_dict.user_role + != LitellmUserRoles.PROXY_ADMIN.value + ): + data.user_id = user_api_key_dict.user_id + # Validate budget values are not negative if data.max_budget is not None and data.max_budget < 0: raise HTTPException( @@ -1203,9 +1212,12 @@ async def generate_key_fn( parent_otel_span=user_api_key_dict.parent_otel_span, check_db_only=True, ) - except Exception as e: - verbose_proxy_logger.debug( - f"Error getting team object in `/key/generate`: {e}" + except Exception: + raise HTTPException( + status_code=404, + detail={ + "error": f"Team not found, passed team_id={data.team_id}" + }, ) key_generation_check( @@ -1873,6 +1885,19 @@ async def update_key_fn( detail=f"User={data.user_id} is not allowed to update key={key} to belong to user={existing_key_row.user_id}", ) + ## prevent non-proxy admin user from removing user_id from a key + _update_fields = data.model_dump(exclude_unset=True) + if ( + "user_id" in _update_fields + and _update_fields["user_id"] is None + and existing_key_row.user_id is not None + and user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN.value + ): + raise HTTPException( + status_code=403, + detail="Non-admin users cannot remove user_id from a key.", + ) + common_key_access_checks( user_api_key_dict=user_api_key_dict, data=data,