{"record":{"id":"35d27951e425cfc5","repo":"bitwarden/server","slug":"resource-not-found-35d279","errorCode":null,"errorMessage":"Resource not found.","messagePattern":"Resource not found\\.","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Api/SecretsManager/Controllers/SecretsManagerEventsController.cs","lineNumber":45,"sourceCode":"        IAuthorizationService authorizationService)\n    {\n        _authorizationService = authorizationService;\n        _serviceAccountRepository = serviceAccountRepository;\n        _eventRepository = eventRepository;\n    }\n\n    [HttpGet(\"sm/events/service-accounts/{serviceAccountId}\")]\n    public async Task<ListResponseModel<EventResponseModel>> GetServiceAccountEventsAsync(Guid serviceAccountId,\n        [FromQuery] DateTime? start = null, [FromQuery] DateTime? end = null,\n        [FromQuery] string continuationToken = null)\n    {\n        var serviceAccount = await _serviceAccountRepository.GetByIdAsync(serviceAccountId);\n        var authorizationResult =\n            await _authorizationService.AuthorizeAsync(User, serviceAccount, ServiceAccountOperations.ReadEvents);\n\n        if (!authorizationResult.Succeeded)\n        {\n            throw new NotFoundException();\n        }\n\n        var dateRange = ApiHelpers.GetDateRange(start, end);\n\n        var result = await _eventRepository.GetManyByOrganizationServiceAccountAsync(serviceAccount.OrganizationId,\n            serviceAccount.Id, dateRange.Item1, dateRange.Item2,\n            new PageOptions { ContinuationToken = continuationToken });\n        var responses = result.Data.Select(e => new EventResponseModel(e));\n        return new ListResponseModel<EventResponseModel>(responses, result.ContinuationToken);\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":57,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/SecretsManager/Controllers/SecretsManagerEventsController.cs#L27-L57","documentation":"Thrown at SecretsManagerEventsController.cs:45 inside GetServiceAccountEventsAsync (GET sm/events/service-accounts/{id}). The IAuthorizationService.AuthorizeAsync for ServiceAccountOperations.ReadEvents returned Succeeded=false, so the controller throws NotFoundException (authorization-based 404). Note the serviceAccount loaded just above may be null and is passed straight into AuthorizeAsync, so a missing service account also funnels here.","triggerScenarios":"GET /sm/events/service-accounts/{id} by a caller without permission to read that service account's events, or where the service account id does not exist.","commonSituations":"User is not an admin/manager of the service account's organization; service account id is stale/deleted; principal lacks the events-read access policy.","solutions":["Ensure the caller has ReadEvents permission on the service account (org admin or granted access policy).","Confirm the service account id is current and belongs to an org the caller can access.","Fetch the service account list first to validate the id before requesting its events."],"exampleFix":"// before: assume access to any service account's events\nawait client.GetAsync($\"/sm/events/service-accounts/{saId}\"); // 404\n\n// after: verify the id is in the caller's readable service accounts\nvar visible = await ListVisibleServiceAccountsAsync();\nif (visible.Any(sa => sa.Id == saId))\n    await client.GetAsync($\"/sm/events/service-accounts/{saId}\");","handlingStrategy":"validation","validationCode":"// Confirm the service account id is visible to the caller first\nvar visible = await ListVisibleServiceAccountsAsync();\nif (!visible.Any(sa => sa.Id == serviceAccountId))\n    throw new UnauthorizedAccessException(\"Cannot read events for this service account\");\nawait client.GetAsync($\"/sm/events/service-accounts/{serviceAccountId}\");","typeGuard":null,"tryCatchPattern":"try { await client.GetAsync($\"/sm/events/service-accounts/{id}\"); }\ncatch (ApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { Log.Warn(\"Events access denied or SA missing\"); }","preventionTips":["Restrict event-reading UI to admins or granted principals.","Validate the service account id against the readable list first.","Watch for stale/deleted service account ids."],"tags":["csharp","aspnet","bitwarden","secrets-manager","authorization","events","service-account","api"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}