Skip to main content

cookbook-authentication

Implement authentication in Databricks Apps: get current user info, on-behalf-of-user (OBO) auth, service principal auth, and OAuth patterns. Use when the user asks about auth, user tokens, service principals, OAuth, or OBO in Dash, Streamlit, Reflex, or FastAPI.

Datos de origen

Repositorio
databricks-solutions/databricks-apps-cookbook
Última actividad en el origen
28 de abril de 2026 a las 11:17
Idioma detectado de SKILL.md
inglés
Estrellas
187
Forks
124

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
cookbook-authentication
description
Implement authentication in Databricks Apps: get current user info, on-behalf-of-user (OBO) auth, service principal auth, and OAuth patterns. Use when the user asks about auth, user tokens, service principals, OAuth, or OBO in Dash, Streamlit, Reflex, or FastAPI.
# Authentication Databricks Apps supports two auth models: **app auth** (service principal) and **user auth** (on-behalf-of-user). Choose based on whether operations should run as the app or as the logged-in user. | Model | Identity | When to Use | |-------|----------|-------------| | App auth (service principal) | Auto-injected via `Config()` | Default. Data access with app-level permissions | | User auth (OBO) | `x-forwarded-access-token` header | Per-user permissions, audit trails | ## Recipes ### Get current user info Read HTTP headers injected by the Databricks Apps proxy to identify the logged-in user. #### Dash ```python from flask import request headers = request.headers email = headers.get("X-Forwarded-Email") username = headers.get("X-Forwarded-Preferred-Username") user = headers.get("X-Forwarded-User") ip = headers.get("X-Real-Ip") ``` #### Streamlit ```python import streamlit as st from databricks.sdk import WorkspaceClient headers = st.context.headers email = headers.get("X-Forwarded-Email") username = headers.get("X-Forwarded-Preferred-Username") user_access_token = headers.get("X-Forwarded-Access-Token") if user_access_token: w = WorkspaceClient(token=user_access_token, auth_type="pat") current_user = w.current_user.me() st.write(f"Display Name: {current_user.display_name}") st.write(f"Groups: {len(current_user.groups) if current_user.groups else 0}") ``` #### Reflex ```python import reflex as rx from databricks.sdk import WorkspaceClient class UserState(rx.State): user_info: dict = {} @rx.event def load_user(self): headers = self.router.headers token = getattr(headers, "x_forwarded_access_token", "") if token: w = WorkspaceClient(token=token, auth_type="pat") user = w.current_user.me() self.user_info = { "name": user.display_name, "email": user.user_name, } ``` ### On-behalf-of-user (OBO) authentication Run queries using the end user's permissions via their forwarded access token. #### Streamlit ```python import streamlit as st from databricks import sql from databricks.sdk.core import Config cfg = Config() def get_user_token(): return st.context.headers["X-Forwarded-Access-Token"] @st.cache_resource(ttl=300) def connect_with_obo(http_path, user_token): return sql.connect( server_hostname=cfg.host, http_path=http_path, access_token=user_token, ) user_token = get_user_token() conn = connect_with_obo("/sql/1.0/warehouses/xxxxxx", user_token) with conn.cursor() as cursor: cursor.execute("SELECT * FROM samples.nyctaxi.trips LIMIT 10") df = cursor.fetchall_arrow().to_pandas() st.dataframe(df) ``` #### Reflex ```python import reflex as rx from databricks import sql from databricks.sdk.core import Config cfg = Config() class OboQueryState(rx.State): results: list = [] @rx.event(background=True) async def run_query(self): headers = self.router.headers token = getattr(headers, "x_forwarded_access_token", "") conn = sql.connect( server_hostname=cfg.host, http_path="/sql/1.0/warehouses/xxxxxx", access_token=token, ) with conn.cursor() as cursor: cursor.execute("SELECT * FROM samples.nyctaxi.trips LIMIT 10") async with self: self.results = cursor.fetchall_arrow().to_pandas().values.tolist() ``` ### Service principal auth (app auth) This is the default. `Config()` auto-detects credentials from the environment (`DATABRICKS_CLIENT_ID`, `DATABRICKS_CLIENT_SECRET`). ```python from databricks.sdk.core import Config from databricks import sql cfg = Config() conn = sql.connect( server_hostname=cfg.host, http_path="/sql/1.0/warehouses/xxxxxx", credentials_provider=lambda: cfg.authenticate, ) ``` For the SDK client: ```python from databricks.sdk import WorkspaceClient w = WorkspaceClient() # auto-configured from environment ``` ### FastAPI: Connecting from different contexts FastAPI apps support multiple authentication contexts: #### From deployed app (service principal) ```python from databricks.sdk import WorkspaceClient w = WorkspaceClient() # uses auto-injected DATABRICKS_HOST + client credentials ``` #### From external service (M2M) ```python from databricks.sdk import WorkspaceClient w = WorkspaceClient( host="https://workspace.cloud.databricks.com", client_id="your-client-id", client_secret="your-client-secret", ) ``` #### From local development ```bash databricks auth login --host https://workspace.cloud.databricks.com ``` Then in code: ```python from databricks.sdk import WorkspaceClient w = WorkspaceClient(profile="DEFAULT") ``` #### OAuth2 Bearer for API routes FastAPI endpoints on Databricks Apps must be under the `/api` prefix and require Bearer token auth: ```python from fastapi import FastAPI app = FastAPI() # All routes under /api are protected by Databricks Apps OAuth2 @app.get("/api/v1/data") async def get_data(): return {"message": "authenticated"} ``` ## Available HTTP Headers | Header | Description | Requires OBO | |--------|-------------|-------------| | `X-Forwarded-Email` | User's email | No | | `X-Forwarded-Preferred-Username` | Username | No | | `X-Forwarded-User` | User ID | No | | `X-Real-Ip` | Client IP | No | | `X-Forwarded-Access-Token` | User's OAuth token | Yes | ## Enabling OBO OBO requires workspace admin to enable [on-behalf-of-user authentication](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/app-development#-using-the-databricks-apps-authorization-model) for the app. Without it, only basic headers (email, username) are available. ## Resources | Auth model | Resources | |-----------|-----------| | App auth | None (auto-configured) | | OBO + SQL | [SQL warehouse](https://docs.databricks.com/aws/en/compute/sql-warehouse/) | ## Permissions | Auth model | Permissions | |-----------|-----------| | App auth | Service principal needs permissions on accessed resources | | OBO | End user's permissions apply; user needs `CAN USE` on SQL warehouse | ## Dependencies ``` databricks-sdk databricks-sql-connector ``` Plus your framework package. ## Common Pitfalls - `X-Forwarded-Access-Token` is only present when deployed with OBO enabled; it's missing during local dev - Without OBO, `w.current_user.me()` returns the service principal, not the logged-in user - Never hardcode tokens; always use `Config()` for service principal auth - FastAPI routes must be under `/api` prefix to receive Bearer token authentication - Cache OBO connections per user token to avoid connection exhaustion
Ver en GitHub