mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-14 01:07:15 +00:00
Permission Management - disable global guardrails by key/team (#16983)
* feat(teams.py): param for disabling guardrails by team allows use-case where you don't run global guardrails for team - only run team-specific guardrails * feat(custom_guardrail.py): add support for disabling global guardrails only run guardrails requested for in the request/key/team * feat: support adding disable_global_guardrails to metadata if present in key/team metadata * feat(create_key_button.tsx): new disable global guardrails field * feat(key_edit_view.tsx): support disabling global guardrails on key edit * feat(teams.tsx): add disable global guardrails on create team on UI * feat(team_info.tsx): allow disabling global guardrails on team update
This commit is contained in:
@@ -11,9 +11,7 @@ from litellm.types.guardrails import (
|
||||
Mode,
|
||||
PiiEntityType,
|
||||
)
|
||||
from litellm.types.llms.openai import (
|
||||
AllMessageValues,
|
||||
)
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
from litellm.types.proxy.guardrails.guardrail_hooks.base import GuardrailConfigModel
|
||||
from litellm.types.utils import (
|
||||
CallTypes,
|
||||
@@ -136,6 +134,17 @@ class CustomGuardrail(CustomLogger):
|
||||
f"Event hook {event_hook} is not in the supported event hooks {supported_event_hooks}"
|
||||
)
|
||||
|
||||
def get_disable_global_guardrail(self, data: dict) -> Optional[bool]:
|
||||
"""
|
||||
Returns True if the global guardrail should be disabled
|
||||
"""
|
||||
if "disable_global_guardrail" in data:
|
||||
return data["disable_global_guardrail"]
|
||||
metadata = data.get("litellm_metadata") or data.get("metadata", {})
|
||||
if "disable_global_guardrail" in metadata:
|
||||
return metadata["disable_global_guardrail"]
|
||||
return False
|
||||
|
||||
def get_guardrail_from_metadata(
|
||||
self, data: dict
|
||||
) -> Union[List[str], List[Dict[str, DynamicGuardrailParams]]]:
|
||||
@@ -252,6 +261,7 @@ class CustomGuardrail(CustomLogger):
|
||||
Returns True if the guardrail should be run on the event_type
|
||||
"""
|
||||
requested_guardrails = self.get_guardrail_from_metadata(data)
|
||||
disable_global_guardrail = self.get_disable_global_guardrail(data)
|
||||
verbose_logger.debug(
|
||||
"inside should_run_guardrail for guardrail=%s event_type= %s guardrail_supported_event_hooks= %s requested_guardrails= %s self.default_on= %s",
|
||||
self.guardrail_name,
|
||||
@@ -260,7 +270,7 @@ class CustomGuardrail(CustomLogger):
|
||||
requested_guardrails,
|
||||
self.default_on,
|
||||
)
|
||||
if self.default_on is True:
|
||||
if self.default_on is True and disable_global_guardrail is not True:
|
||||
if self._event_hook_is_event_type(event_type):
|
||||
if isinstance(self.event_hook, Mode):
|
||||
try:
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -812,6 +812,7 @@ class KeyRequestBase(GenerateRequestBase):
|
||||
key: Optional[str] = None
|
||||
budget_id: Optional[str] = None
|
||||
tags: Optional[List[str]] = None
|
||||
disable_global_guardrails: Optional[bool] = None
|
||||
enforced_params: Optional[List[str]] = None
|
||||
allowed_routes: Optional[list] = []
|
||||
allowed_passthrough_routes: Optional[list] = None
|
||||
@@ -1357,6 +1358,7 @@ class NewTeamRequest(TeamBase):
|
||||
prompts: Optional[List[str]] = None
|
||||
object_permission: Optional[LiteLLM_ObjectPermissionBase] = None
|
||||
allowed_passthrough_routes: Optional[list] = None
|
||||
disable_global_guardrails: Optional[bool] = None
|
||||
model_rpm_limit: Optional[Dict[str, int]] = None
|
||||
rpm_limit_type: Optional[
|
||||
Literal["guaranteed_throughput", "best_effort_throughput"]
|
||||
@@ -1418,6 +1420,7 @@ class UpdateTeamRequest(LiteLLMPydanticObjectBase):
|
||||
model_aliases: Optional[dict] = None
|
||||
guardrails: Optional[List[str]] = None
|
||||
object_permission: Optional[LiteLLM_ObjectPermissionBase] = None
|
||||
disable_global_guardrails: Optional[bool] = None
|
||||
team_member_budget: Optional[float] = None
|
||||
team_member_rpm_limit: Optional[int] = None
|
||||
team_member_tpm_limit: Optional[int] = None
|
||||
@@ -3257,6 +3260,7 @@ LiteLLM_ManagementEndpoint_MetadataFields = [
|
||||
]
|
||||
|
||||
LiteLLM_ManagementEndpoint_MetadataFields_Premium = [
|
||||
"disable_global_guardrails",
|
||||
"guardrails",
|
||||
"tags",
|
||||
"team_member_key_duration",
|
||||
|
||||
@@ -585,7 +585,6 @@ class LiteLLMProxyRequestSetup:
|
||||
if user_api_key_dict.budget_reset_at
|
||||
else None
|
||||
),
|
||||
|
||||
user_api_key_auth_metadata=user_api_key_dict.metadata,
|
||||
)
|
||||
return user_api_key_logged_metadata
|
||||
@@ -668,6 +667,12 @@ class LiteLLMProxyRequestSetup:
|
||||
tags_to_add=key_metadata["tags"],
|
||||
)
|
||||
)
|
||||
if "disable_global_guardrails" in key_metadata and isinstance(
|
||||
key_metadata["disable_global_guardrails"], bool
|
||||
):
|
||||
data[_metadata_variable_name]["disable_global_guardrails"] = key_metadata[
|
||||
"disable_global_guardrails"
|
||||
]
|
||||
if "spend_logs_metadata" in key_metadata and isinstance(
|
||||
key_metadata["spend_logs_metadata"], dict
|
||||
):
|
||||
@@ -936,6 +941,12 @@ async def add_litellm_data_to_request( # noqa: PLR0915
|
||||
request_tags=data[_metadata_variable_name].get("tags"),
|
||||
tags_to_add=team_metadata["tags"],
|
||||
)
|
||||
if "disable_global_guardrails" in team_metadata and isinstance(
|
||||
team_metadata["disable_global_guardrails"], bool
|
||||
):
|
||||
data[_metadata_variable_name]["disable_global_guardrails"] = team_metadata[
|
||||
"disable_global_guardrails"
|
||||
]
|
||||
if "spend_logs_metadata" in team_metadata and isinstance(
|
||||
team_metadata["spend_logs_metadata"], dict
|
||||
):
|
||||
@@ -1240,7 +1251,7 @@ def _add_guardrails_from_key_or_team_metadata(
|
||||
) -> None:
|
||||
"""
|
||||
Helper add guardrails from key or team metadata to request data
|
||||
|
||||
|
||||
Key guardrails are set first, then team guardrails are appended (without duplicates).
|
||||
|
||||
Args:
|
||||
@@ -1254,19 +1265,25 @@ def _add_guardrails_from_key_or_team_metadata(
|
||||
|
||||
# Initialize guardrails set (avoiding duplicates)
|
||||
combined_guardrails = set()
|
||||
|
||||
|
||||
# Add key-level guardrails first
|
||||
if key_metadata and "guardrails" in key_metadata:
|
||||
if isinstance(key_metadata["guardrails"], list) and len(key_metadata["guardrails"]) > 0:
|
||||
if (
|
||||
isinstance(key_metadata["guardrails"], list)
|
||||
and len(key_metadata["guardrails"]) > 0
|
||||
):
|
||||
_premium_user_check()
|
||||
combined_guardrails.update(key_metadata["guardrails"])
|
||||
|
||||
|
||||
# Add team-level guardrails (set automatically handles duplicates)
|
||||
if team_metadata and "guardrails" in team_metadata:
|
||||
if isinstance(team_metadata["guardrails"], list) and len(team_metadata["guardrails"]) > 0:
|
||||
if (
|
||||
isinstance(team_metadata["guardrails"], list)
|
||||
and len(team_metadata["guardrails"]) > 0
|
||||
):
|
||||
_premium_user_check()
|
||||
combined_guardrails.update(team_metadata["guardrails"])
|
||||
|
||||
|
||||
# Set combined guardrails in metadata as list
|
||||
if combined_guardrails:
|
||||
data[metadata_variable_name]["guardrails"] = list(combined_guardrails)
|
||||
@@ -1292,23 +1309,32 @@ def move_guardrails_to_metadata(
|
||||
)
|
||||
|
||||
#########################################################################################
|
||||
# User's might send "guardrails" in the request body, we need to add them to the request metadata.
|
||||
# User's might send "guardrails" in the request body, we need to add them to the request metadata.
|
||||
# Since downstream logic requires "guardrails" to be in the request metadata
|
||||
#########################################################################################
|
||||
if "guardrails" in data:
|
||||
request_body_guardrails = data.pop("guardrails")
|
||||
if "guardrails" in data[_metadata_variable_name] and isinstance(data[_metadata_variable_name]["guardrails"], list):
|
||||
if "guardrails" in data[_metadata_variable_name] and isinstance(
|
||||
data[_metadata_variable_name]["guardrails"], list
|
||||
):
|
||||
data[_metadata_variable_name]["guardrails"].extend(request_body_guardrails)
|
||||
else:
|
||||
data[_metadata_variable_name]["guardrails"] = request_body_guardrails
|
||||
|
||||
|
||||
#########################################################################################
|
||||
if "guardrail_config" in data:
|
||||
request_body_guardrail_config = data.pop("guardrail_config")
|
||||
if "guardrail_config" in data[_metadata_variable_name] and isinstance(data[_metadata_variable_name]["guardrail_config"], dict):
|
||||
data[_metadata_variable_name]["guardrail_config"].update(request_body_guardrail_config)
|
||||
if "guardrail_config" in data[_metadata_variable_name] and isinstance(
|
||||
data[_metadata_variable_name]["guardrail_config"], dict
|
||||
):
|
||||
data[_metadata_variable_name]["guardrail_config"].update(
|
||||
request_body_guardrail_config
|
||||
)
|
||||
else:
|
||||
data[_metadata_variable_name]["guardrail_config"] = request_body_guardrail_config
|
||||
data[_metadata_variable_name][
|
||||
"guardrail_config"
|
||||
] = request_body_guardrail_config
|
||||
|
||||
|
||||
def add_provider_specific_headers_to_request(
|
||||
data: dict,
|
||||
|
||||
@@ -688,8 +688,7 @@ async def new_team( # noqa: PLR0915
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
if (data.max_budget is not None and user_api_key_dict.user_id is not None):
|
||||
if data.max_budget is not None and user_api_key_dict.user_id is not None:
|
||||
# Fetch user object to get max_budget
|
||||
user_obj = await get_user_object(
|
||||
user_id=user_api_key_dict.user_id,
|
||||
@@ -699,7 +698,7 @@ async def new_team( # noqa: PLR0915
|
||||
)
|
||||
|
||||
if (
|
||||
user_obj is not None
|
||||
user_obj is not None
|
||||
and user_obj.max_budget is not None
|
||||
and data.max_budget > user_obj.max_budget
|
||||
):
|
||||
|
||||
@@ -171,6 +171,79 @@ class TestCustomGuardrailShouldRunGuardrail:
|
||||
|
||||
assert result is False
|
||||
|
||||
def test_should_run_guardrail_with_disable_global_guardrail(self):
|
||||
"""Test that disable_global_guardrail disables a global guardrail when set to True"""
|
||||
from litellm.types.guardrails import GuardrailEventHooks
|
||||
|
||||
# Create a guardrail with default_on=True (global guardrail)
|
||||
custom_guardrail = CustomGuardrail(
|
||||
guardrail_name="global_guardrail",
|
||||
default_on=True,
|
||||
event_hook=GuardrailEventHooks.pre_call,
|
||||
)
|
||||
|
||||
# Test 1: Global guardrail runs by default when default_on=True
|
||||
data = {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
}
|
||||
result = custom_guardrail.should_run_guardrail(
|
||||
data=data, event_type=GuardrailEventHooks.pre_call
|
||||
)
|
||||
assert result is True, "Global guardrail should run when default_on=True"
|
||||
|
||||
# Test 2: Global guardrail is disabled when disable_global_guardrail=True at root level
|
||||
data_with_disable_root = {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
"disable_global_guardrail": True,
|
||||
}
|
||||
result = custom_guardrail.should_run_guardrail(
|
||||
data=data_with_disable_root, event_type=GuardrailEventHooks.pre_call
|
||||
)
|
||||
assert (
|
||||
result is False
|
||||
), "Global guardrail should be disabled when disable_global_guardrail=True"
|
||||
|
||||
# Test 3: Global guardrail is disabled when disable_global_guardrail=True in litellm_metadata
|
||||
data_with_disable_litellm = {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
"litellm_metadata": {"disable_global_guardrail": True},
|
||||
}
|
||||
result = custom_guardrail.should_run_guardrail(
|
||||
data=data_with_disable_litellm, event_type=GuardrailEventHooks.pre_call
|
||||
)
|
||||
assert (
|
||||
result is False
|
||||
), "Global guardrail should be disabled when disable_global_guardrail=True in litellm_metadata"
|
||||
|
||||
# Test 4: Global guardrail is disabled when disable_global_guardrail=True in metadata
|
||||
data_with_disable_metadata = {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
"metadata": {"disable_global_guardrail": True},
|
||||
}
|
||||
result = custom_guardrail.should_run_guardrail(
|
||||
data=data_with_disable_metadata, event_type=GuardrailEventHooks.pre_call
|
||||
)
|
||||
assert (
|
||||
result is False
|
||||
), "Global guardrail should be disabled when disable_global_guardrail=True in metadata"
|
||||
|
||||
# Test 5: Global guardrail runs when disable_global_guardrail=False
|
||||
data_with_disable_false = {
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
"disable_global_guardrail": False,
|
||||
}
|
||||
result = custom_guardrail.should_run_guardrail(
|
||||
data=data_with_disable_false, event_type=GuardrailEventHooks.pre_call
|
||||
)
|
||||
assert (
|
||||
result is True
|
||||
), "Global guardrail should still run when disable_global_guardrail=False"
|
||||
|
||||
|
||||
class TestApplyGuardrailCheck:
|
||||
def test_apply_guardrail_check_only_on_direct_implementation(self):
|
||||
@@ -304,7 +377,9 @@ class TestGuardrailLoggingAggregation:
|
||||
|
||||
self._invoke_add_log(request_data)
|
||||
|
||||
info = request_data["litellm_metadata"]["standard_logging_guardrail_information"]
|
||||
info = request_data["litellm_metadata"][
|
||||
"standard_logging_guardrail_information"
|
||||
]
|
||||
assert isinstance(info, list)
|
||||
assert len(info) == 2
|
||||
assert info[1]["guardrail_name"] == "test_guardrail"
|
||||
|
||||
+20
-1
@@ -1,4 +1,4 @@
|
||||
import { Button as Button2, Form, Input, Modal, Select as Select2, Tooltip } from "antd";
|
||||
import { Button as Button2, Form, Input, Modal, Select as Select2, Switch, Tooltip } from "antd";
|
||||
import { Accordion, AccordionBody, AccordionHeader, Text, TextInput } from "@tremor/react";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import {
|
||||
@@ -452,6 +452,25 @@ const CreateTeamModal = ({
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Disable Global Guardrails{" "}
|
||||
<Tooltip title="When enabled, this team will bypass any guardrails configured to run on every request (global guardrails)">
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="disable_global_guardrails"
|
||||
className="mt-4"
|
||||
valuePropName="checked"
|
||||
help="Bypass global guardrails for this team"
|
||||
>
|
||||
<Switch
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@tremor/react";
|
||||
import { Button as Button2, Form, Input, Modal, Select as Select2, Tooltip, Typography } from "antd";
|
||||
import { Button as Button2, Form, Input, Modal, Select as Select2, Switch, Tooltip, Typography } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { formatNumberWithCommas } from "../utils/dataUtils";
|
||||
import { fetchTeams } from "./common_components/fetch_teams";
|
||||
@@ -1262,6 +1262,26 @@ const Teams: React.FC<TeamProps> = ({
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Disable Global Guardrails{" "}
|
||||
<Tooltip title="When enabled, this team will bypass any guardrails configured to run on every request (global guardrails)">
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="disable_global_guardrails"
|
||||
className="mt-4"
|
||||
valuePropName="checked"
|
||||
help="Bypass global guardrails for this team"
|
||||
>
|
||||
<Switch
|
||||
disabled={!premiumUser}
|
||||
checkedChildren={premiumUser ? "Yes" : "Premium feature - Upgrade to disable global guardrails by team"}
|
||||
unCheckedChildren={premiumUser ? "No" : "Premium feature - Upgrade to disable global guardrails by team"}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { useState, useEffect, useCallback } from "react";
|
||||
import { Button, TextInput, Grid, Col } from "@tremor/react";
|
||||
import { Text, Title, Accordion, AccordionHeader, AccordionBody } from "@tremor/react";
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
||||
import { Button as Button2, Modal, Form, Input, Select, Radio } from "antd";
|
||||
import { Button as Button2, Modal, Form, Input, Select, Radio, Switch } from "antd";
|
||||
import NumericalInput from "../shared/numerical_input";
|
||||
import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key";
|
||||
import SchemaFormFields from "../common_components/check_openapi_schema";
|
||||
@@ -879,6 +879,37 @@ const CreateKey: React.FC<CreateKeyProps> = ({
|
||||
options={guardrailsList.map((name) => ({ value: name, label: name }))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Disable Global Guardrails{" "}
|
||||
<Tooltip title="When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)">
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/proxy/guardrails/quick_start"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()} // Prevent accordion from collapsing when clicking link
|
||||
>
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</a>
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="disable_global_guardrails"
|
||||
className="mt-4"
|
||||
valuePropName="checked"
|
||||
help={
|
||||
premiumUser
|
||||
? "Bypass global guardrails for this key"
|
||||
: "Premium feature - Upgrade to disable global guardrails by key"
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
disabled={!premiumUser}
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
teamUpdateCall,
|
||||
getGuardrailsList,
|
||||
} from "@/components/networking";
|
||||
import { Button, Form, Input, Select, message, Modal, Tooltip } from "antd";
|
||||
import { Button, Form, Input, Select, Switch, message, Modal, Tooltip } from "antd";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { ArrowLeftIcon } from "@heroicons/react/outline";
|
||||
import MemberModal from "./edit_membership";
|
||||
@@ -558,6 +558,7 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
||||
team_member_tpm_limit: info.team_member_budget_table?.tpm_limit,
|
||||
team_member_rpm_limit: info.team_member_budget_table?.rpm_limit,
|
||||
guardrails: info.metadata?.guardrails || [],
|
||||
disable_global_guardrails: info.metadata?.disable_global_guardrails || false,
|
||||
metadata: info.metadata
|
||||
? JSON.stringify((({ logging, ...rest }) => rest)(info.metadata), null, 2)
|
||||
: "",
|
||||
@@ -673,6 +674,25 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Disable Global Guardrails{" "}
|
||||
<Tooltip title="When enabled, this team will bypass any guardrails configured to run on every request (global guardrails)">
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="disable_global_guardrails"
|
||||
valuePropName="checked"
|
||||
help="Bypass global guardrails for this team"
|
||||
>
|
||||
<Switch
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Vector Stores" name="vector_stores">
|
||||
<VectorStoreSelector
|
||||
onChange={(values: string[]) => form.setFieldValue("vector_stores", values)}
|
||||
@@ -806,6 +826,17 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
||||
<Badge color={info.blocked ? "red" : "green"}>{info.blocked ? "Blocked" : "Active"}</Badge>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Disable Global Guardrails</Text>
|
||||
<div>
|
||||
{info.metadata?.disable_global_guardrails === true ? (
|
||||
<Badge color="yellow">Enabled - Global guardrails bypassed</Badge>
|
||||
) : (
|
||||
<Badge color="green">Disabled - Global guardrails active</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ObjectPermissionsView
|
||||
objectPermission={info.object_permission}
|
||||
variant="inline"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import GuardrailSelector from "@/components/guardrails/GuardrailSelector";
|
||||
import { TextInput, Button as TremorButton } from "@tremor/react";
|
||||
import { Form, Input, Select, Tooltip } from "antd";
|
||||
import { Form, Input, Select, Switch, Tooltip } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { mapInternalToDisplayNames } from "../callback_info_helpers";
|
||||
import KeyLifecycleSettings from "../common_components/KeyLifecycleSettings";
|
||||
@@ -17,6 +17,7 @@ import NumericalInput from "../shared/numerical_input";
|
||||
import { Tag } from "../tag_management/types";
|
||||
import EditLoggingSettings from "../team/EditLoggingSettings";
|
||||
import VectorStoreSelector from "../vector_store_management/VectorStoreSelector";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
|
||||
interface KeyEditViewProps {
|
||||
keyData: KeyResponse;
|
||||
@@ -164,6 +165,7 @@ export function KeyEditView({
|
||||
budget_duration: getBudgetDuration(keyData.budget_duration),
|
||||
metadata: formatMetadataForDisplay(stripTagsFromMetadata(keyData.metadata)),
|
||||
guardrails: keyData.metadata?.guardrails,
|
||||
disable_global_guardrails: keyData.metadata?.disable_global_guardrails || false,
|
||||
prompts: keyData.metadata?.prompts,
|
||||
tags: keyData.metadata?.tags,
|
||||
vector_stores: keyData.object_permission?.vector_stores || [],
|
||||
@@ -188,6 +190,7 @@ export function KeyEditView({
|
||||
budget_duration: getBudgetDuration(keyData.budget_duration),
|
||||
metadata: formatMetadataForDisplay(stripTagsFromMetadata(keyData.metadata)),
|
||||
guardrails: keyData.metadata?.guardrails,
|
||||
disable_global_guardrails: keyData.metadata?.disable_global_guardrails || false,
|
||||
prompts: keyData.metadata?.prompts,
|
||||
tags: keyData.metadata?.tags,
|
||||
vector_stores: keyData.object_permission?.vector_stores || [],
|
||||
@@ -388,6 +391,25 @@ export function KeyEditView({
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Disable Global Guardrails{" "}
|
||||
<Tooltip title="When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)">
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="disable_global_guardrails"
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch
|
||||
disabled={!premiumUser}
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Tags" name="tags">
|
||||
<Select
|
||||
mode="tags"
|
||||
|
||||
@@ -673,6 +673,17 @@ export default function KeyInfoView({
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Disable Global Guardrails</Text>
|
||||
<Text>
|
||||
{currentKeyData.metadata?.disable_global_guardrails === true ? (
|
||||
<Badge color="yellow">Enabled - Global guardrails bypassed</Badge>
|
||||
) : (
|
||||
<Badge color="green">Disabled - Global guardrails active</Badge>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Models</Text>
|
||||
<div className="flex flex-wrap gap-2 mt-1">
|
||||
|
||||
Reference in New Issue
Block a user