OIDC 'admin_groups' fails to grant admin rights despite valid group claim

Summary

Despite a meticulously configured OIDC integration with Authentik, GitLab consistently fails to grant administrative privileges to users based on the admin_groups setting. The user is always created as a regular user (admin => false), even though the ID Token from the OIDC provider correctly includes the required group claim.

We have performed extensive troubleshooting, including deep analysis of the GitLab source code for our version, and have tried every possible configuration permutation based on that analysis. The issue persists, suggesting a potential bug or a deeply hidden, undocumented configuration requirement in GitLab's OIDC implementation.

Goal

A user logging in via OIDC who is a member of a group specified in the admin_groups array should be automatically promoted to an administrator in GitLab upon their first login.

Environment Details

  • GitLab Version: [PLEASE FILL IN YOUR GITLAB VERSION HERE, e.g., 16.x.x]
  • Installation Method: Omnibus GitLab
  • OIDC Provider: Authentik

Final gitlab.rb Configuration

This is the final, cleaned-up configuration based on source code analysis (lib/gitlab/auth/oauth/user.rb and lib/gitlab/auth/oauth/provider.rb), which dictates that admin_groups and groups_attribute should be read directly from the args hash.

gitlab_rails['omniauth_providers'] = [
  {
    name: 'openid_connect',
    label: 'Aiursoft Login', # Or your preferred label
    args: {
      admin_groups: ["gitlab-admins"],
      groups_attribute: "groups",
      scope: ['openid', 'profile', 'email'],
      response_type: 'code',
      issuer: 'https://auth.aiursoft.cn/application/o/gitlab/',
      discovery: true,
      client_auth_method: 'query',
      uid_field: 'preferred_username',
      send_scope_to_token_endpoint: true,
      pkce: true,
      
      # 4. Client credentials.
      client_options: {
        # I tried both places
        admin_groups: ["gitlab-admins"],
        groups_attribute: "groups",
        identifier: 'dIiGy3SJz4FWOYkFL2x3EOYmpF3a3uVqUL3B6RhJ',
        secret: '[REDACTED]',
        redirect_uri: 'https://gitlab.aiursoft.cn/users/auth/openid_connect/callback'
      }
    }
  }
]

OIDC ID Token Payload (from Authentik)

The Authentik provider is correctly configured and sends the groups claim in the ID Token, as confirmed by the provider's preview functionality.

{
    "iss": "https://auth.xxxxxx.cn/application/o/gitlab/",
    "sub": "aaa@bbb.cn",
    "aud": "xxxxxxxxxx",
    "exp": 1753173973,
    "iat": 1753172173,
    "auth_time": 1753172173,
    "email": "aaa@bbb.cn",
    "email_verified": true,
    "name": "Small Anduin",
    "preferred_username": "smallanduin",
    "groups": [
        "devops-contributors",
        "gitlab-admins"
    ]
}

Troubleshooting Steps Performed

  1. Verified Claim Presence: Confirmed that the groups claim is present in the ID Token from Authentik.
  2. Configuration Nesting: Tested placing admin_groups and groups_attribute in every possible location suggested by documentation and community posts, including directly under args and nested within client_options: { gitlab: { ... } }. Neither worked. The final configuration above reflects the structure dictated by the source code.
  3. Claim Mapping: Implemented map_claim: { groups: 'groups' } to explicitly instruct the underlying omniauth-openid-connect gem to move the groups claim into the auth_hash.info object, which is where GitLab's OIDC::User model expects to find it.
  4. Source Code Analysis: Manually reviewed the GitLab source code for our version, specifically lib/gitlab/auth/oauth/user.rb, lib/gitlab/auth/oidc/user.rb, and lib/gitlab/auth/oauth/provider.rb, to determine the exact logic for reading the configuration and evaluating admin rights. Our final configuration is a direct result of this analysis.

Expected Result

When a user who is a member of the gitlab-admins group logs in, the GitLab logs should show that the user is being saved with administrator privileges.

Example: ... message":"(OAuth) saving user aaa@bbb.cn from login with admin => true, ..."

Actual Result

The user is always created as a regular, non-admin user. The log line consistently shows admin => false.

{"severity":"INFO","time":"2025-07-22T08:35:07.285Z","correlation_id":"01K0RMBB7N1SR776V61RG2QAPH","meta.caller_id":"OmniauthCallbacksController#openid_connect", ... ,"message":"(OAuth) saving user aaa@bbb.com from login with admin => false, extern_uid => smallanduin"}

This demonstrates that while the user is successfully authenticated and created, the group-to-admin role synchronization is completely failing, despite all configurations appearing correct according to the source code itself.

Edited by 🤖 GitLab Bot 🤖