Skip to content
English
  • There are no suggestions because the search field is empty.

10.01 What the Workflows Extra Does

The Workflows Extra adds event-driven, visual workflow definitions to SimpleRisk. Workflows attach to triggers (a risk created, a control updated, a document deleted), execute a sequence of actions (send an email, post to Slack, fire a webhook), and support branches, delays, and waits. Build workflows in a visual editor; define your own; execute on every matching event.

Requires: Workflows Extra

The Workflows Extra adds event-driven workflow execution to SimpleRisk. The Extra is at simplerisk/extras/workflows/. The Extra's UI is at /admin/workflows.php; supporting code is in simplerisk/includes/workflows.php and simplerisk/includes/workflows/executor.php.

Why this matters

A risk register that "submits a risk and the right people are emailed and the risk goes into the right approval queue" sounds straightforward but is operationally complex. Different programs want different recipients for different events; some want stage gates ("can't move to Mitigation Planning until two reviewers approve"); some want integrations ("post a Slack message when a Critical risk is filed"); some want delayed notifications ("if no one's reviewed this in 3 days, escalate"). Without configurable workflows, programs either accept SimpleRisk's defaults or build the logic outside SimpleRisk in a separate automation tool.

The Workflows Extra is SimpleRisk's answer to this. Workflows attach to triggers (over 200 trigger events covering every major SimpleRisk entity); each workflow is a visual node graph (start → conditions → actions → branches → delays → end) you build in a builder UI. When the trigger event fires, the workflow runs against the affected entity. The result: programs encode their operational logic in SimpleRisk rather than externally.

The honest scope to know up front: the Workflows Extra is event-driven and action-driven, not state-machine-driven. A workflow doesn't define a state machine ("draft → in review → approved → closed") that a risk must pass through; it defines what happens when something happens. Programs that need true state-gating (a risk can't transition from Submitted to Mitigated without an approval action) implement that with workflow actions plus operational discipline, not with built-in state-machine constructs.

The other thing worth knowing: the action catalog is communications-focused. Built-in actions are mostly send-something: send an email (with optional template), send a webhook, post to Slack, post to Microsoft Teams. There are also branch nodes (conditional routing), delay nodes (wait N hours/days), and wait-for-event nodes (block until a downstream event occurs). What the action catalog doesn't include: arbitrary database mutations, complex business-logic operations, calls into other parts of SimpleRisk's API. For those, you'd typically use a webhook action to dispatch to an external integration that performs the operation.

The third thing: workflows are JSON-defined. The visual builder produces JSON (the node graph) that's stored in workflow_definitions.definition. This is visible to operators with database access; integrations or scripts can also read and write workflow definitions directly via the database (with appropriate care).

How frameworks describe this

Operational workflow automation is core to NIST CSF v2.0's Detect / Respond / Recover functions and to ITIL's incident-response practices. The frameworks don't prescribe specific tools; they expect that programs have documented response and notification procedures and execute against them consistently. The Workflows Extra is one way to encode those procedures in the platform that holds the risk register, ensuring consistent execution.

How SimpleRisk implements this

The data model

Three main tables:

  • workflow_definitions — the workflow definitions themselves. Columns: id, name, description, trigger_type (e.g., risk.created, control.updated), trigger_conditions (JSON: additional filters), definition (JSON: the node graph), enabled (boolean), system_workflow (boolean: distinguishes Extra-shipped workflows from operator-created), created_by (user id).
  • workflow_executions — execution instances. One row per workflow firing. Columns: id, workflow_id, entity_type, entity_id, status (pending/in_progress/success/failed), context (JSON: variables in scope for this execution), current_node (which node the execution is at, for resumable execution), started_at, completed_at, resume_at (for delay nodes that pause and resume).
  • workflow_email_templates — email body templates the send-email action references. System templates ship with the Extra; operators can add custom templates.

Plus workflow_step_outputs for storing per-step output (used in subsequent nodes via variable substitution).

The trigger catalog

Triggers are well-defined event types. The full catalog (200+ events) is in get_workflow_trigger_catalog() in simplerisk/includes/workflows.php. Common triggers:

  • Risk lifecycle: risk.created, risk.updated, risk.deleted, risk.closed, risk.reviewed, risk.commented, risk.mitigated.
  • Mitigation lifecycle: mitigation.created, mitigation.updated, mitigation.deleted.
  • Compliance: framework.created, framework.updated, control.created, control.updated, audit.initiated, audit.completed.
  • Document: document.created, document.updated, document.deleted, document.approved, document.expired.
  • Asset: asset.created, asset.updated, asset.deleted.

When the corresponding event happens in SimpleRisk, the workflow executor checks for active workflows matching the trigger; for each match, it queues a workflow execution.

Trigger conditions

A workflow can have additional filters beyond the trigger event. For example: risk.created triggers the workflow only if the risk's calculated_risk is above a threshold, or if it's in a specific category. Conditions are evaluated when the trigger fires; non-matching events skip the workflow.

The conditions are JSON expressions stored in workflow_definitions.trigger_conditions. The visual builder produces them; operators with deeper needs can author them in raw JSON.

The node graph

Each workflow's definition field is a JSON node graph:

  • Start node — the entry point.
  • Action nodes — perform an action (send_email, send_webhook, send_slack, send_teams).
  • Branch nodes — evaluate a condition and route to one of several downstream nodes.
  • Delay nodes — pause execution for N seconds/minutes/hours/days, then resume.
  • Wait nodes — pause execution until a downstream event fires (e.g., "wait until this risk is closed").
  • End node — terminates the workflow.

Edges connect nodes. The executor walks the graph from start, executing each node in turn, branching where needed, pausing at delays.

The execution lifecycle

When a trigger event fires:

  1. The executor queries workflow_definitions for active workflows matching the trigger.
  2. For each match, it evaluates trigger_conditions against the event context.
  3. For matching workflows, it inserts a workflow_executions row with status pending.
  4. A background worker picks up the pending execution, sets status to in_progress, and walks the node graph.
  5. Each action's output is recorded in workflow_step_outputs; subsequent nodes can reference outputs via variable substitution.
  6. Delay nodes set resume_at and pause; the worker picks up paused executions when their resume time arrives.
  7. The executor completes (status success) or fails (status failed with an error message).

For long-running or delayed workflows, the execution row persists across worker invocations.

Built-in vs custom workflows

The Extra ships some system_workflow definitions for common patterns (notifications on standard events). These are re-enabled on each activation; operators can disable them or override them with custom workflows.

Custom workflows are defined by operators in the visual builder. There's no inherent limit on the number of workflows; complex programs can run dozens. Performance is bounded by the cron worker; high-frequency triggers with expensive actions can backlog.

What the Workflows Extra doesn't do

  • State-machine enforcement — workflows trigger on events but don't gate state transitions. A risk doesn't get blocked from moving to a different state because a workflow hasn't completed.
  • Arbitrary business logic — the action catalog is communications-focused. For complex business logic, dispatch via webhook to an external service.
  • Synchronous workflows — execution is asynchronous; the user submitting a risk doesn't wait for the workflow to complete.
  • Cross-system event correlation — workflows trigger on events within SimpleRisk only; events from external systems (Jira, ticket systems) need to inject into SimpleRisk via the API or the Jira Extra's webhook.
  • A/B testing or staged rollout of workflows — a workflow is enabled or not; there's no "this workflow runs for 10% of risks."

Common pitfalls

A handful of patterns recur with the Workflows Extra.

  • Defining workflows without testing the triggers. Workflows fire on real events. Test in non-production with synthetic events to see if they execute as designed.

  • Stacking many workflows on the same trigger. Each fires independently; cumulative latency and downstream noise add up. Consolidate where reasonable.

  • Using delays for long pauses (days or weeks) and not handling SimpleRisk upgrades. Long-running executions span maintenance windows; upgrades should preserve execution rows but verify on each upgrade.

  • Building workflows that reference fields that get renamed or removed. Workflow JSON references field names; if a custom field is renamed, references break.

  • Using webhooks to call back into SimpleRisk. A workflow that fires a webhook to a script that calls the SimpleRisk API to modify the same record can produce loops. Watch for self-triggering.

  • Not monitoring failed executions. workflow_executions.status = 'failed' is the signal; without monitoring, failures pile up unnoticed.

  • Treating workflows as a substitute for documented procedures. The procedure document explains intent; the workflow executes consistently. Both are needed; one without the other is fragile.

  • Building workflows in production without a deployment pipeline. Workflow JSON is configuration; treat it like configuration. Export, version-control, deploy via your normal change-management process where reasonable.

  • Forgetting that the worker has to run. Workflow executions are queued; without the cron worker (cron_queue_worker.php), they never execute. See The Cron Jobs.

  • Sending high-volume notifications via workflows. A workflow that sends a Slack message on every risk update produces noise. Tune to the events that genuinely warrant notification.

Related