theonedev/onedev · error · UnauthorizedException
Not authorized
Error message
Not authorized
What it means
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.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/ArtifactResource.java:68
if (StringUtils.isNotBlank(artifactPath)) {
artifactPath = StringUtils.stripStart(artifactPath, "/");
if (StringUtils.isNotBlank(artifactPath)) {
if (artifactPath.contains(".."))
throw new ExplicitException("Invalid artifact path");
return artifactPath;
}
}
return null;
}
@Api(order=100, description = "Get artifact info of specified path")
@Path("/{buildId}/infos{artifactPath:(/.*)?}")
@GET
public ArtifactInfo getArtifactInfo(@PathParam("buildId") Long buildId,
@PathParam("artifactPath") @Api(example = "/path/to/directoryOrFile") String artifactPath) {
Build build = buildService.load(buildId);
if (!SecurityUtils.canAccessProject(build.getProject()))
throw new UnauthorizedException();
return buildService.getArtifactInfo(build, normalizeArtifactPath(artifactPath));
}
@Api(order=200, description = "Download artifact of specified path")
@Path("/{buildId}/contents/{artifactPath:(.*)}")
@GET
@Produces(APPLICATION_OCTET_STREAM)
public StreamingOutput downloadArtifact(@PathParam("buildId") Long buildId,
@PathParam("artifactPath") @Api(example = "path/to/file") String artifactPath) {
Build build = buildService.load(buildId);
if (!SecurityUtils.canAccessProject(build.getProject()))
throw new UnauthorizedException();
var projectId = build.getProject().getId();
var buildNumber = build.getNumber();
var normalizedPath = normalizeArtifactPath(artifactPath);
return os -> {
buildService.downloadArtifact(projectId, buildNumber, normalizedPath, os);View on GitHub (pinned to d44925c47c)
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
Example fix
// before # user has no role on project 'web' curl -u user:token .../builds/42/infos// // after # add user to project 'web' with at least Read access, or use an authorized account
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the token owner can access the project before calling
if (!userCanAccessProject(tokenUser, projectName)) throw new Error('no project access'); Type guard
function canAccess(u, project) { return u?.projects?.some(p => p.id === project.id); } Try / catch
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; } Prevention
- Verify project membership of the credential before artifact API calls
- Document which service accounts can read which projects
- Rotate/refresh tokens after role changes
When it happens
Trigger: GET /builds/{buildId}/infos/{artifactPath} with credentials of a user who is not a member of the build's project; unauthenticated request.
Common situations: Sharing artifact URLs across teams with restricted projects; using a token from a user without project access; project access roles changed/revoked.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/9d7f737479b7446f.
Report an issue: GitHub.