SonarSource/sonarqube · error · ForbiddenException

Insufficient privileges

Error message

Insufficient privileges

What it means

The api/qualitygates/project_status web service requires that the caller hold at least one of: project ADMIN, project USER, project SCAN, or global SCAN (Execute Analysis) permission. checkPermission throws insufficientPrivilegesException when none are present. This endpoint exposes quality-gate status for a project/branch, so it is accessible to project users, project admins, and CI accounts with scan rights.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java:227

        return Optional.empty();
      }
      // get the gate status as it was computed during the specified analysis
      String analysisUuid = projectAndSnapshot.snapshotDto.get().getUuid();
      return dbClient.projectMeasureDao().selectMeasure(dbSession, analysisUuid, projectAndSnapshot.branch.getUuid(), CoreMetrics.QUALITY_GATE_DETAILS_KEY)
        .map(ProjectMeasureDto::getData);
    }

    // do not restrict to a specified analysis, use the live measure
    return dbClient.measureDao().selectByComponentUuid(dbSession, projectAndSnapshot.branch.getUuid())
      .map(m -> m.getString(CoreMetrics.QUALITY_GATE_DETAILS_KEY));
  }

  private void checkPermission(ProjectDto project) {
    if (!userSession.hasEntityPermission(ProjectPermission.ADMIN, project) &&
        !userSession.hasEntityPermission(ProjectPermission.USER, project) &&
        !userSession.hasEntityPermission(ProjectPermission.SCAN, project) &&
        !userSession.hasPermission(GlobalPermission.SCAN)) {
      throw insufficientPrivilegesException();
    }
  }

  @Immutable
  private static class ProjectAndSnapshot {
    private final BranchDto branch;
    private final Optional<SnapshotDto> snapshotDto;
    private final ProjectDto project;

    private ProjectAndSnapshot(ProjectDto project, BranchDto branch, @Nullable SnapshotDto snapshotDto) {
      this.project = project;
      this.branch = branch;
      this.snapshotDto = Optional.ofNullable(snapshotDto);
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Grant the calling user global 'Execute Analysis' (scan) permission, the usual fix for CI tokens.
  2. Or add the user to the project with SCAN, ADMIN, or USER permission via api/permissions/add_user.
  3. Ensure the request is authenticated — anonymous users almost always lack all four permissions.
  4. If using a project-wide group permission, confirm the token's user is actually a member of that group.

Example fix

// before: CI token with no permissions
curl -u citoken: "$SONAR/api/qualitygates/project_status?projectKey=my.project"

// after: grant global scan permission to the CI user
curl -u admintoken: -X POST "$SONAR/api/permissions/add_user?permission=scan&login=ci-user"
Defensive patterns

Strategy: try-catch

Validate before calling

curl -u "$TOKEN": "$SONAR/api/permissions/users?projectKey=my.project&login=$USER" | grep -E '"scan"|"admin"|"user"'
curl -u "$TOKEN": "$SONAR/api/permissions/user?login=$USER" | grep '"scan"'

Try / catch

try {
  ProjectStatus status = wsClient.qualityGates().projectStatus(req);
} catch (ServiceErrorException e) {
  if (e.errors().contains("Insufficient privileges")) {
    // grant global scan or project scan/admin/user to the token's user
  }
}

Prevention

When it happens

Trigger: Calling GET api/qualitygates/project_status for a project where the token's user has none of the four checked permissions — typically an anonymous request, or a CI token whose user lost all project roles and the global 'Execute Analysis' permission.

Common situations: CI pipelines calling project_status with a token created before the user's roles were reset; external status dashboards polling the endpoint anonymously; granting SCAN on the project but to a group the CI user isn't in.

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 SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/d682e4698d4f05d5. Report an issue: GitHub.