<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: X-Forwarded-Access-Token occasionally return stale values from a previous session in Administration &amp; Architecture</title>
    <link>https://community.databricks.com/t5/administration-architecture/x-forwarded-access-token-occasionally-return-stale-values-from-a/m-p/163111#M5436</link>
    <description>&lt;P class="PDq2pG_selectionAnchorContainer" data-end="113" data-start="0"&gt;This almost always turns out to be &lt;CODE data-end="54" data-start="35"&gt;st.cache_resource&lt;/CODE&gt; on the connection, not the reverse proxy reusing anything.&lt;/P&gt;
&lt;P data-end="584" data-start="115"&gt;You said you checked your &lt;CODE data-end="156" data-start="141"&gt;st.cache_data&lt;/CODE&gt; functions and they key on username, which is the right instinct, but the leak usually hides in whatever function opens the SQL connection or session object. &lt;CODE data-end="333" data-start="314"&gt;st.cache_resource&lt;/CODE&gt; caches are globally by default, they're shared across every user and every session in the app process, not per-session like &lt;CODE data-end="476" data-start="458"&gt;st.session_state&lt;/CODE&gt;. The cache key comes from the function's arguments, so if your connection-builder function looks like this:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼu"&gt;@&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;cache_resource&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;ttl&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼy"&gt;300&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;def&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;():
    &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;return&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;sql&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;connect(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;server_hostname&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;http_path&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;access_token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-end="1121" data-start="742"&gt;every user hits the same cached connection object for up to the TTL window, and that connection was opened with whichever token happened to trigger the first cache miss. That's exactly the symptom you're describing: queries occasionally running under a previous user's identity, and it'll look "random" because it only shows up when the cache is warm from someone else's request.&lt;/P&gt;
&lt;P data-end="1218" data-start="1123"&gt;The fix is to make the token part of the cache key so each identity gets its own cached object:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="pointer-events-none absolute inset-x-4 top-12 bottom-4"&gt;
&lt;DIV class="pointer-events-none sticky z-40 shrink-0 z-1!"&gt;
&lt;DIV class="sticky bg-token-border-light"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼu"&gt;@&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;cache_resource&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;ttl&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼy"&gt;300&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;def&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_token&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;str&lt;/SPAN&gt;&lt;SPAN&gt;):
    &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;return&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;sql&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;connect(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;server_hostname&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;http_path&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;access_token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_token&lt;/SPAN&gt;&lt;SPAN&gt;)

&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;conn&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-end="1610" data-start="1426"&gt;Or simplest and safest, don't cache the connection at all, open it fresh per request and close it after the query, which is what Databricks' own Apps examples do for this exact reason.&lt;/P&gt;
&lt;P data-end="1829" data-start="1612"&gt;To your second question, yes, there's a cheap way to verify the token belongs to who you think before you use it. Use the SDK with that specific token and check the identity it resolves to against &lt;CODE data-end="1828" data-start="1809"&gt;X-Forwarded-Email&lt;/CODE&gt;:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼv"&gt;from&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;databricks&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;sdk&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;import&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;WorkspaceClient&lt;/SPAN&gt;

&lt;SPAN class="ͼ11"&gt;w&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;WorkspaceClient&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;host&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;host&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;me&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;w&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;current_user&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;me()
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;if&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;me&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;user_name &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;!=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;username&lt;/SPAN&gt;&lt;SPAN&gt;:
    &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;error(&lt;/SPAN&gt;&lt;SPAN class="ͼz"&gt;"Session identity mismatch, please refresh."&lt;/SPAN&gt;&lt;SPAN&gt;)
    &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;stop()&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-is-only-node="" data-is-last-node="" data-end="2558" data-start="2073"&gt;One more thing worth knowing separately from the caching issue: &lt;CODE data-end="2157" data-start="2137"&gt;st.context.headers&lt;/CODE&gt; itself is only populated once, at the initial page load / WebSocket connection, and doesn't refresh on reruns. So on a long-lived tab, even without any caching bug, the token you're holding can go stale if the underlying session persists across a reconnect. The identity check above catches that case too, since it fails closed instead of quietly running a query under a token that no longer matches.&lt;/P&gt;</description>
    <pubDate>Wed, 15 Jul 2026 17:54:36 GMT</pubDate>
    <dc:creator>iyashk-DB</dc:creator>
    <dc:date>2026-07-15T17:54:36Z</dc:date>
    <item>
      <title>X-Forwarded-Access-Token occasionally return stale values from a previous session</title>
      <link>https://community.databricks.com/t5/administration-architecture/x-forwarded-access-token-occasionally-return-stale-values-from-a/m-p/163074#M5435</link>
      <description>&lt;P class=""&gt;Hi all,&lt;/P&gt;&lt;P class=""&gt;I'm running a Streamlit app on Databricks Apps with On-Behalf-Of User Authorization enabled. We've observed that X-Forwarded-Access-Token and X-Forwarded-Email sometimes return values that belong to a &lt;EM&gt;previous&lt;/EM&gt; session(logged out other user, using same browser window) rather than the current one, e.g.:&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV class=""&gt;python&lt;/DIV&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN&gt;user_access_token &lt;SPAN class=""&gt;=&lt;/SPAN&gt; st&lt;SPAN class=""&gt;.&lt;/SPAN&gt;context&lt;SPAN class=""&gt;.&lt;/SPAN&gt;headers&lt;SPAN class=""&gt;.&lt;/SPAN&gt;get&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;"X-Forwarded-Access-Token"&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;
