Skip to content

bump: version 1.84.6 (backport CrowdStrike AIDR metadata capture + identity fix) - #29994

Merged
yuneng-berri merged 3 commits into
stable/1.84.xfrom
litellm_cherrypick_1_84_6
Jun 9, 2026
Merged

bump: version 1.84.6 (backport CrowdStrike AIDR metadata capture + identity fix)#29994
yuneng-berri merged 3 commits into
stable/1.84.xfrom
litellm_cherrypick_1_84_6

Conversation

@yuneng-berri

Copy link
Copy Markdown
Contributor

Relevant issues

Backports the CrowdStrike AIDR user/model metadata capture (#29517, authored by Kenan Yildirim) plus the follow-up metadata-bag fix to stable/1.84.x, and bumps the patch version to 1.84.6 for a release.

The fix corrects a bug in #29517: it resolved the request metadata from a single bag with request_data.get("litellm_metadata", request_data.get("metadata")). Because dict.get returns the stored value when the key is present, a present litellm_metadata (an explicit null, or a caller-supplied dict) shadowed metadata, where /chat/completions places the authenticated identity. So user_id and extra_info.user_name were silently dropped from the outbound guard payload for any request that carried a litellm_metadata field. The fix reads identity from both bags.

Adaptation note (not a clean cherry-pick)

stable/1.84.x carries an older CrowdStrike implementation than #29517 was written against, so the cherry-pick required three deliberate adaptations, each preserved here:

  • guard_input is a plain dict on this branch, so the payload keeps "guard_input": guard_input rather than guard_input.model_dump(mode="json") (the latter would AttributeError on a dict). Kenan's dict[str, Any] annotation is kept.
  • Added from collections.abc import Mapping, which this branch did not import but the metadata code needs.
  • The cherry-pick's test hunk pulled in an unrelated test (test_apply_guardrail_request_skipped_messages_stay_aligned) from a different change that is not on this branch; only Kenan's three new tests were taken.

Kenan's authorship is preserved on his commit.

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all unit tests
  • My PR's scope is as isolated as possible; it only solves 1 specific problem

Screenshots / Proof of Fix

Full CrowdStrike guardrail suite on this branch (stable's 9 tests + Kenan's 3 + the regression test's 4 parametrizations):

$ python -m pytest -q tests/test_litellm/proxy/guardrails/guardrail_hooks/test_crowdstrike_aidr.py
16 passed

The regression test test_apply_guardrail_reads_identity_from_either_metadata_bag fails on the pre-fix single-bag read (3 of 4 parametrizations drop user_id) and passes after. Black, Ruff, and MyPy pass on the changed module, and uv lock --check is consistent with the 1.84.6 bump.

Type

🐛 Bug Fix

Changes

Three commits on top of stable/1.84.x: Kenan's #29517 feature (adapted to this branch as above), the metadata-bag fix with a _merge_metadata_bags helper plus a parametrized regression test, and the 1.84.5 -> 1.84.6 version bump in pyproject.toml and uv.lock.

kenany and others added 3 commits June 8, 2026 18:05
Capture user_id and extra_info from metadata or litellm_metadata. The single-bag read dropped identity whenever a request carried a present litellm_metadata field (null or a user-supplied dict), since /chat/completions routes the authenticated identity into metadata while the guardrail read litellm_metadata first
@yuneng-berri
yuneng-berri requested a review from a team June 9, 2026 01:14
@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR backports CrowdStrike AIDR user/model identity capture to stable/1.84.x and fixes a regression in the original implementation where a present litellm_metadata key blocked reading the authenticated identity from metadata. It also bumps the patch version to 1.84.6.

  • _merge_metadata_bags helper: replaces the single-bag .get(\"litellm_metadata\", .get(\"metadata\")) lookup with a proper merge of both bags, so identity fields in either dict are captured.
  • Identity fields in payload: user_id, model, and extra_info.user_name are now populated from the merged metadata and sent to CrowdStrike AIDR.
  • Test improvements: three new feature tests, a parametrized regression test covering all four identity-location combinations, and two existing config-failure tests hardened with monkeypatch.delenv.

Confidence Score: 3/5

Safe to merge once the merge order in _merge_metadata_bags is corrected; as-is, caller-supplied litellm_metadata can overwrite the auth-system identity in the outbound CrowdStrike AIDR payload.

The _merge_metadata_bags helper iterates metadata then litellm_metadata, so the second dict values win on key collision. Since litellm auth middleware writes verified caller identity into metadata, and litellm_metadata is partially shaped by the incoming request body, a caller who includes user_api_key_user_id or user_api_key_user_email in their litellm_metadata will silently replace the authenticated values in the CrowdStrike AIDR audit payload. None of the new regression tests exercise a conflict case, so the bug passes undetected.

litellm/proxy/guardrails/guardrail_hooks/crowdstrike_aidr/crowdstrike_aidr.py - specifically the _merge_metadata_bags iteration order.

Important Files Changed

Filename Overview
litellm/proxy/guardrails/guardrail_hooks/crowdstrike_aidr/crowdstrike_aidr.py Adds _merge_metadata_bags helper and metadata/identity fields in the AIDR payload; merge order gives litellm_metadata (partially caller-controlled) precedence over metadata (auth-system-set), which can allow identity spoofing in the CrowdStrike AIDR audit payload.
tests/test_litellm/proxy/guardrails/guardrail_hooks/test_crowdstrike_aidr.py Adds three new feature tests and a four-parametrized regression test; strengthens two existing config-failure tests with monkeypatch.delenv to prevent false-passes when env vars happen to be set. No real network calls - all HTTP interactions are mocked.
pyproject.toml Version bump from 1.84.5 to 1.84.6 in both [project] and [tool.commitizen] sections.

Reviews (1): Last reviewed commit: "bump: version 1.84.5 → 1.84.6" | Re-trigger Greptile

def _merge_metadata_bags(request_data: Mapping[str, Any]) -> Optional[dict[str, Any]]:
merged: dict[str, Any] = {}
present = False
for bag in (request_data.get("metadata"), request_data.get("litellm_metadata")):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Merge order lets caller-supplied data overwrite authenticated identity

metadata is applied first, then litellm_metadata overwrites any shared keys. Because litellm's auth middleware writes the authenticated caller identity (user_api_key_user_id, user_api_key_user_email) into metadata, a caller who deliberately (or accidentally) includes these same keys in their request-body litellm_metadata will silently replace the system-verified identity in the outbound CrowdStrike AIDR payload. Reversing the iteration order ensures the system-set metadata values always win on conflict.

Suggested change
for bag in (request_data.get("metadata"), request_data.get("litellm_metadata")):
for bag in (request_data.get("litellm_metadata"), request_data.get("metadata")):

@yuneng-berri
yuneng-berri enabled auto-merge June 9, 2026 01:24
@yuneng-berri
yuneng-berri merged commit 28e3e03 into stable/1.84.x Jun 9, 2026
62 of 74 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_cherrypick_1_84_6 branch June 9, 2026 01:25
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.

3 participants