Xcode Cloud omits read_repository OAuth scope for self-managed GitLab private repositories

While validating Xcode Cloud with a self-managed GitLab instance, I found what appears to be an OAuth scope issue affecting private repositories.

Apple’s documentation says to configure the GitLab OAuth application with:

api, read_repository, read_user

However, the actual /oauth/authorize URL generated by Xcode Cloud requests only:

scope=api+read_user

With a private GitLab repository, OAuth completes successfully and Xcode Cloud can call:

GET /api/v4/user → 200

GET /api/v4/projects/:project → 200

But repository setup fails with:

Repository was not found. Either the repository does not exist or you do not have permission to access it.

The GitLab user had Maintainer-or-higher access.

I reproduced this from a clean Xcode Cloud setup.

As a control test, I repeated the exact same flow but manually changed the OAuth authorization request to:

scope=api+read_user+read_repository

GitLab then explicitly requested read-only access to private repositories over Git HTTP.

After authorization, the same private repository connected successfully to Xcode Cloud, and a build could be queued normally.

A public repository works without read_repository, which can hide the issue.

So the reproducible difference was:

  • Private repo + Apple-generated api read_user → fails
  • Private repo + api read_user read_repository → succeeds

This also appears inconsistent with Apple’s own self-managed GitLab setup documentation, which instructs users to enable read_repository.

I’m sharing this mainly for others who may run into the same issue with private repositories.

Xcode Cloud omits read_repository OAuth scope for self-managed GitLab private repositories
 
 
Q