Chapter 4. Authorization Model for Workflows
4.1. Role-task planning algorithm
Figure 3 depicts the role-task planning algorithm. The algorithm first invokes the GenExecDependency() function to generate the execution dependency among tasks of the workflow W. The algorithm then invokes the recursive function RoleAssignment() to generate the set of all valid role-task assignments in the input workflow. If no valid role-task assignment is found, then the algorithm returns a failure; otherwise, it returns success. The tasks of the input workflow are recorded in a list, Tlist, ordered with a topological order according to the ordering dependency in the workflow. The algorithm uses RTplan to record a valid role-task activation plan, that is, a list of role-task assignments, (Ri, Ti), for each task Ti in Tlist. AllRTplans records the set of all valid assignments generated by the algorithm.
The RoleAssignment() function finds valid role assignments for current task by recursively finding role assignments for the next task in Tlist. Notably, the assignment of valid roles to current tasks must satisfy the constraints of SoD. The SoD verification must satisfy the constraints of execution-dependent SoD as specified in Chapter 3, since workflow tasks have execution-dependent relationships. When planning the activation of current task, the algorithm conducts SoD verification based on the duty-relationships among the current task and all previously assigned tasks. Notably, the assigned tasks are those activated before the current task during workflow execution, since tasks are planned (assigned) in topological order, according to the ordering dependency (control flow) of the workflow.
Algorithm The role-task planning algorithm Input: 1) workflow W;
2) capable_roles(Ti); the set of roles which have the capability to execute task Ti. 3) Tlist: a list of tasks with topological order in a workflow W
Output: Fail if no valid role-task assignment; Success, otherwise.
assigned_role(T): the role assigned to execute task T in an activation plan;
valid_roles(T): the set of roles that are valid (authorized) to execute task T;
RTplan: a valid role-task plan, i.e., a list of role-task assignment, <Ri, Ti>, of tasks in Tlist;
AllRTplans: a set of all valid RTplans;
begin
GenExecDependency(Tlist, W)
T1 = the first task of Tlist; AllRTplans = {}; RTplan = {};
for each task Ti ∈ Tlist do assigned(Ti) = False;
return RoleAssignment(T1);
end;
function RoleAssignment(Ti: task) : Boolean begin
Tk = NextTaskFromTaskList(Tlist, Ti);
R = ChooseNextRole(valid_roles(Ti));
while R is not Null do assigned_role(Ti) = R;
assigned(Ti) = True;
if Tk == Null then
{ RTplan = CreateNewRTplan(Tlist);
AddRoleTaskPlans(AllRTplans, RTplan);
result = Success; }
else if RoleAssignement(Tk) == Success then result = Success;
R = ChooseNextRole(valid_roles(Ti));
endwhile;
assigned(Ti) = False;
return result;
end
Figure 3. The role-task planning algorithm
Initially, valid_roles(Ti) is the set of roles that are capable to execute the current task Ti. According to the roles previously assigned to tasks and the SoD constraints, roles that are not valid to activate Ti are excluded from valid_roles(Ti). Considering each previously assigned task Tj, where Tj and Ti have execution-dependency (Tj∼ Ti), valid roles for task
Ti must exclude the role assigned to Tj that has a duty-conflict relationship with task Ti (Tj
⊕ Ti). Moreover, if Ti and Tj have a duty-supervising relationship, Ti f Tj, then valid roles of task Ti must have a higher position than the role assigned to Tj.
After the SoD verification has been conducted, valid_roles(Ti) is the set of roles that can validly activate the current task Ti. The while-loop considers each role in valid_roles(Ti) as a seed to explore possible role-task activation plans by recursively finding role assignments for the subsequent task Tk in Tlist. If the current task is the last task in Tlist, then a valid role-task assignment of the workflow has been found. A new RTplan, an <assigned_role(Tj), Tj> list, is created to record the role assignments according to the assigned_role(Tj), for each task Tj in Tlist. The RTplan is added to the AllRTplans. The algorithm finds all valid role-task plans of a workflow. If only one role-task plan is needed, then the statement “result = Success” in the while-loop can be changed to “return Success”. The algorithm then returns only one valid role-task plan.
The complexity of the role-task planning algorithm is O(mn) in worst case, which m is the maximum number of capable_roles of all tasks and n is the number of tasks in the workflow.
4.1.1. Execution-dependency considering the AND/XOR split structure
The GenExecDependency() function can be implemented by simply assigning execution dependency to all tasks of the workflow W, without considering the AND/XOR split structure of the workflow. The AND-SPLIT structure splits the workflow execution into multiple parallel paths (tasks) that are all executed, while the XOR-SPLIT structure splits the workflow execution into multiple mutually exclusive alternative paths (XOR-paths), only one of which is executed. Tasks in different XOR-paths are not executed in the same workflow instance. Thus, no execution dependency exists among tasks in different XOR paths. Further checking can be conducted to remove the execution dependency from tasks in different XOR-paths. Our current implementation checks the AND/XOR split structure to determine execution dependency. Moreover, as described in Chapter 3, execution dependency among tasks can be derived from the accessed data objects. If task Ti accesses data objects that are created/modified by task Tj, then the execution of Ti depends on the execution of Tj. The GenExecDependency() function can also be further implemented by checking the accessed data objects to determine the