reflex-enterprise Changelog
v0.9.4 (2026-08-14)
Breaking Changes
EventHandlerAPIPluginnow requires an app-issued bearer token on every request — the bare caller-suppliedclient_token(a UUID naming a session) is no longer accepted. This closes the session-takeover vector where a caller could name (or guess) another session's token: sessions are now server-generated and bound to a bearer the app issues, obtained from the anonymous token endpoint or the OAuth flow. State reads redact the session's server-sideclient_token/session_idfrom the returnedroutervar so the session token never reaches the client. (#198)EventHandlerAPIPluginno longer exposes auth/framework event handlers (anyOIDCAuthStateprovider, the page guard, route dispatchers,AuthUserState, and otherreflex/reflex_enterprisestates). Callers drive the app's own handlers and authenticate through the token endpoint or the OAuth flow rather than by queueing the login events directly. (#198)- OIDC cookie names now carry a
_partitionedsuffix so they do not collide with the unpartitioned cookies written by earlier versions. Sessions established before this upgrade are not recognized under the new names, so users sign in once more after it is deployed. (#206)
Features
- New:
reflex_enterprise.MCPPlugin— serve a Reflex app to AI agents over the Model Context Protocol. Adding the plugin mounts an MCP server that publishes the app's public event handlers assearch_events/queue_eventtools, areflex://resource family for reading the app (reflex://state,reflex://event[/{event_name}],reflex://state/events/{state_name}, andreflex://state/vars/{state_name}[/{var_name}]for the caller's live session state, computed vars recomputed), and auto-generatedinstructionscovering the app's location, auth model, tool workflow and pages, so a client knows how to drive it on connect.configure=(a callable or a"module.function"path) hands you the underlyingFastMCPserver before it is mounted to register your own tools, resources and prompts — also reachable at runtime viareflex_enterprise.get_mcp_server();expose_events=Falsepublishes reads only, without the app's action surface;pending_updates=chooses"drop"(default) or"queue"(buffered for aget_pending_updatestool) for deltas from chained events and background tasks, which have no websocket to land on. Upload handlers cannot run inline, soqueue_eventreturns out-of-band upload directions (URL, headers, form fields and acurlexample) carrying a short-lived, single-use ticket bound to the one handler it was minted for. Requires the optionalmcpextra (pip install reflex-enterprise[mcp]). (#198) - MCP OAuth: with an
AuthPluginconfigured,MCPPluginmakes the app a spec-compliant OAuth 2.1 Authorization Server + Resource Server for its MCP endpoint, federating the human login to the existing OIDC flow through a brandable consent page. Clients discover the flow (RFC 9728 / RFC 8414), register dynamically (RFC 7591), and receive the app's own opaque, resource-bound tokens — upstream identity-provider tokens never leave the server. Each token is bound to a dedicated session, so the full enforcement stack (per-event gate, callableauth=checks, delta filtering,AuthUserState.current()) applies to agent traffic unchanged.app_scopes={name: description}renders each scope as an individually grantable checkbox on the consent screen and the minted token carries only what was granted, readable inauth=callbacks viactx.token_scopes. Tokens and consent live in Redis when the app is configured for it, otherwise in-process. On by default alongside anAuthPlugin; opt out withMCPPlugin(auth=False). In production the issuer must be served overhttps— a plain-http issuer (outside loopback dev hosts) is rejected at wiring time with aConfigError, since the authorization server hands out bearer credentials on that origin. See the production/TLS section indocs/mcp.md. (#198) - The
rxe.mcp.resourcedecorator tags a state method as a top-level MCP resource — a var-like, parameterized, read-only view of the caller's session state, served atstate-resource://<state>/<method>[/{param}]with the method's parameters as URI-template variables. It is never an event handler, so it stays out ofsearch_events/queue_event, and itsauth=(True/False/acheck(ctx)callable, the same contract asrxe.var) gates the read whenever anAuthPluginprovides identity. (#198) - Anonymous API sessions:
MCPPluginandEventHandlerAPIPluginservePOST /_reflex/auth/token, returning an app-issued bearer bound to a fresh, server-generated session — the client never picks or sees the underlying client token. The endpoint is rate limited per client IP (token_rate_limit) so one origin cannot mint unbounded sessions. With anAuthPluginan agent may stay anonymous (no user identity, so onlyauth=Falsesurfaces are reachable) or complete the OAuth flow for an authenticated session. On by default; turn it off withanonymous_sessions=Falseon every API plugin you register, since the shared endpoint is served if either enables it. (#198) - Auth contexts (event/var/page) now carry
ctx.surface("browser"/"event_api"/"mcp") andctx.token_scopes(the app-issued token's scopes, orNonefor a browser request), soauth=checks can restrict what a delegated agent may do independent of the underlying user's identity. (#198) - Per-token API rate limiting: every MCP/REST call is counted against the
presenting session token (
call_rate_limit/call_rate_window), with per-handler overrides viarxe.event(rate_limit=..., rate_limit_window=...)(rate_limit=0exempts a handler). (#198) - Cross-origin iframe login: OIDC cookies are now set with
SameSite=Noneand thePartitionedattribute (including on Python versions whosehttp.cookiescannot emitPartitioneditself), so an app can complete the login flow while embedded in an iframe whose outer page is on a different origin. Logging out from the inner frame now clears the session proactively instead of waiting for apostMessagefrom the popup -- that message was only ever caught by a listener bound to the login button, so it never arrived on a page that rendered no login button. (#206) - An app that does not configure the
AuthPluginno longer loads the auth system from its OIDC providers. The provider helpers that reach for plugin-owned things --AuthUserState, the deauthentication app-state sweep, the audit emissions -- are wrapped in@requires_plugin(AuthPlugin)and do nothing when the plugin is absent, so the provider still clears its own cookies but never graftsAuthUserStateonto a state tree the frontend compiled without it. Previously that state was loaded anyway and every update computed for it reached the client as a dispatch error on the frontend and backend consoles. - The guard is reusable by any plugin integration that must stay inert in apps
that did not enable the plugin:
reflex_enterprise.plugins.guardsexposesrequires_plugin(SomePlugin, default=...)as a decorator for sync and async helpers, plushas_plugin/configured_pluginfor the underlying question. (#210)
Bug Fixes
- Popup auth flows honor
redirect_to_urlagain: it is saved before the flow is initiated, so the query parameter set on the iframed page survives, and the saved URL is what the success handler redirects to. (#206) - Fix a cross-site iframe losing a valid session to a cross-tab logout that never
happened. An iframe's partitioned
localStoragecannot see the token hash the login popup wrote at top level, so its empty report was read as proof that another tab had logged out -- and won that race whenever it arrived before the server-queued hash write. The reported hash is now a change ping rather than a verdict: any disagreement queues one cookie sync and the callback adopts whatever the cookie jar holds. Token material means record the session's hash, re-assert it into this partition'slocalStorageand refresh if due; an empty jar is a real logout and resets as before. (#207) MessageListenerno longer accumulatesmessagelisteners. Its effect cleanup removed a different function than the one it registered, so a listener leaked on every re-render and each popup message was then handled once per leaked listener. (#208)
v0.9.3 (2026-08-05)
Features
- Auth:
AuthPlugin(audit=...)— an observe-only audit hook called for every auth lifecycle action (login, logout, token refresh, session expiry) and every access decision (event gate, page guard). See the audit docs. (#200) - Auth: replay gate-blocked events after login — an action blocked by the event gate for an anonymous visitor (the click or form submit that triggered the login redirect) is preserved and replayed once the user authenticates and lands back on the same page, instead of being silently lost (#190)
Bug Fixes
- OIDC: split authorization-callback failure outcomes — handle identity-provider
errorresponses, restart the flow once when the sign-in session was lost, and reserve the "possible CSRF attack" warning for a genuine state mismatch; the callback is now also idempotent across websocket reconnects instead of re-firing against an already-exchanged code (#203) - OIDC: stop reporting expired ID tokens as backend errors — routine expiry during re-validation now logs at INFO without a traceback and no longer sets
has_error; signature and other validation failures still log at ERROR (#202)
Miscellaneous
- OIDC: add token-presence context (
access_token/id_token/refresh_tokenbooleans, never values) to forced-logout warnings so the cause is visible in production logs (#195) - OIDC: attribute forced logouts from the token-refresh paths in logs and downgrade the userinfo reset warning to debug for anonymous visitors, cutting log noise (#203)
- Fix unawaited-coroutine
RuntimeWarnings in the auth test suite (#192)
v0.9.2.post1 (2026-07-06)
Bug Fixes
- Do not update
AuthUserStatewhenAuthPluginis not registered (#196) - Serialize
HTTPCookie.syncrequests to avoid data race (#196)
v0.9.2 (2026-07-06)
Features
- Add Highcharts chart component (#182)
- Add
reflex_apppytest plugin for downstream testability (#179)
Bug Fixes
- Auth: redeliver protected vars on public pages (#186)
Performance
- Auth: skip protected-var redelivery on same-user navigation (#187)
Miscellaneous
- Add logging to silent auth failure/logout paths (#188)
v0.9.1 (2026-07-01)
Features
- Add
reflex_enterprise.AuthPluginproviding integrated secure-by-default auth primitives for protecting pages, fields, vars, and event handlers. See the full docs for usage.
v0.9.0 (2026-06-09)
Breaking Changes
- Restrict
reflex exportandreflex run --env prodto paid tiers (#177)
v0.8.3 (2026-06-01)
Bug Fixes
- Handle map layer
event_handlersprop properly (#175) - OIDC: use
self.__class__instead oftype(self)for handler lookups (#176) - Redo
redirect_to_loginwhen userinfo is unavailable (#174)
v0.8.2 (2026-05-19)
Features
InteractiveLeafletLayerand enhanced event handling for map components (#170)postMessage-based token sync for iframed OIDC popup flows (#172)
Bug Fixes
- OIDC: try refresh token before resetting auth on validation failure (#173)
Miscellaneous
- Harden GitHub Actions workflows (#171)
v0.8.1 (2026-05-11)
Bug Fixes
- Always set
cls._has_registered_endpoints = True(#169)
v0.8.0 (2026-05-08)
Bug Fixes
HTTPCookie: removeBaseStatepatches and fix subclass var dependencies (#164)
Miscellaneous
- Remove runtime version checks throughout the package (#168)
v0.7.3 (2026-05-01)
Features
- Add valid issuers and related cleanup (#163)
Bug Fixes
- Avoid race condition between updating the
localStoragevalue and redirect (#167) - Fix backend path handling for HTTP cookies (#166)
v0.7.2 (2026-04-27)
Bug Fixes
messageListener.js: referencepublic_pathin the wrapped component (#162)
v0.7.1.post2 (2026-04-27)
Miscellaneous
- Remove the GitHub Packages upload step and attach the wheel to the GitHub Release instead
v0.7.1 (2026-04-24)
Features
- Add event handlers as HTTP endpoints and expose them via the OpenAPI spec (#156)
Miscellaneous
- Add license URL (#161)
v0.7.0.post1 (2026-04-21)
Bug Fixes
- Fix importable path for Mantine (#160)
v0.7.0 (2026-04-20)
Bug Fixes
- Reflex 0.9 compatibility: use
importable_pathfor assets in 0.9.0+ (#159) - Additional Reflex 0.9 compatibility fixes (#157, #158)
v0.6.5 (2026-03-27)
Miscellaneous
- Replace AWS CodeArtifact with GitHub Packages for the enterprise wheel (#154)
- Remove
rx.Basefor 0.9 compatibility (#155)
v0.6.4 (2026-03-18)
Features
- Expose display name (#152)
Miscellaneous
- Improve token type validation (#153)
v0.6.3 (2026-03-16)
Miscellaneous
- Raise with an error message (#151)
v0.6.2 (2026-03-10)
Bug Fixes
- Redirect after logout consistently (#150)
v0.6.1 (2026-03-09)
Features
- Add APIs for Reflex Enterprise to override UI (#149)
v0.6.0 (2026-03-03)
Performance
- OIDC: reduce and centralize out-of-band events (#148)
v0.5.5 (2026-02-21)
Bug Fixes
- Ignore refresh access token errors (#142)
Miscellaneous
- OIDC: handle local storage updates internally (#147)
v0.5.4 (2026-02-19)
Bug Fixes
- OIDC: reset auth for invalid tokens in
userinfo(#146)
v0.5.3 (2026-02-19)
Features
- OIDC: allow a pluggable
_http_clientimplementation (#145)
v0.5.2.post1 (2026-02-18)
Bug Fixes
- Also save
redirect_to_urlinsessionStorage(#144)
v0.5.2 (2026-02-18)
Miscellaneous
- Store PKCE identifiers in
sessionStorage(#143)
v0.5.1 (2026-02-17)
Bug Fixes
- Redirect to login with an invalid token (#141)
v0.5.0 (2026-02-13)
Features
- Implement refresh token in
OIDCAuthState(#139)
Miscellaneous
- Overhaul OIDC implementation for flexibility (#135)
- Upgrade dependency pins (#140)
v0.4.3 (2026-01-22)
Bug Fixes
- Fix issuer claim request to support multiple values (#137)
Miscellaneous
- Exclude OIDC routes from
/sitemap.xml(#134)
v0.4.2 (2026-01-07)
Features
- Add
HTTPCookiepartitioned attribute (#129) - Allow cross-origin cookie sync when
same_site="none"(#128)
Miscellaneous
- Use Starlette
cookie_parserinstead ofSimpleCookie(#133) - Do not validate cookie domain (#130)
- Pre-commit fixes (#131)
v0.4.1 (2025-12-19)
Features
- Allow passing arbitrary headers to
HTTPCookie.sync(#127)
v0.4.0 (2025-12-17)
Features
- Implement HTTP Cookie support (#119)
- Add
presetsand other props for Mantine date components (#120) - Return the row count in
DatasourceandSSRMDatasource(#123) - Row grouping options include the
RowGroupingModule(#122) - Apply default sort order by
primary_key(#121)
Bug Fixes
args_namesmust be a tuple (#124)
Miscellaneous
- Bump ag-grid to 34.3.1 (#125)
- Add upload step to build job (#126)