After upgrading a local Gitlab CE installation from 14.x to 16.x I noticed that access tokens didn't work anymore for pulling a private repository:
ck@ansible:/pub/ansible$ cd /pub/ansible && /usr/bin/git pull https://ansible:my-super-secret-token@gitlab.example.com/infrastructure/ansible.git
fatal: unable to access 'https://gitlab.example.com/infrastructure/ansible.git/': The requested URL returned error: 500
During the Gitlab upgrade path, which involved multiple version upgrades, I tested git pull both with login credentials and access tokens:
The access token (ansible) is still showing up in the repository settings in the now upgraded Gitlab:
But "something" seems to have changed concerning the token handling and using this token now results in an internal server error (HTTP 500).
I created a new access token (ansible2023) with the same permissions (role: developer, scope: read_repository) as the old token (ansible):
Both tokens now show up in the list:
Note: I noticed the "Expires" column has changed for the original ansible token from "never" to "in 11 months"... ?
By using the new token (ansible2023) and its secret, the repository pull was working again:
ck@ansible:/pub/ansible$ cd /pub/ansible && /usr/bin/git pull https://ansible2023:my-new-fancy-secret@gitlab.example.com/infrastructure/ansible.git
From https://gitlab.example.com/infrastructure/ansible
* branch HEAD -> FETCH_HEAD
Already up to date.
By the way, if you assign the "guest" role (instead of "developer"), this won't be enough to pull the repository and you get the following error:
ck@ansible:/pub/ansible$ cd /pub/ansible
&& /usr/bin/git pull
https://ansible2023:my-new-fancy-secret@gitlab.example.com/infrastructure/ansible.git
remote: You are not allowed to download code from this project.
fatal: unable to access 'https://gitlab.example.com/infrastructure/ansible.git/': The requested URL returned error: 403
In the Gitlab access logs, the pull can be seen with a HTTP 200:
xxx.xxx.xxx.xxx - - [28/Jul/2023:11:15:01 +0200] "GET /infrastructure/ansible.git/info/refs?service=git-upload-pack HTTP/1.0" 401 279 "" "git/2.30.2" -
xxx.xxx.xxx.xxx - ansible2023 [28/Jul/2023:11:15:01 +0200] "GET /infrastructure/ansible.git/info/refs?service=git-upload-pack HTTP/1.0" 200 164 "" "git/2.30.2" -
xxx.xxx.xxx.xxx - ansible2023 [28/Jul/2023:11:15:01 +0200] "POST /infrastructure/ansible.git/git-upload-pack HTTP/1.0" 200 145 "" "git/2.30.2" -
Of course the big question is: Why did it work before and since the upgrade to 16.x not anymore? The cause seems to be a change mentioned in the deprecation and removals documentation:
Non-expiring access tokens
Announced in GitLab 15.4 (Sep 2022)
Removal in GitLab 16.0 (May 2023) (breaking change)
Access tokens that have no expiration date are valid indefinitely, which presents a security risk if the access token is divulged. Because access tokens that have an exipiration date are better, from GitLab 15.3 we populate a default expiration date.
In GitLab 16.0, any personal, project, or group access token that does not have an expiration date will automatically have an expiration date set at one year.
It doesn't say whether or not the previously active tokens will become immediately invalid, but this seems to be the case given what I just experienced.
Now a few days after the Gitlab upgrade and a weekend with food poisoning (ugh!), I tested the old access token once more. And interestingly it worked:
ck@ansible:/pub/ansible$ cd /pub/ansible && /usr/bin/git pull https://ansible:my-super-secret-token@gitlab.example.com/infrastructure/ansible.git
From https://gitlab.example.com/infrastructure/ansible
* branch HEAD -> FETCH_HEAD
Already up to date.
So to me it looks that the upgrade to Gitlab 16.x triggered the following internally once Gitlab was started:
ck from Switzerland wrote on Jul 31st, 2023:
Manuel, thanks for the comment. Yes, I saw that too. But as you can see from my upgrade experience, the previously used ansible token stopped working after the upgrade to Gitlab 16.x. I noticed that the expiry date was adjusted from never to in 11 months however this existing token did not work anymore after the upgrade. Only new tokens would work again. According to a Gitlab employee, I talked to in the meantime, this could be a bug.
Manuel Kraft from wrote on Jul 31st, 2023:
Hey Claudio,
Thank you for posting your upgrade documentation.
Just want to share with you and your readers, that the token DO NOT get enforced to stop working after upgrading to 16.0 / 16.x .
The personal access tokens will receive an expiration of 1 year in the future after you upgrade and batched background migrations are run.
As GitLab is open source, and if you need to see code to be confident, the value is set to 365.days.from_now here
Ref:
https://gitlab.com/gitlab-org/gitlab/-/blob/eb0f0465ff1f55f1347b981f2502a8e4d4fe6fe4/lib/gitlab/background_migration/cleanup_personal_access_tokens_with_nil_expires_at.rb#L10
Regarding project / group tokens: Under the hood Project and Group access tokens are also Personal Access tokens; the user they belong to is a "bot" user rather than a real human. So this new expiration applies to all 3 types of tokens.
Ref: https://docs.gitlab.com/ee/development/internal_users.html
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office OpenSearch PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder