SonarSource/sonarqube · error · UnauthorizedException

You are not allowed to authenticate

Error message

You are not allowed to authenticate

What it means

Thrown by GitLabIdentityProvider.validateUserInAllowedGroups when the authenticated user's GitLab groups contain none of the configured allowed groups. It is an UnauthorizedException: the login succeeded against GitLab but is rejected by group allowlisting policy. The reason is logged server-side before throwing.

Source

Thrown at server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabIdentityProvider.java:157

      Set<String> userGroups = getGroups(accessToken);
      validateUserInAllowedGroups(user.getUsername(), userGroups);
      builder.setGroups(userGroups);
    }
    context.authenticate(builder.build());
    context.redirectToRequestedPage();
  }

  private void validateUserInAllowedGroups(String gitlabUserName, Set<String> userGroups) {
    if (gitLabSettings.allowedGroups().isEmpty() || gitLabSettings.allowAllGroups()) {
      return;
    }

    boolean allowedUser = userGroups.stream()
      .anyMatch(gitLabSettings::isAllowedGroup);

    if (!allowedUser) {
      LOG.info("Login for user with GitLab user name {} rejected, as the user do not belong to the allowlisted groups", gitlabUserName);
      throw new UnauthorizedException("You are not allowed to authenticate");
    }
  }

  private Set<String> getGroups(OAuth2AccessToken accessToken) {
    Set<String> allowedGroups = gitLabSettings.allowedGroups();
    List<GsonGroup> groups;
    if (allowedGroups.isEmpty() || gitLabSettings.allowAllGroups() || hasShortGroupName(allowedGroups)) {
      // GitLab GraphQL API requires a minimum of 3 characters for group search queries.
      // When any allowed group name is shorter than 3 characters, targeted search cannot
      // be used, so all user groups are fetched and filtered client-side instead.
      groups = gitLabGraphQlClient.getGroups(accessToken.getAccessToken(), null);
    } else {
      groups = findGroupsUsingGraphQlApiInParallel(accessToken, allowedGroups);
    }
    return groups.stream()
      .map(GsonGroup::getFullPath)
      .collect(toSet());
  }

View on GitHub (pinned to 184c821202)

Solutions

  1. Verify the sonar.auth.gitlab.allowed-groups values exactly match the group paths/names returned by the GitLab API for the user.
  2. Confirm the user is (still) a member of at least one allowed group in GitLab.
  3. Check server logs for the 'rejected, as the user do not belong to the allowlisted groups' line and compare the returned group list.
  4. Update configuration after any group rename or reorganization in GitLab.
Defensive patterns

Strategy: validation

Validate before calling

// Compare the user's GitLab groups to the allowlist before login completes
Set<String> allowed = new HashSet<>(Arrays.asList(gitLabSettings.allowedGroups()));
allowed.retainAll(userGroups); // empty result means the login will be rejected

Try / catch

try {
    validateUserInAllowedGroups(accessToken, gitlabUserName);
} catch (UnauthorizedException e) {
    LOG.warn("GitLab group allowlist rejected user {}: {}", gitlabUserName, e.getMessage());
}

Prevention

When it happens

Trigger: onCallback -> validateUserInAllowedGroups: getGroups(accessToken) returns the user's groups, and userGroups.stream().anyMatch(gitLabSettings::isAllowedGroup) is false — no overlap with sonar.auth.gitlab.allowed-groups.

Common situations: Admin configured full group paths (e.g. my-org/my-team) while matching logic expects bare slugs or vice versa; user recently removed from the group; allowed group exists in a different GitLab instance/namespace; group renamed after configuration.

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


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/58cc4c3d6a5c7276. Report an issue: GitHub.