{"record":{"id":"f6b9b76697dcdc84","repo":"SonarSource/sonarqube","slug":"insufficient-privileges-f6b9b7","errorCode":null,"errorMessage":"Insufficient privileges","messagePattern":"Insufficient privileges","errorType":"exception","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java","lineNumber":91,"sourceCode":"        new Change(\"8.4\", \"Field 'id' in the response is deprecated. Format changes from integer to string.\"),\n        new Change(\"6.6\", \"The parameter 'projectId' has been removed\"),\n        new Change(\"6.6\", \"The parameter 'projectKey' has been renamed to 'project'\"),\n        new Change(\"6.6\", \"This webservice is now part of the public API\"));\n\n    action.createParam(PARAM_PROJECT)\n      .setDescription(\"Project key\")\n      .setExampleValue(KEY_PROJECT_EXAMPLE_001)\n      .setRequired(true);\n  }\n\n  @Override\n  public void handle(Request request, Response response) throws Exception {\n    try (DbSession dbSession = dbClient.openSession(false)) {\n      ProjectDto project = componentFinder.getProjectByKey(dbSession, request.mandatoryParam(PARAM_PROJECT));\n\n      if (!userSession.hasEntityPermission(USER, project) &&\n          !userSession.hasEntityPermission(ADMIN, project)) {\n        throw insufficientPrivilegesException();\n      }\n\n      QualityGateData data = qualityGateFinder.getEffectiveQualityGate(dbSession, project);\n\n      writeProtobuf(buildResponse(data), request, response);\n    }\n  }\n\n  private static GetByProjectResponse buildResponse(QualityGateData qg) {\n    GetByProjectResponse.Builder response = GetByProjectResponse.newBuilder();\n\n    response.getQualityGateBuilder()\n      .setName(qg.getName())\n      .setDefault(qg.isDefault());\n\n    return response.build();\n  }\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java#L73-L109","documentation":"The api/qualitygates/get_by_project web service refuses to return the quality gate effective for a project because the authenticated user holds neither the USER nor the ADMIN project permission on that project. The handler explicitly checks both entity permissions after resolving the project key and throws insufficientPrivilegesException() when neither is granted. Quality gate data is considered project-scoped information, so read access requires at least USER-level project membership.","triggerScenarios":"Calling GET api/qualitygates/get_by_project with a project key on which the current token's user has no USER or ADMIN project permission. E.g., a CI or script token whose user was never added to the project, or a user querying another team's project key.","commonSituations":"Scripts using an old token whose project memberships were revoked; users without SonarQube access requesting gate status for a project they can see in CI but not in SonarQube; project key typos causing the lookup to hit a different project the user lacks access to.","solutions":["In SonarQube UI or via api/permissions/add_user, grant the calling user USER (or ADMIN) project permission on the project being queried.","Use a token belonging to a user who is already a member of the project.","If the intent is CI-only access, grant the project SCAN permission and use api/qualitygates/project_status instead (see ProjectStatusAction).","Verify the project key is correct — a mistyped key may resolve to a project the user has no rights on."],"exampleFix":"// before: user queries with a personal token lacking project membership\ncurl -u mytoken: $SONAR/api/qualitygates/get_by_project?project=my.project\n\n// after: grant USER permission first\ncurl -u admintoken: -X POST \"$SONAR/api/permissions/add_user?projectKey=my.project&permission=user&login=jdoe\"","handlingStrategy":"try-catch","validationCode":"// Java-side pre-check is not exposed to clients; on the client, verify membership first:\ncurl -u \"$TOKEN\": \"$SONAR/api/permissions/users?projectKey=my.project&login=$USER\" | grep '\"permission\":\"user\"'","typeGuard":null,"tryCatchPattern":"try {\n  ProjectQualityGate gate = wsClient.qualityGates().getByProject(req);\n} catch (ServiceErrorException e) {\n  if (e.errors().stream().anyMatch(m -> m.contains(\"Insufficient privileges\"))) {\n    // request USER/ADMIN project permission or fall back to project_status\n  }\n}","preventionTips":["Use tokens whose user has USER permission on every project the script touches.","Prefer api/qualitygates/project_status with a SCAN token for CI pipelines.","Check project permissions (api/permissions/users) before calling gate endpoints.","Audit token ownership: revoked project membership silently breaks old tokens."],"tags":["sonarqube","webapi","authorization","quality-gates"],"backgroundTag":"insufficient-permissions","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}