theonedev/onedev · error · UnauthorizedException
Not authorized
Error message
Not authorized
What it means
OneDev's REST API throws UnauthorizedException (HTTP 403, message 'Not authorized') when the authenticated caller lacks the required permission. getAuthorization loads a UserAuthorization by id and requires the caller to be able to manage the project the authorization belongs to. Even a valid, authenticated request is rejected if the project is outside the caller's management scope.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserAuthorizationResource.java:47
public class UserAuthorizationResource {
private final UserAuthorizationService authorizationService;
private final AuditService auditService;
@Inject
public UserAuthorizationResource(UserAuthorizationService authorizationService, AuditService auditService) {
this.authorizationService = authorizationService;
this.auditService = auditService;
}
@Api(order=100, description = "Get user authorization of specified id")
@Path("/{authorizationId}")
@GET
public UserAuthorization getAuthorization(@PathParam("authorizationId") Long authorizationId) {
UserAuthorization authorization = authorizationService.load(authorizationId);
if (!SecurityUtils.canManageProject(authorization.getProject()))
throw new UnauthorizedException();
return authorization;
}
@Api(order=200, description="Create user authorization")
@POST
public Long createAuthorization(@NotNull UserAuthorization authorization) {
if (!SecurityUtils.canManageProject(authorization.getProject()))
throw new UnauthorizedException();
authorizationService.createOrUpdate(authorization);
var newAuditContent = VersionedXmlDoc.fromBean(authorization).toXML();
auditService.audit(null, "created user authorization via RESTful API", null, newAuditContent);
return authorization.getId();
}
@Api(order=300, description = "Delete user authorization of specified id")
@Path("/{authorizationId}")
@DELETE
public Response deleteAuthorization(@PathParam("authorizationId") Long authorizationId) {View on GitHub (pinned to d44925c47c)
Solutions
- Use an access token belonging to a user who can manage the target project (project owner/maintainer) or an administrator.
- Verify the authorizationId actually refers to an authorization of the project you manage (load the entity and check its project).
- Grant the token's owner Project management permission (Project > Access/Settings > add user with Manage privilege).
- Check the request is authenticating at all — an anonymous or wrongly-scoped token yields the same 403.
Example fix
// before (token of a member without manage rights) curl -H "Authorization: Bearer <member-token>" https://onedev/~api/users/authorizations/42 // after (token of project owner/admin) curl -H "Authorization: Bearer <owner-token>" https://onedev/~api/users/authorizations/42
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check with a per-project endpoint the caller can access:
// GET /~api/projects/{projectPath} must succeed for the project of authorizationId
const projectAccessible = await fetch(`${baseUrl}/~api/projects/${projectPath}`, { headers }).then(r => r.ok);
if (!projectAccessible) throw new Error('caller cannot manage project; 403 expected'); Try / catch
try {
const auth = await get(`/users/authorizations/${id}`);
} catch (e) {
if (e.response?.status === 403) {
// caller lacks manage rights on the authorization's project
// fall back to admin credentials or skip
} else throw e;
} Prevention
- Keep a dedicated admin/provisioning token for authorization APIs.
- Look up the authorization's project before requesting it.
- Document which token is required for project-level ACL operations.
- Handle 403 as an expected outcome of permission scoping, not a bug.
When it happens
Trigger: GET /~api/users/authorizations/{authorizationId} (within UserAuthorizationResource) where SecurityUtils.canManageProject(authorization.getProject()) returns false — i.e. the authenticated user/token is not an administrator or a project manager of the project referenced by the authorization entity.
Common situations: Calling with an access token whose owner is a regular project member, not a project maintainer/owner; the authorization id exists but belongs to a different project than the caller manages; scripts configured with a personal access token of a non-admin user; recent permission changes removed the caller's manage rights.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Issue schedule permission required to set iterations
- No permission to update issue fields
- No permission to add specified link for specified issues
- No permission to read code of source project:
- No permission to read code of target project:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/fdf520d0dbe6f47f.
Report an issue: GitHub.