{"record":{"id":"0572711555139dce","repo":"theonedev/onedev","slug":"unauthorized-057271","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/BuildLogStreamResource.java","lineNumber":65,"sourceCode":"\tprivate final SessionService sessionService;\n\t\n\t@Inject\n\tpublic BuildLogStreamResource(BuildService buildService, LogService logService,\n                                  ObjectMapper objectMapper, SessionService sessionService) {\n\t\tthis.buildService = buildService;\n\t\tthis.logService = logService;\n\t\tthis.objectMapper = objectMapper;\n\t\tthis.sessionService = sessionService;\n\t}\n\t\n\t@Api(order=200, description = \"Streaming log of specified build\")\n\t@Path(\"/{buildId}\")\n\t@GET\n\t@Produces(APPLICATION_OCTET_STREAM)\n\tpublic StreamingOutput downloadLog(@PathParam(\"buildId\") Long buildId) {\n\t\tBuild build = buildService.load(buildId);\n\t\tif (!SecurityUtils.canAccessLog(build))\n\t\t\tthrow new UnauthorizedException();\n\t\t\n\t\tvar loggingSupport = build.getLoggingSupport();\n\t\tvar buildStatus = build.getStatus();\n\n\t\treturn os -> {\n\t\t\twriteStatus(os, buildStatus);\n\t\t\tvar logListener = new LogListener() {\n\n\t\t\t\t@Override\n\t\t\t\tpublic void logged(LoggingSupport loggingSupport) {\n\t\t\t\t\tif (loggingSupport instanceof BuildLoggingSupport buildLoggingSupport \n\t\t\t\t\t\t\t&& buildLoggingSupport.getBuildId().equals(buildId)) {\n\t\t\t\t\t\tsynchronized (os) {\n\t\t\t\t\t\t\tos.notify();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/BuildLogStreamResource.java#L47-L83","documentation":"BuildLogStreamResource.downloadLog streams a build's log and throws UnauthorizedException when SecurityUtils.canAccessLog(build) is false. Log access is a stricter privilege than general project access in OneDev, so users who can view a build may still be barred from reading its raw log. The check happens before any streaming begins.","triggerScenarios":"GET /rest/builds/{buildId}/log (octet-stream) as a user lacking log-access permission on the build's project — e.g. guest-level access, a token without log viewing rights, or jobs flagged to restrict log visibility.","commonSituations":"Downloading CI logs via API token with read-only role; projects that hide logs of security-sensitive jobs from non-admins; anonymous access attempts; monitoring scripts hitting the endpoint with an expired token.","solutions":["Grant the user's role the 'Access Build Log' (or equivalent) permission on the project.","Check the job/build configuration — some jobs restrict log visibility; relax it if appropriate.","Use a token from an account that passes canAccessLog (project admin usually qualifies).","Verify the request includes valid Authorization credentials; anonymous users are typically denied."],"exampleFix":"// before\nInputStream in = client.path(\"/rest/builds/\" + buildId + \"/log\").get(InputStream.class);\n// after: pick an identity allowed to read logs\n// e.g. switch to an admin token or grant the role 'Access build logs' in project security settings\nInputStream in = adminClient.path(\"/rest/builds/\" + buildId + \"/log\").get(InputStream.class);","handlingStrategy":"validation","validationCode":"// probe access with a cheap read before streaming\nResponse probe = client.path(\"/rest/builds/\" + buildId).get();\nif (probe.getStatus() != 200) throw new SecurityException(\"No access to build \" + buildId + \" log\");","typeGuard":null,"tryCatchPattern":"try (InputStream in = client.path(\"/rest/builds/\" + id + \"/log\").get(InputStream.class)) {\n    // consume\n} catch (ProcessingException e) {\n    if (e.getCause() instanceof IOException && String.valueOf(e).contains(\"401\")) {\n        throw new SecurityException(\"Log access denied — need 'Access build log' permission\");\n    }\n    throw e;\n}","preventionTips":["Grant the log-access privilege explicitly; it is separate from build read access.","Use admin/service tokens for log collection jobs.","Check job-level log visibility restrictions in pipeline config.","Handle 401 by surfacing a permission message, not retrying."],"tags":["rest","authorization","logs"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}