← Back to Services

6.5 Workflow Approval Nodes

An approval node creates a durable WorkflowApproval, marks its execution log waiting, and pauses the WorkflowInstance. DefaultWorkflowApprovalManager validates responders, records immutable WorkflowApprovalResponse rows, updates the gate, and resumes the engine when the configured outcome is reached.

Approver types

approverType Main approverConfig Meaning
permission permission Members with an active role granting the named permission
role role Members with the named active role
member member_id One configured/resolved member
dynamic registered service plus resolver-specific fields Server-side resolver returns eligible member IDs
policy policyClass, policyAction, entityTable, entityIdKey Eligibility evaluated against a policy/resource context

Use WorkflowApproverResolverRegistry for dynamic resolvers so the designer sees safe metadata while the server retains class/method details. Direct class-name configuration exists for compatibility; new plugin integrations should register a stable resolver key.

Common node configuration

Use the designer/definition validator rather than relying on undocumented fields. The JSON definition and provider schema must agree.

Status and decisions

Approval statuses are pending, approved, rejected, expired, and cancelled. Response decisions are approve, reject, abstain, and request_changes. Use entity constants.

Eligibility is checked again when recording a response. Client-side eligible-approver lists and hidden controls are not security boundaries. Dynamic resolvers receive the persisted approval and must return tenant-local member IDs; a pinned current_approver_id further restricts who may respond.

Approval versus other waiting work

Do not create plugin-specific approval tables. Use approval context renderers to add safe domain context to the unified /approvals UI.

Multi-tenant and lifecycle rules

The definition/version, instance, approval, responses, members, and domain entity all belong to one tenant database. Workers must bind that tenant before deadlines, reassignment, or resumption. Cancellation/restart flows should preserve historical responses but ensure they never count toward a replacement gate.

Verification

Cover every approver type, active-window eligibility, required counts, parallel and serial-pick-next behavior, reassignment, duplicate/concurrent responses, reject/abstain/request-changes outcomes, cancellation/expiry, resolver failure, policy resource loading, context-expression validation, restart history, and tenant isolation.