Skip to main content

Automating Operations with Webhook Apps

The FlyteWebhookAppEnvironment provides a "batteries-included" FastAPI application designed to automate common Flyte operations. Instead of writing custom boilerplate to trigger tasks or monitor runs from external systems, you can deploy this pre-configured environment to expose a secure REST API for your Flyte project.

Basic Setup

When you need to trigger Flyte tasks from a CI/CD pipeline or a external dashboard, you can instantiate a FlyteWebhookAppEnvironment and serve it using flyte.serve(). By default, this enables all available endpoints, including task execution, run monitoring, and app management.

import flyte
from flyte.app.extras import FlyteWebhookAppEnvironment

# Create the webhook environment
webhook_env = FlyteWebhookAppEnvironment(
name="ops-webhook",
title="Operations Webhook",
description="API for triggering and monitoring Flyte tasks",
resources=flyte.Resources(cpu=1, memory="512Mi"),
)

# Deploy the webhook
if __name__ == "__main__":
flyte.serve(webhook_env)

Once deployed, the app runs a Uvicorn server (defaulting to port 8080) that handles incoming requests by translating them into Flyte remote calls.

Endpoint Configuration

To minimize the attack surface or simplify the API, you can restrict which endpoints are enabled. flyte-sdk allows you to filter by broad functional groups or by individual endpoints.

Using Endpoint Groups

The endpoint_groups parameter accepts a list of predefined categories:

  • core: Health checks and user info (/health, /me)
  • task: Task operations (/run-task, /task)
  • run: Run operations (/run, /run/{name}/io, /run/{name}/abort)
  • app: App management (/app/{name}, /app/{name}/activate, etc.)
  • trigger: Trigger management (/trigger/...)
  • build: Image building (/build-image)
  • prefetch: HuggingFace model prefetching
# Enable only core and task operations
webhook_env = FlyteWebhookAppEnvironment(
name="task-only-webhook",
endpoint_groups=["core", "task"],
)

Individual Endpoint Selection

If you need even finer control, use the endpoints parameter to specify exact routes. Note that endpoints and endpoint_groups are mutually exclusive; providing both will raise a ValueError.

# Enable only specific routes
webhook_env = FlyteWebhookAppEnvironment(
name="minimal-webhook",
endpoints=["health", "run_task", "get_run"],
)

Security and Access Control

The FlyteWebhookAppEnvironment implements security at two levels: authentication for the caller and allow-listing for the Flyte entities being accessed.

Authentication Passthrough

By default, requires_auth=True. The environment uses FastAPIPassthroughAuthMiddleware (found in src/flyte/app/extras/_auth_middleware.py) to extract credentials from the incoming request.

The middleware looks for:

  1. An Authorization header (e.g., Bearer <token>)
  2. A Cookie header

These credentials are automatically injected into the Flyte context using flyte.remote.auth_metadata. This ensures that the webhook performs operations on behalf of the caller, respecting their specific Flyte permissions. If no credentials are found, the app returns a 401 Unauthorized response.

Entity Allowlists

To prevent the webhook from being used to run unauthorized tasks or manage sensitive apps, you can define allowlists. The environment checks these lists before executing any handler.

  • task_allowlist: Supports formats like domain/project/name, project/name, or just name.
  • app_allowlist: A list of allowed app names.
  • trigger_allowlist: Supports task_name/trigger_name or just trigger_name.
webhook_env = FlyteWebhookAppEnvironment(
name="restricted-webhook",
task_allowlist=["production/my-project/allowed-task", "utility-task"],
app_allowlist=["my-safe-app"],
)

If a request targets an entity not in the allowlist, the app returns a 403 Forbidden response.

Internal Implementation

Internally, FlyteWebhookAppEnvironment uses a private registry of _EndpointConfig objects to map route names to their HTTP methods, paths, and handlers.

# Internal registry structure in src/flyte/app/extras/_webhook_app.py
endpoint_registry: dict[WebhookEndpoint, _EndpointConfig] = {
"run_task": _EndpointConfig(
method="POST",
path="/run-task/{domain}/{project}/{name}",
handler=run_task,
),
# ... other endpoints
}

When the environment is initialized, _create_webhook_app filters this registry based on your configuration and constructs a standard fastapi.FastAPI instance. This instance is then served by Uvicorn within the _fastapi_app_server method.

Constraints and Limitations

  • Self-Reference Restriction: To prevent accidental loops or self-destruction, the app management endpoints (/app/{name}/activate, etc.) will reject requests where the target name matches the webhook's own name with a 400 Bad Request.
  • Reserved Ports: Flyte reserves several ports for internal use (8012, 8022, 8112, 9090, 9091). Attempting to configure the webhook to use these ports will result in a failure.
  • Uvicorn Dependency: The environment requires uvicorn to be installed. If it is missing when _fastapi_app_server is called, it will raise a ModuleNotFoundError.
  • Image Defaults: By default, the environment uses a Debian-based image with fastapi and uvicorn pre-installed via flyte.Image.from_debian_base().with_pip_packages("fastapi", "uvicorn").