You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
StarletteIntegration overwrites the user set during a request (AuthenticationMiddleware) #6756
2.64.0 (also reproduces on current master, HEAD 44fb035)
Steps to Reproduce
With AuthenticationMiddleware + StarletteIntegration + send_default_pii=True, the integration extracts the user from the ASGI request and calls scope.set_user(...)after the request handler has run (patch_authentication_middleware calls _add_user_to_sentry_scope after await old_call(...), sentry_sdk/integrations/starlette.py:411-412).
Because set_userreplaces the scope user (starlette.py:392), any user the application set during the request via sentry_sdk.set_user(...) is discarded.
And Starlette's SimpleUser/BaseUser only exposes username, so id/email are lost.
repro:
importsentry_sdkfromsentry_sdk.integrations.starletteimportStarletteIntegrationfromstarlette.applicationsimportStarlettefromstarlette.authenticationimportAuthCredentials, AuthenticationBackend, SimpleUserfromstarlette.middlewareimportMiddlewarefromstarlette.middleware.authenticationimportAuthenticationMiddlewarefromstarlette.responsesimportPlainTextResponsefromstarlette.routingimportRoutefromstarlette.testclientimportTestClientcaptured= []
classTokenBackend(AuthenticationBackend):
asyncdefauthenticate(self, conn):
# request principal only carries the token subject (username)returnAuthCredentials(["authenticated"]), SimpleUser("token-subject-123")
asyncdefendpoint(request):
# app enriches the Sentry user during the requestsentry_sdk.set_user({"id": "user_42", "email": "real@user.com", "username": "token-subject-123"})
returnPlainTextResponse("ok")
defcapture(event, hint):
captured.append(event.get("user"))
returnNone# drop, don't sendsentry_sdk.init(
dsn="https://public@o0.ingest.sentry.io/0",
send_default_pii=True,
traces_sample_rate=1.0,
integrations=[StarletteIntegration()],
before_send_transaction=capture,
)
app=Starlette(
routes=[Route("/", endpoint)],
middleware=[Middleware(AuthenticationMiddleware, backend=TokenBackend())],
)
TestClient(app).get("/")
print(captured[-1])
pip freeze --all:
sentry-sdk==2.64.0
starlette==0.48.0
Expected Result
The request-derived user augments what the app set; app-set values are kept:
The app-set id/email are clobbered — only the request principal survives:
{'username': 'token-subject-123'}
Real-world impact: on a FastMCP-based MCP server (bearer auth, stateless_http) every transaction loses user.email/user.id; only user.username (the token subject) survives, so traces can't be attributed to real users.
Activity
linear-code commentedon Jul 6, 2026
PY-2596
fix(starlette): Don't overwrite user set during request in Authentica…
fix(starlette): Don't overwrite user set during request in Authentica…