Portal Community

Execution Isolation

Isolation BoundaryGuarantee
Same workflow, different executionsCompletely independent ExecutionMemory instances. Concurrent runs of the same workflow cannot read each other's nodeOutputs or globalVariables.
Different workflows, same tenantCompletely independent. ExecutionMemory is scoped to executionId, not processId.
Different tenantsCompletely independent. TenantId is baked into ExecutionMetadata at creation and verified on every HIL resume path.

Tenant Verification on Resume

When a suspended execution is resumed, the system verifies that the acting user's tenant matches the tenant recorded in the serialized ExecutionMetadata. A cross-tenant resume attempt is rejected before the memory is deserialized.

// WorkflowExecutionService.ResumeAsync — tenant verification
var suspended = await _repo.GetSuspendedExecutionAsync(executionId, ct);

// Check tenant before deserializing
if (suspended.TenantId != _tenantContext.TenantId)
{
    _logger.LogWarning("Cross-tenant resume attempt blocked. ExecutionId={ExecutionId}", executionId);
    throw new UnauthorizedException("Access denied");
}

// Safe to deserialize now
var memory = _serializer.Deserialize(suspended.ExecutionMemoryJson);

ExecutionMemory Does Not Enforce Tenant At Read Time

The in-memory ExecutionMemory object itself does not enforce tenant checks on GetNodeOutput calls — it is a plain in-memory dictionary. The tenant boundary is enforced at the layer that creates and dispatches the memory:

PII and Sensitive Data Guidance

Data TypeGuidance
PII (names, emails, IDs)ExecutionMemory is ephemeral and in-process — acceptable to store for intra-execution use. However, if the execution involves a HIL node, it will be serialized to the database. Apply PII classification rules to the serialized form.
Authentication tokens or API keysNever store in ExecutionMemory. Use ICredentialResolver at execution time — do not cache credentials in nodeOutputs.
Financial amountsAcceptable — they are structured data. Ensure they are passed by value, not by reference to a mutable object.

Node Inspector Exposure

The Node Inspector tab in the Observer Panel displays the inputData and outputData for nodes in a completed or running execution. These values come from a snapshot of ExecutionMemory.nodeOutputs captured by the engine after each node runs. Users with execution:view permission on the process can see this data — design your output accordingly if it contains sensitive values.

ExecutionMemory is process-local. It never leaves the server process except when serialized for HIL suspension. It is not logged, not transmitted over SignalR, and not accessible via the API during a live execution. The only time its contents become external is when the Node Inspector API reads a snapshot of nodeOutputs for the inspector display.