---
title: "Assigning Tasks to People — Spiff Arena 0.1 documentation"
description: "This guide explains how to assign tasks to specific users, roles, or groups in your BPMN workflows."
source_url: https://spiff.works/docs/spiff-arena/how_to_guides/building_diagrams/assigning_tasks_to_people.html
---

☰ Menu

# Assigning Tasks to People[](#assigning-tasks-to-people "Link to this heading")

This guide explains how to assign tasks to specific users, roles, or groups in your BPMN workflows.

## Overview[](#overview "Link to this heading")

In SpiffWorkflow, task assignment is primarily managed through **Lanes** within your BPMN diagrams. Lanes allow you to:

- Assign tasks to specific roles or departments
- Route work to the appropriate personnel
- Control who can execute particular tasks in a workflow

## Using Lanes for Task Assignment[](#using-lanes-for-task-assignment "Link to this heading")

Lanes are subdivisions within a Pool that assign activities to specific roles, systems, or departments.
When a human task is placed within a Lane, only users associated with that Lane can complete the task.

![Lanes Example](../../_images/lanes_1.png)

### Basic Lane Setup[](#basic-lane-setup "Link to this heading")

1. Create a Pool in your BPMN diagram
2. Add Lanes to represent different roles (e.g., “Requester”, “Manager”, “Approver”)
3. Place human tasks within the appropriate Lane
4. Configure the Lane with a name and unique ID

| Field | Description |
| --- | --- |
| **Name** | A descriptive label representing the role (e.g., “Manager”) |
| **ID** | A unique identifier for the Lane (e.g., “lane\_manager”) |

Note

Each Pool requires Lane configuration, even if it contains just a single Lane.

## Methods to Assign Lane Owners[](#methods-to-assign-lane-owners "Link to this heading")

There are three primary methods to specify who owns a Lane (i.e., who can complete tasks in that Lane):

### Method 1: Using User Groups[](#method-1-using-user-groups "Link to this heading")

Lane owners can be specified using predefined user groups configured in the system.

User groups are typically defined in a YAML configuration file:

```
groups:
  admin:
    users:
      - user1@spiffworkflow.org
      - user2@spiffworkflow.org
  reviewers:
    users:
      - user3@spiffworkflow.org
      - user4@spiffworkflow.org
```

When a Lane name matches a group name in the configuration, users in that group can complete tasks in the Lane.

For more information on configuring user groups, see the [permissions documentation](../deployment/manage_permissions.html).
You can also configure the system to respect group membership defined through your OpenID provider.
See [Configuring an OpenID Provider](../deployment/configure_openid_provider.html).

### Method 2: Using Script Tasks[](#method-2-using-script-tasks "Link to this heading")

Script tasks enable dynamic assignment of lane owners within the workflow.
You can specify the lane owners directly in the workflow logic, and you might choose this path if the task assignment logic is more nuanced than simply assigning the members of a specific group.

```
# Script task to assign lane owners
lane_owners = {
    "Reviewer": ["user1@example.com", "user2@example.com"]
}
```

The dictionary maps Lane names to lists of users who can complete tasks in that Lane.

Note

Specifying a user group in the `lane_owners` dictionary in a script task does not require it to previously exist in the database.

### Method 3: Group Assignment with `group:` Prefix[](#method-3-group-assignment-with-group-prefix "Link to this heading")

For more flexible task assignment, you can assign entire groups to lanes using the `group:` prefix in your script tasks. This approach allows you to:

- Assign tasks to multiple groups simultaneously
- Mix group assignments with individual user assignments
- Handle users who haven’t signed in yet (they’ll be assigned automatically when they sign in)
- Override the default lane name group assignment

```
# Script task with group assignment
lane_owners = {
    "Reviewer": [
        "group:senior-reviewers",    # Assign to entire group
        "group:technical-leads",     # Multiple groups allowed
        "john@company.com",          # Mix with individual users
        "newbie@company.com"         # User will be assigned when they sign in
    ]
}
```

#### Key Features[](#key-features "Link to this heading")