&lt;/SPAN&gt;&lt;SPAN&gt;username &lt;SPAN class=""&gt;=&lt;/SPAN&gt; st&lt;SPAN class=""&gt;.&lt;/SPAN&gt;context&lt;SPAN class=""&gt;.&lt;/SPAN&gt;headers&lt;SPAN class=""&gt;.&lt;/SPAN&gt;get&lt;SPAN class=""&gt;(&lt;/SPAN&gt;&lt;SPAN class=""&gt;"X-Forwarded-Email"&lt;/SPAN&gt;&lt;SPAN class=""&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P class=""&gt;username occasionally appears to be a different user's email from an earlier session, and the associated user_access_token then gets used for a Databricks SQL query executed on behalf of the wrong identity.&lt;/P&gt;&lt;P class=""&gt;&lt;STRONG&gt;What we've verified:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL class=""&gt;&lt;LI&gt;We are &lt;STRONG&gt;not&lt;/STRONG&gt; caching the connection or the token anywhere in our code (no st.cache_resource wrapping a connection object, no module-level/global variables holding the token). user_access_token and username are read fresh from st.context.headers at the top of the script on every run.&lt;/LI&gt;&lt;LI&gt;Our st.cache_data-decorated functions include username as an explicit cache key argument, so we don't believe this is Streamlit's function-level caching bleeding across users.&lt;/LI&gt;&lt;/UL&gt;&lt;P class=""&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL class=""&gt;&lt;LI&gt;Is it expected/known that the Databricks Apps reverse proxy (or the underlying connection between the proxy and the app container) can reuse a connection across different end-user sessions in a way that causes X-Forwarded-* headers from one user's request to be forwarded on a subsequent request from a different user?&lt;/LI&gt;&lt;LI&gt;Is there a recommended way to positively verify, on every request, that X-Forwarded-Access-Token actually corresponds to X-Forwarded-Email (e.g., calling current_user.me() with the token) before we trust it for a query? We've added this as a client-side safety check in the meantime, but would prefer a platform-level explanation/fix if this is a known proxy behavior.&lt;/LI&gt;&lt;/UL&gt;&lt;P class=""&gt;Any insight into whether this is expected behavior, a known issue, or something we should file a support ticket for would be appreciated. Happy to share more app code / logs if useful.&lt;/P&gt;&lt;P class=""&gt;Thanks!&lt;/P&gt;</description>
      <pubDate>Wed, 15 Jul 2026 10:52:39 GMT</pubDate>
      <guid>https://community.databricks.com/t5/administration-architecture/x-forwarded-access-token-occasionally-return-stale-values-from-a/m-p/163074#M5435</guid>
      <dc:creator>tesshy-amane</dc:creator>
      <dc:date>2026-07-15T10:52:39Z</dc:date>
    </item>
    <item>
      <title>Re: X-Forwarded-Access-Token occasionally return stale values from a previous session</title>
      <link>https://community.databricks.com/t5/administration-architecture/x-forwarded-access-token-occasionally-return-stale-values-from-a/m-p/163111#M5436</link>
      <description>&lt;P class="PDq2pG_selectionAnchorContainer" data-end="113" data-start="0"&gt;This almost always turns out to be &lt;CODE data-end="54" data-start="35"&gt;st.cache_resource&lt;/CODE&gt; on the connection, not the reverse proxy reusing anything.&lt;/P&gt;
&lt;P data-end="584" data-start="115"&gt;You said you checked your &lt;CODE data-end="156" data-start="141"&gt;st.cache_data&lt;/CODE&gt; functions and they key on username, which is the right instinct, but the leak usually hides in whatever function opens the SQL connection or session object. &lt;CODE data-end="333" data-start="314"&gt;st.cache_resource&lt;/CODE&gt; caches are globally by default, they're shared across every user and every session in the app process, not per-session like &lt;CODE data-end="476" data-start="458"&gt;st.session_state&lt;/CODE&gt;. The cache key comes from the function's arguments, so if your connection-builder function looks like this:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼu"&gt;@&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;cache_resource&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;ttl&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼy"&gt;300&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;def&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;():
    &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;return&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;sql&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;connect(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;server_hostname&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;http_path&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;access_token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-end="1121" data-start="742"&gt;every user hits the same cached connection object for up to the TTL window, and that connection was opened with whichever token happened to trigger the first cache miss. That's exactly the symptom you're describing: queries occasionally running under a previous user's identity, and it'll look "random" because it only shows up when the cache is warm from someone else's request.&lt;/P&gt;
&lt;P data-end="1218" data-start="1123"&gt;The fix is to make the token part of the cache key so each identity gets its own cached object:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="pointer-events-none absolute inset-x-4 top-12 bottom-4"&gt;
&lt;DIV class="pointer-events-none sticky z-40 shrink-0 z-1!"&gt;
&lt;DIV class="sticky bg-token-border-light"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼu"&gt;@&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;cache_resource&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;ttl&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼy"&gt;300&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;def&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_token&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;str&lt;/SPAN&gt;&lt;SPAN&gt;):
    &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;return&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;sql&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;connect(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;server_hostname&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;http_path&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;..., &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;access_token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_token&lt;/SPAN&gt;&lt;SPAN&gt;)

&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;conn&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;get_connection&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-end="1610" data-start="1426"&gt;Or simplest and safest, don't cache the connection at all, open it fresh per request and close it after the query, which is what Databricks' own Apps examples do for this exact reason.&lt;/P&gt;
&lt;P data-end="1829" data-start="1612"&gt;To your second question, yes, there's a cheap way to verify the token belongs to who you think before you use it. Use the SDK with that specific token and check the identity it resolves to against &lt;CODE data-end="1828" data-start="1809"&gt;X-Forwarded-Email&lt;/CODE&gt;:&lt;/P&gt;
&lt;DIV class="relative w-full mt-4 mb-1"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="contents"&gt;
&lt;DIV class="border border-token-border-light border-radius-3xl corner-superellipse/1.1 rounded-3xl"&gt;
&lt;DIV class="relative h-full w-full border-radius-3xl bg-(--code-block-surface) corner-superellipse/1.1 overflow-clip rounded-3xl [--code-block-surface:var(--bg-elevated-secondary)] dark:[--code-block-surface:var(--composer-surface-primary)] lxnfua_clipPathFallback"&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class="h-full min-h-0 min-w-0"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative"&gt;
&lt;DIV class=""&gt;
&lt;DIV class="relative z-0 flex max-w-full"&gt;
&lt;DIV id="code-block-viewer" class="q9tKkq_viewer cm-editor z-10 light:cm-light dark:cm-light flex h-full w-full flex-col items-stretch ͼs ͼ16" dir="ltr"&gt;
&lt;DIV class="cm-scroller"&gt;
&lt;PRE class="cm-content q9tKkq_readonly m-0"&gt;&lt;CODE&gt;&lt;SPAN class="ͼv"&gt;from&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;databricks&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;sdk&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;import&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;WorkspaceClient&lt;/SPAN&gt;

&lt;SPAN class="ͼ11"&gt;w&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;WorkspaceClient&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;host&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;host&lt;/SPAN&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;token&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;user_access_token&lt;/SPAN&gt;&lt;SPAN&gt;)
&lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;me&lt;/SPAN&gt; &lt;SPAN class="ͼv"&gt;=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;w&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;current_user&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;me()
&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;if&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;me&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;user_name &lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;!=&lt;/SPAN&gt; &lt;SPAN class="ͼ11"&gt;username&lt;/SPAN&gt;&lt;SPAN&gt;:
    &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;error(&lt;/SPAN&gt;&lt;SPAN class="ͼz"&gt;"Session identity mismatch, please refresh."&lt;/SPAN&gt;&lt;SPAN&gt;)
    &lt;/SPAN&gt;&lt;SPAN class="ͼ11"&gt;st&lt;/SPAN&gt;&lt;SPAN class="ͼv"&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;stop()&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P data-is-only-node="" data-is-last-node="" data-end="2558" data-start="2073"&gt;One more thing worth knowing separately from the caching issue: &lt;CODE data-end="2157" data-start="2137"&gt;st.context.headers&lt;/CODE&gt; itself is only populated once, at the initial page load / WebSocket connection, and doesn't refresh on reruns. So on a long-lived tab, even without any caching bug, the token you're holding can go stale if the underlying session persists across a reconnect. The identity check above catches that case too, since it fails closed instead of quietly running a query under a token that no longer matches.&lt;/P&gt;</description>
      <pubDate>Wed, 15 Jul 2026 17:54:36 GMT</pubDate>
      <guid>https://community.databricks.com/t5/administration-architecture/x-forwarded-access-token-occasionally-return-stale-values-from-a/m-p/163111#M5436</guid>
      <dc:creator>iyashk-DB</dc:creator>
      <dc:date>2026-07-15T17:54:36Z</dc:date>
    </item>
  </channel>
</rss>

