elsa-workflows/elsa-core · error · HubException

Access denied.

Error message

Access denied.

What it means

Elsa's OpenTelemetry SignalR hub throws this HubException when a connecting client is not authenticated or lacks the ReadOpenTelemetry permission, as checked by EnsureCanReadOpenTelemetry before subscribing to live OpenTelemetry streams. The library guards telemetry data behind the shared PermissionEvaluator so only authorized users can read it.

Solutions

  1. Ensure the SignalR client supplies a valid access token via AccessTokenFactory or cookie auth before starting the connection.
  2. Grant the user/role the ReadOpenTelemetry permission in your Elsa permission configuration.
  3. Verify claims are populated by your auth middleware (check Context.User.IsAuthenticated server-side).
  4. Wrap hub invocation in try-catch and surface a clear 'sign in required' message to the UI.

Example fix

// before
await connection.start();
await connection.invoke('SubscribeAsync');
// after
const connection = new HubConnectionBuilder()
  .withUrl('/hubs/opentelemetry', { accessTokenFactory: () => getToken() })
  .build();
await connection.start();
await connection.invoke('SubscribeAsync');
Defensive patterns

Strategy: try-catch

Validate before calling

const isAuthenticated = user?.identity?.isAuthenticated === true; const canRead = isAuthenticated && user.permissions.includes('OpenTelemetry.Read'); if (!canRead) throw new Error('Sign in with OpenTelemetry read permission before subscribing.');

Type guard

function canReadTelemetry(user) { return Boolean(user?.identity?.isAuthenticated) && Array.isArray(user?.permissions) && user.permissions.includes('OpenTelemetry.Read'); }

Try / catch

try { await connection.invoke('SubscribeAsync'); } catch (e) { if (e?.message === 'Access denied.') redirectToLogin(); else throw e; }

Prevention

When it happens

Trigger: Calling SubscribeAsync on the OpenTelemetryHub while Context.User is null or unauthenticated, or while the authenticated user has no ReadOpenTelemetry permission per PermissionEvaluator.Shared.

Common situations: Forgetting to send the auth token with the SignalR handshake (accessTokenFactory missing), the user's roles/claims not granting the OpenTelemetry read permission, or anonymous access to the hub endpoint after upgrading Elsa where authorization was newly enforced.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/836839050bbd39c2. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Diagnostics.OpenTelemetry/RealTime/OpenTelemetryHub.cs:48

        await base.OnDisconnectedAsync(exception).ConfigureAwait(false);
    }

    private static OpenTelemetryTraceFilter ValidateFilter(OpenTelemetryTraceFilter? filter)
    {
        filter ??= new();

        if (filter.From is { } from && filter.To is { } to && from > to)
            throw new HubException("The OpenTelemetry filter 'from' timestamp must be earlier than or equal to 'to'.");

        return filter;
    }

    private void EnsureCanReadOpenTelemetry()
    {
        var user = Context.User;

        if (user?.Identity?.IsAuthenticated != true || !PermissionEvaluator.Shared.HasPermission(user, ReadOpenTelemetry))
            throw new HubException("Access denied.");
    }
}

View on GitHub (pinned to fe9217bdfa)