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.