Skip to content

Setup

Set up a local Bifrost environment for developing and debugging workflows

This guide shows you how to set up a local Bifrost environment for developing workflows using the bifrost-workspace project.

Running ./start.sh will start a complete Bifrost environment locally:

  • Azurite - Azure Storage emulator for tables, blobs, and queues
  • Bifrost API - The complete workflow engine and API (port 7071)
  • Bifrost Client - The web interface (port 4280)
  • Debugpy - Python debugger for setting breakpoints in workflows (port 5678)

Docker Desktop

Required to run the containerized Bifrost environment

VS Code

Recommended for debugging workflows with breakpoints (with Python extension)

Azure Resources

  • Entra ID App Registration
  • Key Vault (can use production)
  • Web PubSub (optional but recommended)

You’ll need an Entra ID App Registration for authentication. You can create a dedicated dev app registration or use your production one.

Create App Registration:

  1. Navigate to Entra Admin Center
  2. Go to App RegistrationsNew Registration
  3. Set the Redirect URI:
    • Platform: Web
    • URI: http://localhost:4280/.auth/login/aad/callback
  4. Under Certificates & Secrets, create a new client secret
  5. Under Authentication, enable ID tokens
  6. Copy your Application (client) ID, Tenant ID, and Client Secret for later

Your App Registration (not your user account) needs the Key Vault Secrets Officer role on your Key Vault.

Assign the Role:

  1. Navigate to your Key Vault in the Azure Portal
  2. Go to Access control (IAM)
  3. Click Add role assignment
  4. Select Key Vault Secrets Officer
  5. Assign to your App Registration (search by the app name or client ID)

Web PubSub enables real-time updates in the web interface. Without it, you’ll need to refresh the page to see workflow execution updates.

You can use your production Web PubSub instance or create a free-tier instance for development:

  1. In Azure Portal, create a new Web PubSub resource
  2. Select the Free tier (sufficient for development)
  3. Copy the Connection String from Keys section
  1. Clone the workspace repository:

    Terminal window
    git clone https://github.com/jackmusick/bifrost-workspace.git
    cd bifrost-workspace
  2. Copy the example environment file:

    Terminal window
    cp .env.example .env
  3. Edit .env with your credentials:

    Terminal window
    # Azure Entra ID (App Registration)
    ENTRA_TENANT_ID=your-tenant-id
    ENTRA_CLIENT_ID=your-app-client-id
    ENTRA_CLIENT_SECRET=your-app-client-secret
    # Azure Key Vault URL
    AZURE_KEY_VAULT_URL=https://your-vault-name.vault.azure.net/
    # Web PubSub (optional but recommended)
    WebPubSubConnectionString=your-connection-string
  4. Make start script executable:

    Terminal window
    chmod +x ./start.sh ./stop.sh
VariableRequiredDescription
ENTRA_TENANT_IDYesYour Entra ID tenant ID
ENTRA_CLIENT_IDYesApp Registration client ID
ENTRA_CLIENT_SECRETYesApp Registration client secret
AZURE_KEY_VAULT_URLYesKey Vault URL (can be production)
WebPubSubConnectionStringNoWeb PubSub connection string (free tier recommended)
ENABLE_DEBUGGINGNoEnable debugpy for breakpoints (default: true)
FUNCTIONS_WORKER_PROCESS_COUNTNoWorker processes (must be 1 when debugging, default: 1)

Simply run the start script:

Terminal window
./start.sh

The script will:

  1. Download the latest Bifrost type stubs for IDE autocomplete
  2. Check for .env file (prompts to create if missing)
  3. Start Docker services (Azurite + API + Client)
  4. Wait for services to become healthy
  5. Display access URLs and debugging instructions

Once started, you’ll have:

Create Python files in the /workspace directory. These files will be automatically mounted into the container.

workspace/hello_world.py
def run(context):
"""
Simple workflow example
Args:
context: OrganizationContext containing org, caller, execution_id
"""
print(f"Hello from workflow!")
print(f"Organization: {context.org.name if context.org else 'No org'}")
print(f"Caller: {context.caller.email}")
return {
"status": "success",
"message": "Workflow completed successfully"
}

See the Workflows Guide for more information on writing workflows.

One of the major benefits of local development is the ability to debug workflows with breakpoints.

  1. Ensure the environment is running:

    Terminal window
    ./start.sh
  2. Open the workspace in VS Code:

    Terminal window
    code .
  3. Set breakpoints in your Python workflow files by clicking in the gutter next to line numbers

  4. Start debugging: Press F5 or go to Run and DebugAttach to Docker Functions

  5. Trigger your workflow from the web interface at http://localhost:4280

  6. Debugger pauses at your breakpoints. You can now:

    • Inspect variables
    • Step through code line by line
    • Evaluate expressions in the Debug Console
    • Modify variables and continue execution

The workspace includes a pre-configured .vscode/launch.json that attaches to debugpy running on port 5678 inside the container.

Path Mappings:

  • Local: ${workspaceFolder}/workspace
  • Container: /mounts/workspace

Monitor what’s happening in your containers:

Terminal window
# All services
docker compose logs -f
# Just the API (workflow engine)
docker compose logs -f api
# Just the client (web interface)
docker compose logs -f client

When you’re done developing:

Terminal window
./stop.sh

Or manually:

Terminal window
docker compose down

Check if the required ports are already in use:

Terminal window
# Check for port conflicts
lsof -i :4280 # Client
lsof -i :7071 # API
lsof -i :5678 # Debugpy

Kill any conflicting processes or modify the ports in docker-compose.yml.

Verify your .env file has the correct:

  • ENTRA_CLIENT_ID
  • ENTRA_CLIENT_SECRET
  • ENTRA_TENANT_ID

And that your App Registration has:

  • Redirect URI: http://localhost:4280/.auth/login/aad/callback
  • ID tokens enabled

Ensure your App Registration (not your user) has the Key Vault Secrets Officer role:

Terminal window
# Check role assignments
az role assignment list --scope /subscriptions/{subscription-id}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault-name}

Look for your App Registration’s client ID with the b86a8fe4-44ce-4948-aee5-eccb2c155cd7 role (Key Vault Secrets Officer).

  1. Verify ENABLE_DEBUGGING=true in .env
  2. Verify FUNCTIONS_WORKER_PROCESS_COUNT=1 in .env
  3. Check debugpy is listening:
    Terminal window
    docker compose logs api | grep debugpy
  4. Restart the environment:
    Terminal window
    ./stop.sh && ./start.sh

Regenerate type stubs:

Terminal window
./start.sh # Downloads latest types automatically

Or manually download from GitHub Releases.