{"record":{"id":"156754b17677092a","repo":"jellyfin/jellyfin","slug":"only-admin-users-can-retrieve-the-activity-log","errorCode":null,"errorMessage":"Only admin users can retrieve the activity log.","messagePattern":"Only admin users can retrieve the activity log\\.","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"warning","filePath":"Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs","lineNumber":78,"sourceCode":"        {\n            _activityManager.EntryCreated -= OnEntryCreated;\n            _disposed = true;\n        }\n\n        await base.DisposeAsyncCore().ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Starts sending messages over an activity log web socket.\n    /// </summary>\n    /// <param name=\"message\">The message.</param>\n    protected override void Start(WebSocketMessageInfo message)\n    {\n        if (!message.Connection.AuthorizationInfo.IsApiKey\n            && (message.Connection.AuthorizationInfo.User is null\n                || !message.Connection.AuthorizationInfo.User.HasPermission(PermissionKind.IsAdministrator)))\n        {\n            throw new AuthenticationException(\"Only admin users can retrieve the activity log.\");\n        }\n\n        base.Start(message);\n    }\n\n    private void OnEntryCreated(object? sender, GenericEventArgs<ActivityLogEntry> e)\n    {\n        SendData(true);\n    }\n}\n","sourceCodeStart":60,"sourceCodeEnd":89,"githubUrl":"https://github.com/jellyfin/jellyfin/blob/ae8723026d97b6d0f926638803edef338919b794/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs#L60-L89","documentation":"ActivityLogWebSocketListener.Start throws AuthenticationException('Only admin users can retrieve the activity log.') when the websocket connection is neither an API key nor an administrator user. The activity log is admin-scoped, so subscribing to its websocket feed requires elevated privileges. The check reads AuthorizationInfo.IsApiKey and the user's IsAdministrator permission.","triggerScenarios":"A non-admin authenticated client (or a non-API-key connection) sends the ActivityLog websocket message to subscribe to the activity-log feed, triggering Start's permission check.","commonSituations":"Regular user sessions opening the admin dashboard's activity feed; third-party clients subscribing without checking role; tokens downgraded from admin to user without the client noticing.","solutions":["Authenticate as an Administrator user, or use an API key, before subscribing to the ActivityLog websocket feed.","Have non-admin clients avoid the activity-log subscription message entirely.","Verify the session's role before attempting to subscribe."],"exampleFix":"// before\nsocket.Send(\"ActivityLog\", {}); // non-admin session\n// after\nif (session.IsAdmin) socket.Send(\"ActivityLog\", {});","handlingStrategy":"validation","validationCode":"if (!session.IsAdministrator && !session.IsApiKey) { /* don't subscribe to ActivityLog */ }","typeGuard":"bool CanReadActivityLog(AuthorizationInfo a) => a.IsApiKey || (a.User?.HasPermission(PermissionKind.IsAdministrator) ?? false);","tryCatchPattern":"try { socket.Subscribe(\"ActivityLog\"); }\ncatch (AuthenticationException) { /* need admin/api key */ }","preventionTips":["Subscribe to the activity log only as admin or with an API key.","Check the session role before sending the subscribe message.","Keep non-admin clients off admin-scoped feeds."],"tags":["authorization","websocket","activity-log","authentication"],"backgroundTag":null,"analyzedSha":"ae8723026d97b6d0f926638803edef338919b794","analyzedAt":"2026-08-13T10:43:30.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}