feat(auth): allow a custom OAuth client_id on gitlab.com

Description

On gitlab.com, glab always used its built-in OAuth application and ignored client_id and GITLAB_CLIENT_ID. Now glab auth login on gitlab.com (web and device) can use your own OAuth application.

For gitlab.com, glab picks the application ID in this order:

  • Login: GITLAB_CLIENT_ID, then client_id under hosts.gitlab.com, then the built-in application.
  • Token refresh: client_id under hosts.gitlab.com, then the built-in application.

A top-level or local repository client_id is ignored for gitlab.com. After a successful login with GITLAB_CLIENT_ID, glab saves the ID as client_id for gitlab.com, so the next refresh uses the same application.

Refresh does not read GITLAB_CLIENT_ID, because people often set it machine-wide for a self-managed instance. This way existing gitlab.com sessions keep working. Self-managed and GitLab Dedicated hosts work the same as before.

For the docs, I updated the client_id description and regenerated the config docs. I also added a "Use your own OAuth application" section to the authentication page and updated the GITLAB_CLIENT_ID row in its environment variables table.

Two choices you may want to change:

  1. After a gitlab.com login with GITLAB_CLIENT_ID, I always save the ID, even when it equals the built-in one. This way an old custom ID does not stay. Or do you prefer to save it only when it differs from the built-in one?
  2. A machine-wide GITLAB_CLIENT_ID for a self-managed instance also applies to a new gitlab.com login, as the issue asks. The docs show GITLAB_CLIENT_ID= glab auth login --hostname gitlab.com to use the built-in application. Or should gitlab.com login use only client_id under hosts.gitlab.com?

Closes #8616

How has this been tested?

I added tests for gitlab.com that check the client ID the OAuth endpoints receive:

  • Device login uses GITLAB_CLIENT_ID and saves it under hosts.gitlab.com.
  • A top-level client_id is ignored.
  • Refresh ignores GITLAB_CLIENT_ID and uses the saved client_id.

Three of them fail on the first version of this MR: the shell ID and the top-level ID were used, and nothing was saved.

$ GOFLAGS=-p=2 go test -count=1 ./internal/oauth2/ ./internal/config/
ok  	gitlab.com/gitlab-org/cli/internal/oauth2	1.742s
ok  	gitlab.com/gitlab-org/cli/internal/config	1.808s

I also ran the oauth2 tests with GITLAB_CLIENT_ID set in the shell, to check they do not depend on it:

$ GITLAB_CLIENT_ID=from-shell GOFLAGS=-p=2 go test -count=1 ./internal/oauth2/
ok  	gitlab.com/gitlab-org/cli/internal/oauth2	1.690s

The rest runs in the pipeline.

Implemented with AI assistance; I reviewed and tested the changes.

Edited by Hamza Hassanain

Merge request reports

Loading
Loading