fix(ci): regen schema.d.ts, true eslint metrics, migration-endpoint auth-layer test

- schema.d.ts: regenerate for the logging_exporters doc/scope changes
- eslint-metrics.json: set to the actual post-merge counts (2016/126/61)
- test_migrate_encryption_requires_admin: assert 403, not 401. This PR makes
  /credentials/{credential_name} a self-managed route (so team admins can PATCH a
  credential's access), which the single-segment /credentials/migrate-encryption
  path matches, so the non-admin clears the route gate and is rejected on the
  endpoint's first line by _require_proxy_admin (before any DB read/write) instead
  of the route-level gate. No security change; only the rejection layer moved.
This commit is contained in:
yucheng-berriai 2026-07-02 13:37:07 -07:00
parent a78ae0f99b
commit e68d7f0db7
3 changed files with 16 additions and 13 deletions

View file

@ -48,10 +48,14 @@ async def test_migrate_encryption_check_requires_admin(proxy_client, scratch):
async def test_migrate_encryption_requires_admin(proxy_client, scratch):
"""A non-admin key cannot trigger the migration (auth layer rejects, 401).
"""A non-admin key cannot trigger the migration; it is rejected before any write.
Rejection happens before any write: the admin-only route check fires in
``user_api_key_auth``, ahead of the endpoint body.
``/credentials/{credential_name}`` is a self-managed route (team admins reach
``PATCH /credentials/{name}`` to grant their own team a logging destination), so
the single-segment ``/credentials/migrate-encryption`` path matches that pattern
and clears the route-level gate. The migration endpoint then rejects the
non-admin on its first line via ``_require_proxy_admin`` (403), ahead of any DB
read or write. Either way the non-admin never triggers the migration.
"""
gen = await proxy_client.post(
"/key/generate",
@ -68,4 +72,4 @@ async def test_migrate_encryption_requires_admin(proxy_client, scratch):
"/credentials/migrate-encryption",
headers={"Authorization": f"Bearer {nonadmin_key}"},
)
assert resp.status_code == 401, resp.text
assert resp.status_code == 403, resp.text

View file

@ -1,5 +1,5 @@
{
"@typescript-eslint/no-explicit-any": 2029,
"complexity": 129,
"max-depth": 62
"@typescript-eslint/no-explicit-any": 2016,
"complexity": 126,
"max-depth": 61
}

View file

@ -6514,6 +6514,7 @@ export interface paths {
* - metadata: Optional[dict] - Metadata for key, store information for key. Example metadata = {"team": "core-infra", "app": "app2", "email": "ishaan@berri.ai" }
* - guardrails: Optional[List[str]] - List of active guardrails for the key
* - policies: Optional[List[str]] - List of policy names to apply to the key. Policies define guardrails, conditions, and inheritance rules.
* - logging_exporters: Optional[List[str]] - Names of admin-owned logging destinations (credential names) this key exports its traces to.
* - disable_global_guardrails: Optional[bool] - Whether to disable global guardrails for the key.
* - permissions: Optional[dict] - key-specific permissions. Currently just used for turning off pii masking (if connected). Example - {"pii": false}
* - model_max_budget: Optional[Dict[str, BudgetConfig]] - Model-specific budgets {"gpt-4": {"budget_limit": 0.0005, "time_period": "30d"}}}. IF null or {} then no model specific budget.
@ -6913,6 +6914,7 @@ export interface paths {
* - send_invite_email: Optional[bool] - Send invite email to user_id
* - guardrails: Optional[List[str]] - List of active guardrails for the key
* - policies: Optional[List[str]] - List of policy names to apply to the key. Policies define guardrails, conditions, and inheritance rules.
* - logging_exporters: Optional[List[str]] - Names of admin-owned logging destinations (credential names) this key exports its traces to.
* - disable_global_guardrails: Optional[bool] - Whether to disable global guardrails for the key.
* - prompts: Optional[List[str]] - List of prompts that the key is allowed to use.
* - blocked: Optional[bool] - Whether the key is blocked
@ -8968,6 +8970,7 @@ export interface paths {
*
* - organization_alias: *str* - The name of the organization.
* - models: *List* - The models the organization has access to.
* - logging_exporters: *Optional[List[str]]* - Names of admin-owned logging destinations (credential names) this organization exports its traces to.
* - budget_id: *Optional[str]* - The id for a budget (tpm/rpm/max budget) for the organization.
* ### IF NO BUDGET ID - CREATE ONE WITH THESE PARAMS ###
* - max_budget: *Optional[float]* - Max budget for org
@ -13566,6 +13569,7 @@ export interface paths {
* - model_aliases: Optional[dict] - Model aliases for the team. [Docs](https://docs.litellm.ai/docs/proxy/team_based_routing#create-team-with-model-alias)
* - guardrails: Optional[List[str]] - Guardrails for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails)
* - policies: Optional[List[str]] - Policies for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies)
* - logging_exporters: Optional[List[str]] - Names of admin-owned logging destinations (credential names) this team exports its traces to.
* - disable_global_guardrails: Optional[bool] - Whether to disable global guardrails for the key.
* - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission.
* - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member.
@ -13743,6 +13747,7 @@ export interface paths {
* - model_aliases: Optional[dict] - Model aliases for the team. [Docs](https://docs.litellm.ai/docs/proxy/team_based_routing#create-team-with-model-alias)
* - guardrails: Optional[List[str]] - Guardrails for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails)
* - policies: Optional[List[str]] - Policies for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies)
* - logging_exporters: Optional[List[str]] - Names of admin-owned logging destinations (credential names) this team exports its traces to.
* - disable_global_guardrails: Optional[bool] - Whether to disable global guardrails for the key.
* - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"], "agents": ["agent_1", "agent_2"], "agent_access_groups": ["dev_group"]}. IF null or {} then no object permission.
* - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member.
@ -27943,8 +27948,6 @@ export interface components {
guardrails?: string[] | null;
/** Key Alias */
key_alias?: string | null;
/** Logging Exporters */
logging_exporters?: string[] | null;
/** Max Budget */
max_budget?: number | null;
/** Max Parallel Requests */
@ -32152,8 +32155,6 @@ export interface components {
guardrails?: string[] | null;
/** Key Alias */
key_alias?: string | null;
/** Logging Exporters */
logging_exporters?: string[] | null;
/** Max Budget */
max_budget?: number | null;
/** Max Parallel Requests */
@ -32252,8 +32253,6 @@ export interface components {
guardrails?: string[] | null;
/** Key Alias */
key_alias?: string | null;
/** Logging Exporters */
logging_exporters?: string[] | null;
/** Max Budget */
max_budget?: number | null;
/** Max Parallel Requests */