{"record":{"id":"836839050bbd39c2","repo":"elsa-workflows/elsa-core","slug":"access-denied-opentelemetryhub","errorCode":null,"errorMessage":"Access denied.","messagePattern":"Access denied\\.","errorType":"exception","errorClass":"HubException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Diagnostics.OpenTelemetry/RealTime/OpenTelemetryHub.cs","lineNumber":48,"sourceCode":"        await base.OnDisconnectedAsync(exception).ConfigureAwait(false);\n    }\n\n    private static OpenTelemetryTraceFilter ValidateFilter(OpenTelemetryTraceFilter? filter)\n    {\n        filter ??= new();\n\n        if (filter.From is { } from && filter.To is { } to && from > to)\n            throw new HubException(\"The OpenTelemetry filter 'from' timestamp must be earlier than or equal to 'to'.\");\n\n        return filter;\n    }\n\n    private void EnsureCanReadOpenTelemetry()\n    {\n        var user = Context.User;\n\n        if (user?.Identity?.IsAuthenticated != true || !PermissionEvaluator.Shared.HasPermission(user, ReadOpenTelemetry))\n            throw new HubException(\"Access denied.\");\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":51,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Diagnostics.OpenTelemetry/RealTime/OpenTelemetryHub.cs#L30-L51","documentation":"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.","triggerScenarios":"Calling SubscribeAsync on the OpenTelemetryHub while Context.User is null or unauthenticated, or while the authenticated user has no ReadOpenTelemetry permission per PermissionEvaluator.Shared.","commonSituations":"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.","solutions":["Ensure the SignalR client supplies a valid access token via AccessTokenFactory or cookie auth before starting the connection.","Grant the user/role the ReadOpenTelemetry permission in your Elsa permission configuration.","Verify claims are populated by your auth middleware (check Context.User.IsAuthenticated server-side).","Wrap hub invocation in try-catch and surface a clear 'sign in required' message to the UI."],"exampleFix":"// before\nawait connection.start();\nawait connection.invoke('SubscribeAsync');\n// after\nconst connection = new HubConnectionBuilder()\n  .withUrl('/hubs/opentelemetry', { accessTokenFactory: () => getToken() })\n  .build();\nawait connection.start();\nawait connection.invoke('SubscribeAsync');","handlingStrategy":"try-catch","validationCode":"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.');","typeGuard":"function canReadTelemetry(user) { return Boolean(user?.identity?.isAuthenticated) && Array.isArray(user?.permissions) && user.permissions.includes('OpenTelemetry.Read'); }","tryCatchPattern":"try { await connection.invoke('SubscribeAsync'); } catch (e) { if (e?.message === 'Access denied.') redirectToLogin(); else throw e; }","preventionTips":["Always pass an access token to the SignalR connection via accessTokenFactory.","Check the user's permission set before opening telemetry hubs.","Keep permission grants (ReadOpenTelemetry) in your deployment configuration review checklist.","Handle the 'Access denied.' HubException explicitly to guide users to sign in."],"tags":["signalr","authorization","opentelemetry"],"backgroundTag":"permission-denied","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}