{"record":{"id":"9d7f737479b7446f","repo":"theonedev/onedev","slug":"not-authorized-9d7f73","errorCode":null,"errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":403,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/ArtifactResource.java","lineNumber":68,"sourceCode":"\t\tif (StringUtils.isNotBlank(artifactPath)) {\n\t\t\tartifactPath = StringUtils.stripStart(artifactPath, \"/\");\n\t\t\tif (StringUtils.isNotBlank(artifactPath)) {\n\t\t\t\tif (artifactPath.contains(\"..\"))\n\t\t\t\t\tthrow new ExplicitException(\"Invalid artifact path\");\n\t\t\t\treturn artifactPath;\n\t\t\t}\n\t\t} \n\t\treturn null;\n\t}\n\t\n\t@Api(order=100, description = \"Get artifact info of specified path\")\n\t@Path(\"/{buildId}/infos{artifactPath:(/.*)?}\")\n    @GET\n    public ArtifactInfo getArtifactInfo(@PathParam(\"buildId\") Long buildId, \n\t\t\t\t\t\t\t\t\t\t@PathParam(\"artifactPath\") @Api(example = \"/path/to/directoryOrFile\") String artifactPath) {\n\t\tBuild build = buildService.load(buildId);\n\t\tif (!SecurityUtils.canAccessProject(build.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\treturn buildService.getArtifactInfo(build, normalizeArtifactPath(artifactPath));\n    }\n\n\t@Api(order=200, description = \"Download artifact of specified path\")\n\t@Path(\"/{buildId}/contents/{artifactPath:(.*)}\")\n\t@GET\n\t@Produces(APPLICATION_OCTET_STREAM)\n\tpublic StreamingOutput downloadArtifact(@PathParam(\"buildId\") Long buildId,\n\t\t\t\t\t\t\t\t\t @PathParam(\"artifactPath\") @Api(example = \"path/to/file\") String artifactPath) {\n\t\tBuild build = buildService.load(buildId);\n\t\tif (!SecurityUtils.canAccessProject(build.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\n\t\tvar projectId = build.getProject().getId();\n\t\tvar buildNumber = build.getNumber();\n\t\tvar normalizedPath = normalizeArtifactPath(artifactPath);\n\t\treturn os -> {\n\t\t\tbuildService.downloadArtifact(projectId, buildNumber, normalizedPath, os);","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/ArtifactResource.java#L50-L86","documentation":"Thrown by ArtifactResource.getArtifactInfo when the authenticated user lacks permission to access the project that owns the specified build. OneDev requires SecurityUtils.canAccessProject(build.getProject()) before returning artifact metadata.","triggerScenarios":"GET /builds/{buildId}/infos/{artifactPath} with credentials of a user who is not a member of the build's project; unauthenticated request.","commonSituations":"Sharing artifact URLs across teams with restricted projects; using a token from a user without project access; project access roles changed/revoked.","solutions":["Grant the user access to the project (Project > Access Control / role membership)","Use credentials of a user who can access the project","Verify the buildId belongs to the intended project"],"exampleFix":"// before\n# user has no role on project 'web'\ncurl -u user:token .../builds/42/infos//\n// after\n# add user to project 'web' with at least Read access, or use an authorized account","handlingStrategy":"try-catch","validationCode":"// ensure the token owner can access the project before calling\nif (!userCanAccessProject(tokenUser, projectName)) throw new Error('no project access');","typeGuard":"function canAccess(u, project) { return u?.projects?.some(p => p.id === project.id); }","tryCatchPattern":"try { getArtifactInfo(buildId, path); } catch (e) { if (/Not authorized/i.test(e.message)) { throw new Error('User lacks access to the build\\'s project'); } throw e; }","preventionTips":["Verify project membership of the credential before artifact API calls","Document which service accounts can read which projects","Rotate/refresh tokens after role changes"],"tags":["rest","auth","artifact","project-access"],"backgroundTag":"insufficient-permissions","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"}