Skip to content

feat(asgi): Gate client IP/user info behind data_collection config#6841

Draft
ericapisani wants to merge 1 commit into
py-2583-query-params-awsfrom
py-2586-gate-user-data
Draft

feat(asgi): Gate client IP/user info behind data_collection config#6841
ericapisani wants to merge 1 commit into
py-2583-query-params-awsfrom
py-2586-gate-user-data

Conversation

@ericapisani

@ericapisani ericapisani commented Jul 17, 2026

Copy link
Copy Markdown
Member

Apply data_collection.user_info filtering to REMOTE_ADDR/client.address,
falling back to send_default_pii when data_collection is not configured.

Also convert earlier query parameter data collection tests to end-to-end assertions via a real ASGI app.

Ref PY-2586
Ref #6746

Apply data_collection.user_info filtering to REMOTE_ADDR/client.address,
falling back to send_default_pii when data_collection is not configured.

Also convert earlier query parameter data collection tests to end-to-end assertions via a real ASGI app.

Ref PY-2586
Ref #6746
@linear-code

linear-code Bot commented Jul 17, 2026

Copy link
Copy Markdown

PY-2586

Comment on lines +152 to +153
if has_data_collection_enabled(client_options):
if client_options["data_collection"]["user_info"]:

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.

client_options may be unbound when scope type is not http/websocket

In both _get_request_data and _get_request_attributes, client_options = sentry_sdk.get_client().options is assigned only inside the if ty in ("http", "websocket") block, but is later referenced unconditionally when client/asgi_scope_client is truthy. If a scope with ty other than http/websocket carries a client entry, has_data_collection_enabled(client_options) raises NameError. In practice only http/websocket ASGI scopes carry a client key (lifespan scopes do not), so this path is largely unreachable with spec-compliant servers, but it is a latent regression: the prior code branched on should_send_default_pii() and did not depend on client_options.

Evidence
  • client_options is assigned at line 128 (and 181) inside if ty in ("http", "websocket").
  • Lines 151-156 (_get_request_data) and 234-239 (_get_request_attributes) reference has_data_collection_enabled(client_options) at the outer indent, guarded only by if client: / if asgi_scope_client:, not by scope type.
  • Per ASGI, only http/websocket scopes include a client key, so client being truthy while ty is neither is not expected from compliant servers, making the NameError path hard to reach in practice.
  • The regression is that the old branch used should_send_default_pii(), which needed no client_options, so a malformed/non-standard scope with a client value would now raise instead of behaving gracefully.
Also found at 1 additional location
  • sentry_sdk/integrations/_asgi_common.py:233-235

Identified by Warden code-review · DVQ-38F

)
def test_get_request_data_query_string_data_collection(
sentry_init, init_kwargs, expected_query_string
async def test_get_request_data_query_string_data_collection(

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.

async test missing @pytest.mark.asyncio marker under strict asyncio mode

test_get_request_data_query_string_data_collection was converted to an async def but lacks the @pytest.mark.asyncio marker; under strict asyncio mode this parametrized test's body never runs and its assertions are silently skipped. Add @pytest.mark.asyncio above it like the sibling tests.

Evidence
  • pyproject.toml:115 sets asyncio_mode = "strict", which requires an explicit @pytest.mark.asyncio marker for async tests to be collected and awaited.
  • Line 1017 defines async def test_get_request_data_query_string_data_collection, decorated only by @pytest.mark.parametrize (closing ) at line 1016); no @pytest.mark.asyncio precedes it.
  • The two neighboring converted tests at lines 1038 and 1056 do add @pytest.mark.asyncio, confirming the marker is otherwise required here.
  • Without the marker the coroutine is never awaited, so the assert checks inside never execute.

Identified by Warden find-bugs · 3GV-DAH

@github-actions

Copy link
Copy Markdown
Contributor

Codecov Results 📊

94002 passed | ⏭️ 6338 skipped | Total: 100340 | Pass Rate: 93.68% | Execution Time: 331m 7s

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +2184
Passed Tests 📈 +2148
Failed Tests
Skipped Tests 📈 +36

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 2483 uncovered lines.
✅ Project coverage is 89.73%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    89.68%    89.73%    +0.05%
==========================================
  Files          193       193         —
  Lines        24004     24186      +182
  Branches      8340      8492      +152
==========================================
+ Hits         21528     21703      +175
- Misses        2476      2483        +7
- Partials      1385      1383        -2

Generated by Codecov Action

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