Skip to main content

Deploy an agent using on-behalf-of-user authorization

Preview

This feature is in Public Preview.

On-behalf-of-user (OBO) authorization lets an agent act as the Databricks user who runs the query. This provides:

  • Per-user access to sensitive data
  • Fine-grained data controls enforced by Unity Catalog
  • Tokens that are restricted (“downscoped”) to only the APIs your agent declares, reducing risk of misuse

Requirements

tip

Databricks recommends installing the latest version of the MLflow Python client when developing agents.

  • On-behalf-of-user authorization requires MLflow 2.22.1 and above.
  • On-behalf-of-user authorization is disabled by default and must be enabled by a workspace admin. Review the security considerations before enabling this feature.

Supported resources

Agents with OBO authorization can access the following Databricks resources:

Databricks resource

Compatible clients

Vector Search Index

databricks_langchain.VectorSearchRetrieverTool, databricks_openai.VectorSearchRetrieverTool, VectorSearchClient

Model Serving Endpoint

databricks.sdk.WorkspaceClient

SQL Warehouse

databricks.sdk.WorkspaceClient

UC Connections

databricks.sdk.WorkspaceClient

UC Tables and Functions

Not directly supported. Use Genie with OBO for structured data access.

Genie Space

databricks_langchain.GenieAgent, databricks_openai.GenieAgent

Model Context Protocol (MCP)

databricks_mcp.DatabricksMCPClient

Enable on-behalf-of-user authorization

You can continue to use familiar Databricks SDKs and tools (for example, vector search indexes) in your agent code. To enable OBO authorization:

  1. Update SDK calls to specify that resources are accessed on behalf of the end user.
  2. Update agent code to initialize OBO access inside the predict function, not in __init__, because the user identity is only known at runtime.
  3. When logging your agent for deployment, declare the Databricks REST API scopes your agent requires. This ensures user tokens are limited to the correct APIs.

For a full walkthrough, see the end-to-end example.

Configure SDKs

The following snippets demonstrate how to configure on-behalf-of-user access to different Databricks resources.

When initializing tools, handle permission errors gracefully. Wrap initialization in a try-except block to let the agent respond even if the user lacks access. If you don’t handle errors, the agent fails when required resources are missing.

Python
from databricks.sdk import WorkspaceClient
from databricks_ai_bridge import ModelServingUserCredentials
from databricks_langchain import VectorSearchRetrieverTool

# Configure a Databricks SDK WorkspaceClient to use on behalf of end
# user authorization
user_client = WorkspaceClient(credentials_strategy = ModelServingUserCredentials())

vector_search_tools = []
# Exclude exception handling if you want the agent to fail
# when users lack access to all required Databricks resources
try:
tool = VectorSearchRetrieverTool(
index_name="<index_name>",
description="...",
tool_name="...",
workspace_client=user_client # Specify the user authorized client
)
vector_search_tools.append(tool)
except Exception as e:
_logger.debug("Skipping adding tool as user does not have permissions")

Initialize the agent in the predict function

On-behalf-of-user authorization is compatible with the ResponsesAgent interface.

Because the user's identity is only known at query time, you must access OBO resources inside predict or predict_stream, not in the agent's __init__ method. This ensures that resources are isolated between invocations.

Python
from mlflow.pyfunc import ResponsesAgent


class OBOResponsesAgent(ResponsesAgent):
def initialize_agent():
user_client = WorkspaceClient(
credentials_strategy=ModelServingUserCredentials()
)
system_authorized_client = WorkspaceClient()
### Use the clients above to access resources with either system or user authorization

def predict(
self, request
) -> ResponsesAgentResponse:
agent = initialize_agent() # Initialize the Agent in Predict

agent.predict(request)
...

Declare REST API scopes when logging the agent

When you log your OBO agent for deployment, you need to list the Databricks REST API scopes that your agent will call on behalf of the user. This makes sure user tokens are limited to only the APIs your agent actually needs.

This ensures the agent follows the principle of least privilege: tokens are restricted to just the APIs your agent requires, reducing the chance of unauthorized actions or token misuse.

Below is a list of scopes required to access several common types of Databricks resources.

Resource type

Required API scope

Model Serving endpoints

serving.serving-endpoints

Vector Search endpoints

vectorsearch.vector-search-endpoints

Vector Search indexes

vectorsearch.vector-search-indexes

SQL warehouses

sql.warehouses

UC connections

catalog.connections and serving.serving-endpoints

MCP Genie spaces

mcp.genie

MCP UC functions

mcp.functions

MCP Vector Search

mcp.vectorsearch

MCP external functions

mcp.external

To enable on-behalf-of-user authorization, pass an MLflow AuthPolicy to log_model(), as shown in the example below.

An MLflow AuthPolicy has two components:

  • system_auth_policy: Specify resources accessed with system authentication. Use system authentication for shared resources, such as to query model serving endpoints, in combination with on-behalf-of-user authorization for accessing per-user resources or APIs.
  • user_auth_policy: Specify API scopes your agent needs for on-behalf-of-user authorization. These scopes determine what the agent can do on behalf of the end user.
Python
import mlflow
from mlflow.models.auth_policy import AuthPolicy, SystemAuthPolicy, UserAuthPolicy
from mlflow.models.resources import DatabricksServingEndpoint

# System policy: resources accessed with system credentials
system_policy = SystemAuthPolicy(
resources=[DatabricksServingEndpoint(endpoint_name="my_endpoint")]
)

# User policy: API scopes for OBO access
user_policy = UserAuthPolicy(api_scopes=[
"serving.serving-endpoints",
"vectorsearch.vector-search-endpoints",
"vectorsearch.vector-search-indexes"
])

# Log the agent with both policies
with mlflow.start_run():
mlflow.pyfunc.log_model(
name="agent",
python_model="agent.py",
auth_policy=AuthPolicy(
system_auth_policy=system_policy,
user_auth_policy=user_policy
)
)

Security considerations

Consider the following security considerations before enabling on-behalf-of-user authorization with agents:

  • Expanded resource access: Agents can access sensitive resources on behalf of users. While scopes restrict APIs, endpoints might allow more actions than your agent explicitly requests.

    For example, the serving.serving-endpoints API scope grants an agent permission to run a serving endpoint on behalf of the user. However, the serving endpoint itself may have access to additional API scopes that the original agent isn't authorized to use.

Example notebook

The following notebook shows you how to create an agent with vector search using on-behalf-of-user authorization.

On Behalf of User Authorization with Vector Search

Open notebook in new tab