doc/administration/auth/smartcard.md
{{< details >}}
{{< /details >}}
GitLab supports authentication using smart cards.
By default, existing users can continue to sign in with a username and password when smart card authentication is enabled.
To force existing users to use only smart card authentication, disable username and password authentication.
GitLab supports two authentication methods:
{{< details >}}
{{< /details >}}
Smart cards with X.509 certificates can be used to authenticate with GitLab.
To use a smart card with an X.509 certificate to authenticate against a local
database with GitLab, CN and emailAddress must be defined in the
certificate. For example:
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 12856475246677808609 (0xb26b601ecdd555e1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=Random Corp Ltd, CN=Random Corp
Validity
Not Before: Oct 30 12:00:00 2018 GMT
Not After : Oct 30 12:00:00 2019 GMT
Subject: CN=Gitlab User, [email protected]
{{< details >}}
{{< /details >}}
Smart cards with X.509 certificates using SAN extensions can be used to authenticate with GitLab.
To use a smart card with an X.509 certificate to authenticate against a local database with GitLab:
subjectAltName (SAN) extensions
must define the user identity (email) within the GitLab instance (URI).URI must match Gitlab.config.host.gitlab.email with the URI.For example:
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 12856475246677808609 (0xb26b601ecdd555e1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=Random Corp Ltd, CN=Random Corp
Validity
Not Before: Oct 30 12:00:00 2018 GMT
Not After : Oct 30 12:00:00 2019 GMT
...
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment, Data Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
email:[email protected], URI:http://gitlab.example.com/
{{< details >}}
{{< /details >}}
GitLab implements a standard way of certificate matching following
RFC4523. It uses the
certificateExactMatch certificate matching rule against the userCertificate
attribute. As a prerequisite, you must use an LDAP server that:
certificateExactMatch matching rule.userCertificate attribute.{{< history >}}
reverse_issuer_and_subject and reverse_issuer_and_serial_number formats in GitLab 17.11.issuer_and_subject, reverse_issuer_and_subject, and subject formats updated in GitLab 18.6 with a flag named smartcard_ad_formats_v2. Enabled by default. Disable this flag to revert these formats to the previous versions.smartcard_ad_formats_v2 removed.{{< /history >}}
[!flag] The functionality of this feature is controlled by a feature flag. For more information, see the history.
Active Directory does not support the certificateExactMatch rule or the userCertificate attribute. Most tools for certificate-based authentication such as smart cards use the altSecurityIdentities attribute, which can contain multiple certificates for each user. The data in the field must match one of the formats Microsoft recommends.
Use the following attributes to customize the field GitLab checks and the format for certificate data:
smartcard_ad_cert_field - specify the name of the field to search. This can be any attribute on a user object.smartcard_ad_cert_format - specify the format of the information gathered from the certificate. This format must be one of the following values. The most common is
issuer_and_serial_number to match the behavior of non-Active Directory LDAP servers.smartcard_ad_cert_format | Example data |
|---|---|
principal_name | X509:<PN>[email protected] |
rfc822_name | X509:<RFC822>[email protected] |
subject | X509:<S>CN=dennis,OU=UserAccounts,DC=example,DC=com |
issuer_and_serial_number | X509:<I>CN=CONTOSO-DC-CA,DC=example,DC=com<SR>1181914561 |
issuer_and_subject | X509:<I>CN=EXAMPLE-DC-CA,DC=example,DC=com<S>CN=cynthia,OU=UserAccounts,DC=example,DC=com |
reverse_issuer_and_serial_number | X509:<I>DC=com,DC=example,CN=CONTOSO-DC-CA<SR>1181914561 |
reverse_issuer_and_subject | X509:<I>DC=com,DC=example,CN=CONTOSO-DC-CA<S>CN=cynthia,OU=UserAccounts,DC=example,DC=com |
reverse_issuer_and_reverse_subject | X509:<I>DC=com,DC=example,CN=CONTOSO-DC-CA<S>DC=com,DC=example,OU=UserAccounts,CN=cynthia |
For issuer_and_serial_number, the <SR> portion is in reverse-byte-order, with the least-significant byte first. For more information, see how to map a user to a certificate using the altSecurityIdentities attribute.
The reverse issuer formats sort the issuer string from the smallest unit to the largest. Some Active Directory servers store certificates in this format.
[!note] If no
smartcard_ad_cert_formatis specified, but an LDAP server is configured withactive_directory: trueand smart cards enabled, GitLab defaults to the behavior of 16.8 and earlier, and usescertificateExactMatchon theuserCertificateattribute.
{{< history >}}
{{< /history >}}
Microsoft Entra ID, formerly known as Azure Active Directory, provides a cloud-based directory for companies and organizations. Entra Domain Services provides a secure read-only LDAP interface to the directory, but only exposes a limited subset of the fields Entra ID has.
Entra ID uses the CertificateUserIds field to manage client certificates for users, but this field is not exposed in LDAP / Entra ID Domain Services. With a cloud-only setup, it is not possible for GitLab to authenticate users' smart cards using LDAP.
In a hybrid on-premise and cloud environment, entities are synced between the on-premise Active Directory controller and the cloud Entra ID using Entra Connect. If you are syncing your altSecurityIdentities attribute to certificateUserIds in Entra ID using Entra ID Connect, you can expose this data in LDAP / Entra ID Domain Services so it can be authenticated by GitLab:
altSecurityIdentities to an additional attribute in Entra ID.smartcard_ad_cert_field field in GitLab to use this extension attribute.For Linux package installations:
Edit /etc/gitlab/gitlab.rb:
# Allow smart card authentication
gitlab_rails['smartcard_enabled'] = true
# Path to a file containing a CA certificate
gitlab_rails['smartcard_ca_file'] = "/etc/ssl/certs/CA.pem"
# Host and port where the client side certificate is requested by the
# webserver (NGINX/Apache)
gitlab_rails['smartcard_client_certificate_required_host'] = "smartcard.example.com"
gitlab_rails['smartcard_client_certificate_required_port'] = 3444
[!note] Assign a value to at least one of the following variables:
gitlab_rails['smartcard_client_certificate_required_host']orgitlab_rails['smartcard_client_certificate_required_port'].
Save the file and reconfigure GitLab for the changes to take effect.
For self-compiled installations:
Configure NGINX to request a client side certificate
In NGINX configuration, an additional server context must be defined with the same configuration except:
The additional NGINX server context must be configured to run on a different port:
listen *:3444 ssl;
It can also be configured to run on a different hostname:
listen smartcard.example.com:443 ssl;
The additional NGINX server context must be configured to require the client side certificate:
ssl_verify_depth 2;
ssl_client_certificate /etc/ssl/certs/CA.pem;
ssl_verify_client on;
The additional NGINX server context must be configured to forward the client side certificate:
proxy_set_header X-SSL-Client-Certificate $ssl_client_escaped_cert;
For example, the following is an example server context in an NGINX
configuration file (such as in /etc/nginx/sites-available/gitlab-ssl):
server {
listen smartcard.example.com:3443 ssl;
# certificate for configuring SSL
ssl_certificate /path/to/example.com.crt;
ssl_certificate_key /path/to/example.com.key;
ssl_verify_depth 2;
# CA certificate for client side certificate verification
ssl_client_certificate /etc/ssl/certs/CA.pem;
ssl_verify_client on;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-SSL-Client-Certificate $ssl_client_escaped_cert;
proxy_read_timeout 300;
proxy_pass http://gitlab-workhorse;
}
}
Edit config/gitlab.yml:
## Smart card authentication settings
smartcard:
# Allow smart card authentication
enabled: true
# Path to a file containing a CA certificate
ca_file: '/etc/ssl/certs/CA.pem'
# Host and port where the client side certificate is requested by the
# webserver (NGINX/Apache)
client_certificate_required_host: smartcard.example.com
client_certificate_required_port: 3443
[!note] Assign a value to at least one of the following variables:
client_certificate_required_hostorclient_certificate_required_port.
Save the file and restart GitLab for the changes to take effect.
For extra security, deploy GitLab behind a firewall such as CloudFlare WAF or a server running ModSecurity. URLs matching the following patterns should be accessible to NGINX deployed as part of GitLab, but not to external clients:
/-/smartcard/extract_certificate
/-/smartcard/verify_certificate
These paths should only be externally accessible using the smartcard hostname and port allocated to NGINX, and not externally accessible using the primary GitLab hostname and port. This should be robust against HTTP Host Header attacks, so that users cannot submit their own certificate parameters without going through NGINX.
For Linux package installations:
Add to /etc/gitlab/gitlab.rb:
gitlab_rails['smartcard_san_extensions'] = true
Save the file and reconfigure GitLab for the changes to take effect.
For self-compiled installations:
Add the san_extensions line to config/gitlab.yml within the smart card section:
smartcard:
enabled: true
ca_file: '/etc/ssl/certs/CA.pem'
client_certificate_required_port: 3444
# Enable the use of SAN extensions to match users with certificates
san_extensions: true
Save the file and restart GitLab for the changes to take effect.
For Linux package installations:
Edit /etc/gitlab/gitlab.rb:
gitlab_rails['ldap_servers'] = YAML.load <<-EOS
main:
# snip...
# Enable smart card authentication against the LDAP server. Valid values
# are "false", "optional", and "required".
smartcard_auth: optional
# If your LDAP server is Active Directory, you can configure these two fields.
# Specify which field contains certificate information, 'altSecurityIdentities' by default
smartcard_ad_cert_field: altSecurityIdentities
# Specify format of certificate information. Valid values are:
# principal_name, rfc822_name, issuer_and_subject, subject, issuer_and_serial_number
smartcard_ad_cert_format: issuer_and_serial_number
EOS
Save the file and reconfigure GitLab for the changes to take effect.
For self-compiled installations:
Edit config/gitlab.yml:
production:
ldap:
servers:
main:
# snip...
# Enable smart card authentication against the LDAP server. Valid values
# are "false", "optional", and "required".
smartcard_auth: optional
# If your LDAP server is Active Directory, you can configure these two fields.
# Specify which field contains certificate information, 'altSecurityIdentities' by default
smartcard_ad_cert_field: altSecurityIdentities
# Specify format of certificate information. Valid values are:
# principal_name, rfc822_name, issuer_and_subject, subject, issuer_and_serial_number
smartcard_ad_cert_format: issuer_and_serial_number
Save the file and restart GitLab for the changes to take effect.
For Linux package installations:
Edit /etc/gitlab/gitlab.rb:
gitlab_rails['smartcard_required_for_git_access'] = true
Save the file and reconfigure GitLab for the changes to take effect.
For self-compiled installations:
Edit config/gitlab.yml:
## Smart card authentication settings
smartcard:
# snip...
# Browser session with smart card sign-in is required for Git access
required_for_git_access: true
Save the file and restart GitLab for the changes to take effect.
The Generated passwords for users created through integrated authentication guide provides an overview of how GitLab generates and sets passwords for users created via smart card authentication.