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

  1. Grant the user access to the project (Project > Access Control / role membership)
  2. Use credentials of a user who can access the project
  3. 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

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.