Skip to main content

Securing Interactive Apps

When you build an interactive app in flyte-sdk, you often need the app to perform actions on behalf of the user who is accessing it. The FastAPIPassthroughAuthMiddleware automates this by extracting authentication credentials from incoming HTTP requests and injecting them into the Flyte context.

Basic Setup

To secure your app, you must initialize Flyte in "passthrough" mode and add the middleware to your FastAPI instance. This is typically done within the FastAPI lifespan to ensure the Flyte client is ready before the app starts receiving requests.

from contextlib import asynccontextmanager
from fastapi import FastAPI
import flyte
from flyte.app.extras import FastAPIPassthroughAuthMiddleware

@asynccontextmanager
async def lifespan(app: FastAPI):
# Initialize Flyte with passthrough authentication
# This allows the app to use the caller's credentials
await flyte.init_passthrough.aio(
project=flyte.current_project(),
domain=flyte.current_domain(),
)
yield

app = FastAPI(lifespan=lifespan)

# Add middleware to automatically handle auth headers
app.add_middleware(FastAPIPassthroughAuthMiddleware)

Excluding Public Endpoints

If your app has public endpoints that do not require authentication (such as health checks or documentation), use the excluded_paths parameter. Requests to these paths will bypass the authentication check and will not return a 401 response if headers are missing.

app.add_middleware(
FastAPIPassthroughAuthMiddleware,
excluded_paths={"/health", "/docs", "/openapi.json"}
)

@app.get("/health")
async def health():
return {"status": "ok"}

Using Custom Authentication Headers

By default, FastAPIPassthroughAuthMiddleware looks for Authorization and Cookie headers. If your environment uses a non-standard header for authentication, you can configure a custom extractor using the extract_custom_header static method.

from flyte.app.extras import FastAPIPassthroughAuthMiddleware

# Create an extractor for a custom 'X-Flyte-Token' header
token_extractor = FastAPIPassthroughAuthMiddleware.extract_custom_header("x-flyte-token")

app.add_middleware(
FastAPIPassthroughAuthMiddleware,
header_extractors=[
token_extractor,
FastAPIPassthroughAuthMiddleware.extract_authorization_header
]
)

Verifying Authenticated Identity

Once the middleware is active, any Flyte SDK call made within a route handler will automatically use the credentials from the request. You can verify the identity of the caller using remote.User.get.aio().

import flyte.remote as remote
from fastapi import FastAPI, HTTPException

@app.get("/me")
async def get_current_user():
try:
# The middleware has already set the auth context
user = await remote.User.get.aio()
return {
"subject": user.subject(),
"name": user.name(),
}
except Exception:
raise HTTPException(status_code=401, detail="Could not verify user")

Executing Tasks with User Identity

The primary benefit of passthrough authentication is the ability to launch Flyte tasks or workflows that execute with the permissions of the user calling your API.

import flyte
import flyte.remote as remote

@app.post("/trigger-job")
async def trigger_job(payload: dict):
# Fetch a task definition
task = remote.Task.get(
project="my-project",
domain="development",
name="my_task"
)

# This execution is launched using the caller's identity
execution = await flyte.run.aio(task, **payload)

return {"execution_id": execution.name, "url": execution.url}

Implementation Details

  • Automatic 401 Responses: If a request is made to a non-excluded path without any valid authentication headers, the middleware immediately returns a 401 Unauthorized JSON response with a WWW-Authenticate: Bearer header.
  • Thread and Async Safety: FastAPIPassthroughAuthMiddleware uses Python contextvars via the flyte.remote.auth_metadata context manager. This ensures that authentication metadata is isolated to the specific request and is safe for concurrent async operations.
  • Lifespan Requirement: You must call flyte.init_passthrough.aio() (or the synchronous flyte.init_passthrough()) before the middleware processes requests. Without this initialization, the Flyte client will not know to look for the metadata injected by the middleware.