Investigating Workflow security issues

Many of us might have encountered the below error messages when trying to run a newly created workflow. I would like to provide this neat troubleshooting tip with the below code snippet for investigating workflow security issues.

Stopped (error): X++ Exception: Work item could not be created. 
Insufficient rights for user %1.

In most of the cases it is due to the lack of security access for the execution account on a menu item, for which we could add a couple of lines of code to resolve the problem.

Change \AOT\Classes\SysWorfklowDocument\assertAsUser method and for each fork of menu item type you may add the entry point in a security privilege or role, for which you need to provide access for on the user account you have been using. That means for each section of workflowPermission you need to add the appropriate menu item in the error log.

    if (workflowPermission.parmDisplayMenuItem())
    {
        permission = SysWorkflowDocument::assertMenuItem(workflowPermission.parmDisplayMenuItem(), MenuItemType::Display);
        if (!permission)
        {
            error(strFmt('Entry point %1', workflowPermission.parmDisplayMenuItem()));
            return [permission, buf2Con(rec)]; // buf2Con() needed to support packing buffers participating in SC/sc hierarchies
        }
    }

Also you need to add the following pieces to \AOT\Classes\SysWorkflowEventDispatcher\onWorkItemCreate() method:

    if (workflowPermission.parmDisplayMenuItem())
    {
        permission = SysWorkflowDocument::assertMenuItem(workflowPermission.parmDisplayMenuItem(), MenuItemType::Display);
        if (!permission)
        {
            error(strFmt('Entry point %1', workflowPermission.parmDisplayMenuItem()));
            return [permission, buf2Con(rec)]; // buf2Con() needed to support packing buffers participating in SC/sc hierarchies
        }
    }

(...)
 
    if (!SysWorkflowHelper::userHasPermission(
        _workItemContext.parmWorkflowCorrelation().parmWorkflowContext(),
        stepTable.workflowElementTable().workflowVersionTable().workflowTable().TemplateName,
        sysDictWorkflowElement.actionMenuItem(completingOutcome),
        menuItemName,
        user))
    {
        error(strFmt('Entry point %1 / Menu item action %2', menuItemName, sysDictWorkflowElement.actionMenuItem(completingOutcome)));
        throw error(strfmt("@SYS109561", user));
    }

Using the above changes you will be able to set up the missing security pieces easily by taking a look at the workflow execution history, where the infolog in the tracking history will contain the entry points causing the issues.

External references for the same issue:

https://workflowax.wordpress.com/2012/05/02/x-exception-workitem-could-not-be-created/

http://axfaq.blogspot.hu/2014/08/workflow-ax-2012-insufficient-rights.html