Skip to content

fix(ui): allow internal users/team admins to select guardrails when creating keys#22816

Merged
ishaan-jaff merged 7 commits intomainfrom
cursor/development-environment-setup-1520
Mar 4, 2026
Merged

fix(ui): allow internal users/team admins to select guardrails when creating keys#22816
ishaan-jaff merged 7 commits intomainfrom
cursor/development-environment-setup-1520

Conversation

@ishaan-jaff
Copy link
Member

@ishaan-jaff ishaan-jaff commented Mar 4, 2026

fix(ui): allow internal users/team admins to select guardrails when creating keys

image

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem

CI (LiteLLM team)

  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🐛 Bug Fix

Changes

  • litellm/proxy/_types.py - add /guardrails/list and /v2/guardrails/list to internal_user_routes so internal users can fetch guardrails
  • networking.tsx - fetch guardrails with v2→v1 fallback
  • create_key_button.tsx - show guardrails selector for internal users / team admins (not just premium users)
  • key_edit_view.tsx - same role-based access for key editing
  • key_info_view.tsx - pass canEditGuardrails flag down
  • tests updated to cover new role-based guardrails access logic

@vercel
Copy link

vercel bot commented Mar 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Error Error Mar 4, 2026 10:50pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 4, 2026

Greptile Summary

This PR allows internal users and team admins (roles in rolesWithWriteAccess) to select guardrails when creating and editing API keys, rather than restricting this to premium users only. It adds /guardrails/list and /v2/guardrails/list to internal_user_routes in the backend, adds a v2→v1 fallback in the networking layer, and introduces a canEditGuardrails flag across the key creation/edit/info views.

  • Backend: grants INTERNAL_USER role read access to guardrails list endpoints — appropriate for key management
  • UI: introduces canEditGuardrails = premiumUser || rolesWithWriteAccess.includes(userRole) to gate guardrails and disable-global-guardrails controls
  • Networking: getGuardrailsList now tries /v2/guardrails/list first, falls back to /guardrails/list
  • Tests: good coverage for role-based guardrails access (viewer stripped, admin preserved, premium preserved)
  • Issue: The Prompts selector in both key_edit_view.tsx and create_key_button.tsx is still gated on premiumUser only, which is inconsistent — handleKeyUpdate deletes both guardrails and prompts based on the same canEditGuardrails flag, so internal users can edit guardrails but not prompts in the UI

Confidence Score: 3/5

  • PR is generally safe but has an inconsistency between guardrails and prompts permission gating that could confuse users
  • The core guardrails changes are correct and well-tested. However, the Prompts selector remains gated on premiumUser in both key_edit_view.tsx and create_key_button.tsx, while the backend guard in handleKeyUpdate deletes both guardrails and prompts based on canEditGuardrails. This means internal users will see prompts as disabled in the UI even though the backend would allow them through — creating an inconsistent experience.
  • ui/litellm-dashboard/src/components/templates/key_edit_view.tsx and ui/litellm-dashboard/src/components/organisms/create_key_button.tsx — Prompts selector still uses premiumUser instead of canEditGuardrails

Important Files Changed

Filename Overview
litellm/proxy/_types.py Adds /guardrails/list and /v2/guardrails/list to internal_user_routes, granting internal users read-only access to the guardrails list — appropriate for their key management capabilities.
ui/litellm-dashboard/src/components/networking.tsx Refactors getGuardrailsList to try the v2 endpoint first and fall back to v1 if it fails. Clean error handling with proper fallback chain.
ui/litellm-dashboard/src/components/organisms/create_key_button.tsx Introduces canEditGuardrails for guardrails/disable-global-guardrails controls. However, the Prompts and Policies selectors remain gated on premiumUser only, creating an inconsistency.
ui/litellm-dashboard/src/components/templates/key_edit_view.tsx Same canEditGuardrails pattern applied to guardrails selector and switch. Prompts selector (line 508) and PolicySelector (line 485) are still only gated on premiumUser, which is inconsistent with the guardrails changes.
ui/litellm-dashboard/src/components/templates/key_info_view.tsx Adds canEditGuardrails to guard both the handleKeyUpdate deletion logic and passes premiumUser down to KeyEditView (which re-computes the same flag). Logic is correct.
ui/litellm-dashboard/src/components/templates/KeyInfoView.handleKeyUpdate.test.tsx Good test coverage: tests role-based guardrails access for non-premium viewers (stripped), non-premium admins (preserved), and premium users (preserved). Adds a necessary mock for useResetKeySpend.
ui/litellm-dashboard/src/components/templates/key_edit_view.test.tsx Test description updated to match new behavior. Minimal change, correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User opens Key Create/Edit] --> B{Check canEditGuardrails}
    B -->|premiumUser = true| C[Guardrails enabled]
    B -->|role in rolesWithWriteAccess| C
    B -->|Neither| D[Guardrails disabled]
    C --> E[UI: Guardrails selector enabled]
    C --> F[UI: Disable global guardrails switch enabled]
    D --> G[UI: Guardrails selector disabled]
    D --> H[UI: Disable global guardrails switch disabled]
    E --> I[handleKeyUpdate]
    F --> I
    G --> I
    H --> I
    I --> J{canEditGuardrails?}
    J -->|Yes| K[Preserve guardrails & prompts in payload]
    J -->|No| L[Delete guardrails & prompts from payload]
    K --> M[API Call: keyUpdateCall]
    L --> M
    M --> N{v2/guardrails/list}
    N -->|Success| O[Return guardrails]
    N -->|Fail| P{v1/guardrails/list fallback}
    P -->|Success| O
    P -->|Fail| Q[Throw error]
Loading

Last reviewed commit: 8da9491

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 4, 2026

Additional Comments (2)

ui/litellm-dashboard/src/components/templates/key_edit_view.tsx, line 508
Prompts selector still gated on premiumUser only

The guardrails selector and the "disable global guardrails" switch both use canEditGuardrails, but the Prompts selector on line 508 still checks disabled={!premiumUser} (and the tooltip on line 504). Since handleKeyUpdate in key_info_view.tsx deletes both guardrails and prompts based on the same canEditGuardrails flag (line 144-147), an internal user/team admin would see the prompts selector as disabled in the edit view, but the backend handler would actually allow them through.

The same inconsistency exists for the PolicySelector at line 485 (disabled={!premiumUser}), though policies may intentionally remain premium-only — worth verifying.

      <Form.Item label="Prompts" name="prompts">
        <Tooltip title={!canEditGuardrails ? "Setting prompts by key is a premium feature" : ""} placement="top">
          <Select
            mode="tags"
            style={{ width: "100%" }}
            disabled={!canEditGuardrails}

ui/litellm-dashboard/src/components/organisms/create_key_button.tsx, line 1109
Prompts selector not updated to use canEditGuardrails

Same inconsistency as in key_edit_view.tsx: the Prompts selector is still gated on premiumUser rather than canEditGuardrails. Internal users/team admins will see the guardrails selector enabled but the prompts selector disabled.

                    help={
                      canEditGuardrails
                        ? "Select existing prompts or enter new ones"
                        : "Premium feature - Upgrade to set prompts by key"
                    }
                  >
                    <Select
                      mode="tags"
                      style={{ width: "100%" }}
                      disabled={!canEditGuardrails}

@ishaan-jaff ishaan-jaff merged commit 09e1a06 into main Mar 4, 2026
34 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant