Skip to main content

GitLab

This guide explains how to set up Single Sign-On (SSO) between SmartLink and GitLab. GitLab supports both OpenID Connect and SAML2 - we recommend OpenID Connect for its simplicity.

Prerequisites

  • GitLab CE/EE version 11.4+ (for OpenID Connect)
  • GitLab CE/EE version 9.0+ (for SAML2)
  • Administrator access to GitLab
  • Application configured in SmartLink

1. Create the application

  1. Log in to SmartLink as an administrator
  2. Go to ApplicationsAdd
  3. Create a new application:
    • Name: GitLab
    • URL: https://gitlab.example.com
    • Description: GitLab DevOps Platform
    • Icon: Choose the GitLab icon

2. Configure OpenID Connect

  1. In the Authentication tab
  2. Select OpenID Connect
  3. Note the following information:
    • Client ID: gitlab-xxxxxx
    • Client Secret: secret-xxxxxx
    • Issuer URL: https://your-smartlink.link.vaultys.org/api/oidc/[appid]
    • App ID: [appid] (unique identifier of the application in SmartLink)

3. Redirect URLs

Add to Allowed Redirect URLs:

https://gitlab.example.com/users/auth/openid_connect/callback

4. Required Scopes

  • openid
  • profile
  • email
  • groups (optional, for group synchronization)

Configuration in GitLab

1. Omnibus Configuration (gitlab.rb)

Edit /etc/gitlab/gitlab.rb:

### OpenID Connect Configuration with SmartLink ###

gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']
gitlab_rails['omniauth_sync_email_from_provider'] = 'openid_connect'
gitlab_rails['omniauth_sync_profile_from_provider'] = ['openid_connect']
gitlab_rails['omniauth_sync_profile_attributes'] = ['name', 'email']
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'openid_connect'
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_user'] = ['openid_connect']

gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
label: "SmartLink SSO",
icon: "https://your-smartlink.example.com/logo.png",
args: {
name: "openid_connect",
scope: ["openid", "profile", "email", "groups"],
response_type: "code",
issuer: "https://your-smartlink.link.vaultys.org",
discovery: true,
discovery_endpoint: "https://your-smartlink.link.vaultys.org/api/oidc/[appid]/.well-known/openid-configuration",
client_auth_method: "query",
uid_field: "sub",
send_scope_to_token_endpoint: "false",
pkce: true,
client_options: {
identifier: "gitlab-xxxxxx",
secret: "secret-xxxxxx",
redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
}
}
}
]

# Group synchronization (optional)
gitlab_rails['omniauth_external_providers'] = ['openid_connect']
gitlab_rails['omniauth_allow_bypass_two_factor'] = ['openid_connect']

2. Docker Configuration

For GitLab Docker, use environment variables:

version: '3.8'
services:
gitlab:
image: gitlab/gitlab-ee:latest
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'openid_connect'
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
label: "SmartLink SSO",
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://your-smartlink.link.vaultys.org",
discovery: true,
discovery_endpoint: "https://your-smartlink.link.vaultys.org/api/oidc/[appid]/.well-known/openid-configuration",
uid_field: "sub",
client_options: {
identifier: "${OIDC_CLIENT_ID}",
secret: "${OIDC_CLIENT_SECRET}",
redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
}
}
}
]

3. Apply the Configuration

# For Omnibus
gitlab-ctl reconfigure
gitlab-ctl restart

# For Docker
docker-compose up -d

Group Synchronization

To automatically synchronize SmartLink groups with GitLab:

# In gitlab.rb
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
# ... existing configuration ...
groups_attribute: "groups",
admin_groups: ["smartlink_admins"],
external_groups: ["smartlink_external"],
required_groups: ["gitlab_users"]
}
}
]

Configuration with SAML2

1. Configure SAML2

  1. In the GitLab application
  2. Authentication tab → SAML2
  3. Configure:
    • Entity ID: https://gitlab.example.com
    • ACS URL: https://gitlab.example.com/users/auth/saml/callback
    • NameID Format: emailAddress

2. Download Metadata

Download or note:

  • IdP Metadata: https://your-smartlink.link.vaultys.org/api/saml2/[appid]/metadata
  • X.509 Certificate
  • SSO URL: https://your-smartlink.link.vaultys.org/api/saml2/[appid]/sso
  • SLO URL: https://your-smartlink.link.vaultys.org/api/saml2/[appid]/slo

Configuration in GitLab

# In /etc/gitlab/gitlab.rb

gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_saml_user'] = true

gitlab_rails['omniauth_providers'] = [
{
name: "saml",
label: "SmartLink SSO",
args: {
assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
idp_cert: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
idp_sso_target_url: "https://your-smartlink.link.vaultys.org/api/saml2/[appid]/sso",
idp_metadata_url: "https://your-smartlink.link.vaultys.org/api/saml2/[appid]/metadata",
issuer: "https://gitlab.example.com",
name_identifier_format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
attribute_statements: {
email: ['email'],
name: ['name'],
nickname: ['username'],
groups: ['groups']
}
}
}
]

Permission Management

Role Mapping

Configure automatic role mapping:

# OpenID Connect
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
# GitLab administrator groups
admin_groups: ["smartlink-gitlab-admins"],

# External users (limited access)
external_groups: ["smartlink-contractors"],

# Required groups for access
required_groups: ["smartlink-gitlab-users"],

# Auditor groups (read-only)
auditor_groups: ["smartlink-auditors"]
}
}
]

Auto-Provisioning Projects

To automatically create projects based on groups:

# Custom provisioning script
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
# ... configuration ...
after_sign_in_path: proc do |user, groups|
groups.each do |group|
# Project/group creation logic
Group.find_or_create_by(path: group) do |g|
g.name = group
g.add_user(user, :developer)
end
end
end
}
}
]

User Configuration

Automatic License Assignment (GitLab EE)

# For GitLab Enterprise Edition
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
# ... configuration ...
license_groups: {
ultimate: ["smartlink-ultimate-users"],
premium: ["smartlink-premium-users"],
starter: ["smartlink-starter-users"]
}
}
}
]

User Profile Configuration

# Full profile synchronization
gitlab_rails['omniauth_sync_profile_from_provider'] = ['openid_connect']
gitlab_rails['omniauth_sync_profile_attributes'] = [
'name',
'email',
'location',
'bio',
'organization',
'website_url'
]

Configuration Testing

1. Connection Test

  1. Log out of GitLab
  2. On the login page, click on SmartLink SSO
  3. Authenticate on SmartLink
  4. Verify redirection to GitLab

2. Permission Verification

# Using GitLab API
curl -H "PRIVATE-TOKEN: your_token" \
"https://gitlab.example.com/api/v4/user"

# Using Rails console
gitlab-rails console
user = User.find_by_email('user@example.com')
user.identities
user.group_members

3. Git Test

# Clone with SSO
git clone https://gitlab.example.com/group/project.git

# If prompted, use:
# Username: oauth2
# Password: [your personal access token]

Troubleshooting

Error "Could not authenticate you from OpenIDConnect"

Solution:

  1. Check GitLab logs:
    gitlab-ctl tail gitlab-rails
  2. Test OIDC discovery with your appid:
    curl https://your-smartlink.link.vaultys.org/api/oidc/[appid]/.well-known/openid-configuration
  3. Verify the Client ID and Secret

Groups are not Synchronized

Solution:

  1. Check the groups claim in the OIDC response
  2. Enable detailed logs:
    gitlab_rails['omniauth_providers'] = [
    {
    args: {
    client_options: {
    debug: true
    }
    }
    }
    ]

Error 422 after authentication

Solution:

  1. Ensure email is unique in GitLab
  2. Enable auto-link:
    gitlab_rails['omniauth_auto_link_user'] = ['openid_connect']

Users are Blocked after Creation

Solution:

# Disable automatic blocking
gitlab_rails['omniauth_block_auto_created_users'] = false

# Or manually unblock
gitlab-rails console
User.where(state: 'blocked').update_all(state: 'active')

Security

Recommendations

  1. Mandatory HTTPS on GitLab and SmartLink
  2. Regular secrets rotation
  3. Limitation of groups with required_groups
  4. Enabled audit logs:
    gitlab_rails['audit_events_enabled'] = true
  5. 2FA bypass only if SmartLink manages MFA:
    gitlab_rails['omniauth_allow_bypass_two_factor'] = ['openid_connect']

CSRF Protection

# Protection against CSRF attacks
gitlab_rails['omniauth_providers'] = [
{
args: {
pkce: true, # Use PKCE for OpenID Connect
state: true # Verify the state parameter
}
}
]

Advanced Configuration

Multi-Instance GitLab

For multiple GitLab instances with the same SmartLink:

# Production instance
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
client_options: {
identifier: "gitlab-prod-xxxxxx",
redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
}
}
}
]

# Staging instance
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
args: {
client_options: {
identifier: "gitlab-staging-xxxxxx",
redirect_uri: "https://gitlab-staging.example.com/users/auth/openid_connect/callback"
}
}
}
]

CI/CD Integration

To use SSO in pipelines:

# .gitlab-ci.yml
variables:
CI_JOB_TOKEN_SCOPE: "openid_connect"

deploy:
script:
- |
TOKEN=$(curl -X POST https://your-smartlink.link.vaultys.org/api/oidc/[appid]/token \
-d "grant_type=client_credentials" \
-d "client_id=${CI_CLIENT_ID}" \
-d "client_secret=${CI_CLIENT_SECRET}")
- # Use $TOKEN for deployments

Resources