{"record":{"id":"8a93600614bb2aea","repo":"bitwarden/server","slug":"resource-not-found-8a9360","errorCode":null,"errorMessage":"Resource not found.","messagePattern":"Resource not found\\.","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs","lineNumber":45,"sourceCode":"\n    public SecretsManagerPortingController(ISecretRepository secretRepository, IProjectRepository projectRepository,\n        IUserService userService, IMaxProjectsQuery maxProjectsQuery, IImportCommand importCommand,\n        ICurrentContext currentContext)\n    {\n        _secretRepository = secretRepository;\n        _projectRepository = projectRepository;\n        _userService = userService;\n        _maxProjectsQuery = maxProjectsQuery;\n        _importCommand = importCommand;\n        _currentContext = currentContext;\n    }\n\n    [HttpGet(\"sm/{organizationId}/export\")]\n    public async Task<SMExportResponseModel> Export([FromRoute] Guid organizationId)\n    {\n        if (!await _currentContext.OrganizationAdmin(organizationId) || !_currentContext.AccessSecretsManager(organizationId))\n        {\n            throw new NotFoundException();\n        }\n\n        var userId = _userService.GetProperUserId(User).Value;\n        var projects = await _projectRepository.GetManyByOrganizationIdAsync(organizationId, userId, AccessClientType.NoAccessCheck);\n        var secrets = await _secretRepository.GetManyDetailsByOrganizationIdAsync(organizationId, userId, AccessClientType.NoAccessCheck);\n\n        if (projects == null && secrets == null)\n        {\n            throw new NotFoundException();\n        }\n\n        return new SMExportResponseModel(projects.Select(p => p.Project), secrets.Select(s => s.Secret));\n    }\n\n    [HttpPost(\"sm/{organizationId}/import\")]\n    public async Task Import([FromRoute] Guid organizationId, [FromBody] SMImportRequestModel importRequest)\n    {\n        if (!await _currentContext.OrganizationAdmin(organizationId) || !_currentContext.AccessSecretsManager(organizationId))","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs#L27-L63","documentation":"Thrown at SecretsManagerPortingController.cs:45 inside Export (GET sm/{org}/export). The caller is not an OrganizationAdmin for that org OR lacks Secrets Manager access (_currentContext.AccessSecretsManager false). Either condition throws NotFoundException -> HTTP 404. Export is restricted to organization admins with SM access.","triggerScenarios":"GET /sm/{orgId}/export by a non-admin SM user, a standard org member, or an admin without the Secrets Manager add-on/access.","commonSituations":"A custom-role or standard user attempts an export; admin whose SM access was revoked; scripted export run with a non-admin token.","solutions":["Run the export as an organization admin who also has Secrets Manager access.","Use an admin-level API token for automated exports.","Confirm the organization has Secrets Manager enabled for the admin."],"exampleFix":"// before: non-admin token attempts export\nawait memberClient.GetAsync($\"/sm/{orgId}/export\"); // 404\n\n// after: use an admin credential\nvar adminClient = ClientFor(orgAdminCredential);\nawait adminClient.GetAsync($\"/sm/{orgId}/export\");","handlingStrategy":"validation","validationCode":"if (!await IsOrganizationAdminAsync(orgId) || !await HasSecretsManagerAccessAsync(orgId))\n    throw new UnauthorizedAccessException(\"Export requires org admin with SM access\");\nawait adminClient.GetAsync($\"/sm/{orgId}/export\");","typeGuard":null,"tryCatchPattern":"try { await client.GetAsync($\"/sm/{orgId}/export\"); }\ncatch (ApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { Log.Warn(\"Export denied; use an admin with SM access\"); }","preventionTips":["Use an admin API token for automated exports.","Verify the caller is an org admin before exposing the export action.","Confirm SM is enabled on the org."],"tags":["csharp","aspnet","bitwarden","secrets-manager","authorization","export","admin","api"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}