Can user OAuth tokens be forwarded between Databricks Apps for on-behalf-of (OBO) authorization?
I have two Databricks Apps deployed in the same workspace:
1. **UI App** (Streamlit) - configured with OAuth user authorization
2. **Middleware App** (FastAPI) - also configured with OAuth user authorization
Both apps have matching OAuth scopes configured in their `app.yaml`:
```yaml
# UI App
auth:
type: "user-authorization"
oauth:
scopes:
- sql
- iam.current-user.read
- iam.access-control.read
- catalog.tables.read
- catalog.schemas.read
- catalog.catalogs.read
# Middleware App (same scopes)
auth:
type: "user-authorization"
oauth:
scopes:
- sql
- iam.current-user.read
# ... (same as UI)
```
What I'm Trying to Achieve
When a user accesses the UI app and it makes HTTP requests to the middleware app, I want the middleware to:
1. Receive the **user's OAuth token** (not the UI app's service principal token)
2. Use that token to perform operations **on behalf of the user**
3. Query the user's groups via Databricks APIs (e.g., `WorkspaceClient.current_user.me()` or SCIM API)
What I've Tried
**Attempt 1: Authorization Header**
```python
# In UI app
token = st.context.headers.get("X-Forwarded-Access-Token")
response = requests.get(
middleware_url,
headers={"Authorization": f"Bearer {token}"}
)
```
**Result:** Middleware receives empty `Authorization` header (appears to be stripped by Databricks)
**Attempt 2: Custom Headers**
```python
headers={"X-User-Token": token}
```
**Result:** Custom headers are not forwarded between apps
**Attempt 3: OAuth Token Exchange**
```python
# Tried to exchange UI app token for middleware app token
```
**Result:** 403 error - "Client authentication failed: user 'middleware_client_id' is not a member of workspace"
Documentation I've Reviewed
1. **[Connect to API Databricks App](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/connect-local)** states:
> "From other Databricks apps: the app handles authentication automatically using its assigned service principal."
This seems to indicate service principals are used for app-to-app calls, not user tokens.
2. **[HTTP Headers Forwarded](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/http-headers)** shows:
- โ
`X-Forwarded-Email`, `X-Forwarded-User`, `gap-auth` ARE forwarded
- โ `X-Forwarded-Access-Token` is NOT listed as forwarded between apps
3. The "Specify OAuth scopes" section discusses token generation for local/external access, but doesn't clarify app-to-app scenarios.
My Questions
1. **Is it possible to forward user OAuth tokens between Databricks Apps** for on-behalf-of (OBO) authorization?
2. **If yes**, what is the correct method to:
- Forward the token from UI app to middleware app?
- Extract and use the token in the middleware app?
- Which header should be used?
3. **If no**, what is the recommended pattern for implementing **user-specific authorization** in a multi-app architecture where:
- UI app needs to call middleware app
- Middleware needs to know which user is making the request
- Middleware needs to enforce user-specific permissions (e.g., group-based access control)
Current Workaround
I can extract the user's email from `X-Forwarded-Email` header and use the middleware's service principal to look up the user's groups, but this requires:
- Granting the middleware's service principal workspace admin permissions
- Operations are performed as the service principal, not as the actual user
Is there a better approach that preserves user context without requiring admin permissions?
---
## Environment
- **Databricks Runtime:** Apps (serverless)
- **Workspace Type:** Azure Databricks
- **App Framework:** Streamlit (UI), FastAPI (Middleware)
- **Authentication:** OAuth 2.0 User Authorization on both apps
- **Deployment:** Both apps deployed in same workspace
---
Additional Context
I've spent significant time investigating this and found that:
- Browser โ App: User token IS forwarded via `X-Forwarded-Access-Token` โ
- App โ App: User token appears NOT to be forwarded โ
The documentation suggests using service principals for app-to-app calls, but I'm unclear if this is a limitation or if there's a configuration I'm missing to enable user token forwarding.
Any guidance on the correct architectural pattern for multi-app user authorization would be greatly appreciated!