**Group Assignment**: Use `group:group_name` to assign an entire group to a lane. All current members of the group will be able to complete tasks in that lane.

**Dynamic Membership**: When users are added to or removed from groups, their task assignments are automatically updated for active tasks.

**Mixed Assignment**: You can combine group assignments with individual user assignments in the same lane.

**Pending Users**: If you specify a username or email that doesn’t exist in the system yet, it will be stored and the user will be automatically assigned to relevant active tasks when they sign in.

**Group Override**: When you specify groups in `lane_owners`, the system uses only those groups (it doesn’t automatically include the lane name group).

```
# Example: Complex approval workflow
approval_lane_owners = {
    "Manager": ["group:managers", "ceo@company.com"],
    "Technical": ["group:senior-engineers", "group:architects"],
    "Finance": ["group:finance-team", "temp-consultant@company.com"]
}

lane_owners = approval_lane_owners
```

Important

When using group assignments, users who are added to the assigned groups after task creation can still complete the tasks. This enables dynamic team management without workflow disruption.

## Dynamic Task Assignment[](#dynamic-task-assignment "Link to this heading")

### Excluding the Process Initiator from Approvers[](#excluding-the-process-initiator-from-approvers "Link to this heading")

A common requirement is ensuring that the person who started a process cannot approve their own request.
Here’s how to implement this:

```
# Define the group identifier dynamically based on process data
group_identifier = "approvers"
group_members = get_group_members(group_identifier)

# Retrieve the process initiator's username
initiator = get_process_initiator_user()
initiator_username = initiator["username"]

# Exclude the initiator from the approvers' list if they are part of it
if initiator_username in group_members:
    group_members.remove(initiator_username)

# Assign the modified group list to the lane for task assignment
lane_owners = {"Approval": group_members}
```

### Getting Group Members Dynamically[](#getting-group-members-dynamically "Link to this heading")

You can use the `get_group_members()` function to fetch users belonging to a specific group:

```
group_members = get_group_members("approvers")
```

This is useful for:

- Sending notifications to specific groups
- Dynamic task assignment based on workflow conditions
- Building approval workflows with multiple potential approvers

### Determining the Current Task’s Lane[](#determining-the-current-task-s-lane "Link to this heading")

In pre/post scripts, you can determine which Lane the current task belongs to:

```
# Get the lane name as a string
lane_name = task.task_spec.lane

# Use the lane name to get group members for notifications
group_members = get_group_members(lane_name)
```

## Example: Petty Cash Request Process[](#example-petty-cash-request-process "Link to this heading")

This example demonstrates task assignment across different Lanes for a petty cash request workflow.

![Lanes and Pools Example](../../_images/lanes_pools_example_1.png)

### Process Flow[](#process-flow "Link to this heading")

1. **Start Event**: The workflow begins in the Requester Lane.
2. **User Task: Petty Cash Request** (Requester Lane):
   Collects the request details including amount and reason.

   ![Petty Cash Request Form](../../_images/lanes_pools_example_2.png)
3. **User Task: Approve Petty Cash** (Cashier Lane):
   The cashier reviews and approves the request.

   ![Approve Petty Cash Form](../../_images/lanes_pools_example_3.png)
4. **Manual Task: Display Output** (Requester Lane):
   Shows the approval result to the requester.

   ```
   Your petty cash request for {{amount}} has been approved by {{approved_by}}
   ```

   ![Display Output](../../_images/lanes_pools_example_4.png)

## Integrating with External Role Management[](#integrating-with-external-role-management "Link to this heading")

If you manage user roles in an external system (like an OpenID provider), you can:

1. Configure your OpenID system to include group/role information in user tokens
2. Configure the system to automatically use this information to add users to groups
3. Use this information in your BPMN diagrams, allowing you to map external roles to Lane assignments

## Related Topics[](#related-topics "Link to this heading")

- [Pools and Lanes Reference](../../reference/bpmn/pools_and_lanes.html)
- [Script Tasks](../../reference/bpmn/script_tasks.html)
- [Managing Permissions](../deployment/manage_permissions.html)
