theonedev/onedev · error · UnauthorizedException

Not authorized

Error message

Not authorized

What it means

The token's subject is bound to the security context and SecurityUtils.canRunJob(subject, project, job) checks whether the user may run the named job in the project. If not, UnauthorizedException is thrown. Even a valid token fails here if its user lacks job-run (project member/report permissions) rights or the job doesn't exist in that project.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/TriggerJobResource.java:113

		return triggerJob(projectPath, branch, tag, job, accessToken, uriInfo);
    }

    private Long triggerJob(String projectPath, @Nullable String branch, @Nullable String tag, String job,
							String accessTokenValue, UriInfo uriInfo) {
		Project project = projectService.findByPath(projectPath);
		if (project == null)
			throw new NotAcceptableException("Project not found: " + projectPath);

		var accessToken = accessTokenService.findByValue(accessTokenValue);
		if (accessToken == null)
			throw new NotAcceptableException("Invalid access token");
		
		var subject = accessToken.asSubject();
		var user = SecurityUtils.getUser(subject);
		ThreadContext.bind(subject);
		try {
			if (!SecurityUtils.canRunJob(subject, project, job))		
				throw new UnauthorizedException();

			if (StringUtils.isNotBlank(branch) && StringUtils.isNotBlank(tag)) 
				throw new NotAcceptableException("Either branch or tag should be specified, but not both");
			
			String refName;
			if (branch != null)
				refName = GitUtils.branch2ref(branch);
			else if (tag != null)
				refName = GitUtils.tag2ref(tag);
			else
				refName = GitUtils.branch2ref(project.getDefaultBranch());
			
			RevCommit commit = project.getRevCommit(refName, false);
			if (commit == null)
				throw new NotAcceptableException("Ref not found: " + refName);
			
			Map<String, List<String>> jobParams = new HashMap<>();
			for (Map.Entry<String, List<String>> entry: uriInfo.getQueryParameters().entrySet()) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Add the token's user to the target project with a role that can run jobs, or ask a project admin for access.
  2. Verify the job name matches a job defined in the project's build spec and that the user's role permits running it.
  3. Use a token of a user who is at least a project user with job-run permission (e.g. Project Developer+ depending on setup).

Example fix

// before: token of outsider user
curl 'http://onedev/~api/trigger-job?project=myorg/myrepo&job=CI&access_token=TOKEN'
// after: grant the token's user role in project, or use an admin/member token
OneDev UI: Project myorg/myrepo > People > add user 'ci-bot' as Developer; retry
Defensive patterns

Strategy: validation

Validate before calling

const project = await getProject(projectPath);
const members = await fetch(`/~api/projects/${project.id}/authorizations`, {headers: {Authorization: auth}}).then(r => r.json());
const me = await fetch('/~api/me', {headers: {Authorization: auth}}).then(r => r.json());
if (!members.some(m => m.userName === me.userName))
  throw new Error('Token user is not a member of the target project');

Try / catch

try {
  return await triggerJob(params);
} catch (e) {
  if (e.status === 406 && /not authorized/i.test(e.message))
    throw new Error(`User of token cannot run job '${params.job}' in '${params.project}' - grant project access`);
  throw e;
}

Prevention

When it happens

Trigger: GET/POST /~api/trigger-job with a valid access token whose owner is not authorized to run the specified job in the target project (not a project member, insufficient role), or referencing a job name the user cannot run.

Common situations: Using a personal token of a user not added to the project; token belongs to another user than assumed; project role downgraded; CI bot account never granted access to the new project.

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/140a5b5172b892b6. Report an issue: GitHub.