{"record":{"id":"e32e7f04ed2fe33a","repo":"theonedev/onedev","slug":"not-authorized-e32e7f","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/AgentResource.java","lineNumber":54,"sourceCode":"\tprivate final AgentService agentService;\n\t\n\tprivate final AgentAttributeService agentAttributeService;\n\t\n\tprivate final AuditService auditService;\n\t\n\t@Inject\n\tpublic AgentResource(AgentService agentService, AgentAttributeService agentAttributeService, AuditService auditService) {\n\t\tthis.agentService = agentService;\n\t\tthis.agentAttributeService = agentAttributeService;\n\t\tthis.auditService = auditService;\n\t}\n\n\t@Api(order=100)\n\t@Path(\"/{agentId}\")\n    @GET\n    public Agent getAgent(@PathParam(\"agentId\") Long agentId) {\n    \tif (!SecurityUtils.isAdministrator()) \n\t\t\tthrow new UnauthorizedException();\n    \treturn agentService.load(agentId);\n    }\n\n\t@Api(order=200)\n\t@Path(\"/{agentId}/attributes\")\n    @GET\n    public Map<String, String> getAttributes(@PathParam(\"agentId\") Long agentId) {\n    \tif (!SecurityUtils.isAdministrator()) \n\t\t\tthrow new UnauthorizedException();\n    \treturn agentService.load(agentId).getAttributeMap();\n    }\n\t\n\t@Api(order=300)\n\t@GET\n    public List<Agent> queryAgents(\n    \t\t@QueryParam(\"query\") @Api(description=\"Syntax of this query is the same as in <a href='/~administration/agents'>agent management page</a>\", example=\"\\\"Name\\\" is \\\"agentName\\\"\") String query, \n    \t\t@QueryParam(\"offset\") @Api(example=\"0\") int offset, \n    \t\t@QueryParam(\"count\") @Api(example=\"100\") int count) {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/AgentResource.java#L36-L72","documentation":"getAgent in AgentResource is an administration-only REST endpoint: it loads any agent by id, so it is gated behind SecurityUtils.isAdministrator(). Non-administrator authenticated users get UnauthorizedException ('Not authorized').","triggerScenarios":"GET /~api/agents/{agentId} invoked with credentials of a non-administrator user.","commonSituations":"Regular project members querying agent details via REST with their personal access token; service accounts without server-admin role attempting agent inventory scripts.","solutions":["Use credentials (token) of a server administrator for this call","Grant the calling account server administrator role in OneDev administration","If only your own build's info is needed, use non-admin endpoints or the web UI instead"],"exampleFix":"// before\ncurl -u alice-token: GET /~api/agents/5   // alice is not admin\n// after\ncurl -H \"Authorization: Bearer <admin-token>\" GET /~api/agents/5","handlingStrategy":"validation","validationCode":"// only call if the account is server admin\nboolean isAdmin = userDictatesAdminRole; // check in Admin > Role Management","typeGuard":null,"tryCatchPattern":"try { Agent a = client.getAgent(id); } catch (ForbiddenException e) { throw new IllegalStateException(\"Server administrator required to fetch agent \" + id); }","preventionTips":["Keep a separate admin token for administration REST calls","Document which service accounts hold server-admin role","Check agent info in UI first when unsure of permissions"],"tags":["rest-api","authorization","agent","admin-only"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}