Skip to content

GET /elsa/api/workflow-definitions is always tenant agnostic when using MongoDb package #6913

@franklinthor

Description

@franklinthor

Description

When calling GET /elsa/api/workflow-definitions?versionOptions=Latest with a specific tenant, the response includes all workflow definitions across tenants instead of being scoped to the requested tenant. In other words, the endpoint behaves tenant-agnostic even when a tenant is specified.

This appears to happen because the API path ends up using MongoWorkflowDefinitionStore.FindSummariesAsync<TOrderBy>(....PageArgs pageArgs...) which directly queries the Mongo collection and builds the projection without passing the TenantAgnostic flag through MongoDbStore (which normally enforces tenancy). As a result, tenancy filtering is never applied.

Observed code paths:

// Elsa.MongoDb.Modules.Management.MongoWorkflowDefinitionStore
public async Task<Page<WorkflowDefinitionSummary>> FindSummariesAsync<TOrderBy>(
    WorkflowDefinitionFilter filter, 
    WorkflowDefinitionOrder<TOrderBy> order, 
    PageArgs pageArgs, 
    CancellationToken cancellationToken = default)
{
    var collection = mongoDbStore.GetCollection();
    var queryable = Order(Filter(collection.AsQueryable(), filter), order);
    var count = queryable.LongCount();
    var mongoQueryable = queryable.Paginate(pageArgs)!;
    var documents = await mongoQueryable
        .Select(ExpressionHelpers.WorkflowDefinitionSummary)
        .ToListAsync(cancellationToken);

    return Page.Of(documents, count);
}

// Filter just calls filter.Apply(queryable) without tenancy scoping:
private IQueryable<WorkflowDefinition> Filter(IQueryable<WorkflowDefinition> queryable, WorkflowDefinitionFilter filter)
{
    return filter.Apply(queryable)!;
}

WorkflowDefinitionFilter.Apply(...) does not add any tenant criteria. Other store methods go through mongoDbStore.FindAsync/FindManyAsync/CountAsync(..., tenantAgnostic) which do apply tenancy, but this summaries method bypasses it.

Steps to Reproduce

  1. Setup two tenants (e.g., tenant-a, tenant-b) with separate workflow definitions. Ensure there’s at least one workflow definition unique to each tenant.
  2. Authenticate and include the tenant in your request (e.g., via header or query param, depending on your tenancy
  3. Call the endpoint:
// Adjust depending how the application handles tenancy (mine is included in the JWT token)
curl -X GET \
  -H "Authorization: Bearer <token>" \
  "https://<host>/elsa/api/workflow-definitions?versionOptions=Latest"
  1. Attachments:

    • Sample Project: Should have the same behavior in all projects since it's a base elsa management endpoint
  2. Reproduction Rate:
    Every time

  3. Video/Screenshots:
    N/A

  4. Additional Configuration:

    • Mention any specific settings, features, or configurations that need to be enabled or present to reproduce the issue.

Expected Behavior

The endpoint should only return workflow definitions for the specified tenant (unless TenantAgnostic is explicitly requested).

Actual Behavior

The endpoint returns workflow definitions across all tenants, ignoring the current tenant context.

Screenshots

N/A

Environment

  • Elsa Package Version: 3.5.0
  • Operating System: Windows 11

Log Output

No errors logged. The issue is functional: incorrect result set due to missing tenant filter application.

Troubleshooting Attempts

  • Verified that other store methods (e.g., FindManyAsync, FindAsync) respect tenancy because they go through mongoDbStore.*(..., tenantAgnostic).
  • Confirmed the issue occurs specifically via the summaries code path used by the controller for GET /elsa/api/workflow-definitions.
  • Reproduced with multiple tenants and distinct per-tenant definitions.

Additional Context

  • The summaries overload bypasses mongoDbStore helpers that apply tenant filtering, causing potential cross-tenant data exposure in listings.
  • The non-generic FindSummariesAsync has a similar pattern and may also be affected.

Related Issues

Couldn’t find a matching open issue; please link if one exists.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions