User OBO Token Forwarding between apps

ctgchris
New Contributor III

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!

Khaja_Zaffer
Esteemed Contributor

Hello @ctgchris 

Just pushing this issue for visibility to others. Someone from databricks can come up with a solution.