GitLab
Connect GitLab.com or a self-managed GitLab to Safeguard. The scopes and roles each token needs, which token types work, and step-by-step setup.
What it does
The GitLab card connects Safeguard to projects on GitLab.com or on your own self-managed GitLab server. Safeguard lists the projects a token is a member of, and each project you select (at a branch or tag) becomes a Safeguard project that is cloned and scanned for an SBOM and findings. With write access, Safeguard can also open fix and upgrade merge requests, comment on merge requests and set a commit status for the quality gate. Find the card under Integrations on the Project/Product tab.
Public vs private
| Public | Private | |
|---|---|---|
| What you enter | One or more public project URLs, like https://gitlab.com/group/repository-name | Where GitLab runs, and an access token |
| Credential needed | None | A personal, group or project access token |
| What you can scan | The public projects you add by URL | Every project the token is a member of |
| Container registry | The registries of the public projects you added, read and pulled without a token (the project's registry must be public too) | The registries of every project the token can read, pulled with the token |
Supported auth methods
| Method | Use it when | Notes |
|---|---|---|
| Group access token | Recommended for a team: one token for all projects of a group | A bot user with the role you choose. On GitLab.com it needs Premium or Ultimate |
| Project access token | One project only | Same as a group token, for a single project. On GitLab.com it needs Premium or Ultimate |
| Personal access token | GitLab Free on GitLab.com, or you want the token tied to a person or service account | Sees every project that user is a member of |
| None (Public tab) | Public projects only | Nothing to create |
Signing in with GitLab (OAuth) is not available. The dialog takes an access token only.
Permissions required
For scanning, Safeguard only reads. It writes to GitLab only for the optional features marked below, and only when you use them.
Personal, group or project access token: scopes
| Scope | Required? | What Safeguard uses it for |
|---|---|---|
read_api | Required | Checking the token (/user), listing projects you are a member of, and reading project details, branches, tags and files |
read_repository | Required | Cloning the project over HTTPS for the scan |
read_registry | Optional | The Container registry section: pulling the container images you choose there for image scans. Listing the registry's images and tags uses read_api |
api | Optional | Fix and upgrade merge requests (creating the branch, committing files, opening the merge request), merge request comments and discussions, the Quality gate commit status, and merging from Safeguard. api includes everything read_api grants |
write_repository | Not needed | It covers Git push only and does not work with the API; Safeguard writes through the API |
read_user | Not needed | read_api already covers /user |
Group or project access token: role
| Role | Required? | What it allows |
|---|---|---|
| Reporter | Required | Reading and cloning the code of private projects (on GitLab 18.7 and later, Planner can also read private repository content) |
| Developer | Optional | Creating branches and merge requests for fix merge requests, and the quality gate's commit status |
| Maintainer | Optional | Only if Safeguard should merge into a protected branch |
A personal access token acts with the role its user has in each project, so give that user at least Reporter.
Least privilege: a group access token with the Reporter role and the read_api and read_repository scopes.
Token types
| Token type | Works? | Notes |
|---|---|---|
| Group access token | Yes (recommended) | Reaches the group's projects and subgroups. Create it with the Owner role on the group |
| Project access token | Yes | Reaches one project. Create it with the Maintainer or Owner role on the project |
| Personal access token | Yes | Reaches every project its user is a member of |
| Deploy token | No | GitLab does not accept deploy tokens on the REST API, so Safeguard cannot list projects with one |
| CI/CD job token | No | It exists only inside a pipeline job |
| OAuth sign-in | Not available yet |
Expiry: GitLab sets an expiry date on every token, 365 days at most by default. Choose a shorter one, such as 90 days. When it expires, listing and scans fail until you paste a new token in the connection. GitLab emails the project or group members before a bot token expires.
What we never need: sudo, admin_mode, write_registry, create_runner, k8s_proxy, the Owner role, or any write scope when you only scan.
Step-by-step setup
Create the credential in GitLab
Group access token (project access tokens are the same, from the project's settings):
- Select Search or go to and open your group.
- Select Settings > Access tokens, then Add new token.
- Enter a name and an expiry date, choose the Reporter role (or Developer for fix merge requests), and select the scopes
read_apiandread_repository(addapifor fix merge requests). - Select Create group access token and copy the token. GitLab shows it only once.
Personal access token:
- Select your avatar, then Edit profile.
- Select Access > Personal access tokens, and from the Generate token dropdown choose Legacy token.
- Enter a Token name, set an Expiration date, and select
read_apiandread_repository(addapifor fix merge requests). - Select Generate token and copy it. GitLab shows it only once.
Or with the GitLab CLI
# Group access token, Reporter role, read-only, 90 days
glab token create --group my-group --access-level reporter \
--scope read_api --scope read_repository --duration 90d safeguard-scan
# Project access token for one project
glab token create --repo my-group/my-project --access-level reporter \
--scope read_api --scope read_repository --duration 90d safeguard-scan
# Check what the token sees, as Safeguard does
curl --header "PRIVATE-TOKEN: <token>" "https://gitlab.com/api/v4/projects?membership=true&per_page=100"glab can create personal access tokens for yourself only with the k8s_proxy scope, so create a personal token in the web page above.
Connect it in Safeguard
- Open Integrations and choose the Project/Product tab.
- Click Connect on the GitLab card.
- For public projects, stay on Public, enter a Name, paste each URL under Enter a public URL and click Add. Then click Next.
- For private projects, choose Private and enter a Name (and an optional Description).
- Under Where does GitLab run?, keep GitLab.com (SaaS), or choose Self-managed and enter your Server URL, such as
https://gitlab.example.com. - Paste the token into Access Token and click Check. "Access token validated successfully" means GitLab accepted it.
- Click Next, select the projects and the branch or tag of each, and finish with the Connect button (fast, deep or progressive scan).
- Container images (switched on per workspace): open the connection again with Update. On the review step, the Container registry section lists the images in your projects' GitLab container registries, read with the same server and token. Tick an image, pick a tag, and save. Each image becomes its own project, scanned with the same token and pinned to the digest the tag points at when the scan starts. The token needs
read_registryfor this, and its user at least the Reporter role on each project. On a Public connection the section lists only the registries of the public projects you added, read anonymously, and the scanner pulls the images without a token; GitLab shows a registry this way only when both the project and its container registry are public.
A self-managed server must be reachable from the internet over a public address. Safeguard does not send a token to private or internal addresses.
Webhooks and triggers
This integration has no webhooks to set up. Each selected project is scanned when you connect it. GitLab sends no push events for its container registry to project webhooks, so container images are rescanned on a schedule too. To rescan new commits, set a schedule under Integrations > Scheduled, or choose Rescan from the connection's menu under Project Configurations.
What we read and store
- Read: the token's user, the list of projects it is a member of with their details, branches and tags, and the contents of each selected project at the chosen branch or tag. For merge request features, the merge request, its changes and its notes. With the container registry on, the projects' registry repositories and tags, and the images you choose.
- Stored: the connection's settings, the projects you selected, the SBOM and findings of each scan, and the token, which is encrypted at rest with a per-workspace key and never shown again after you save it.
- Not stored: source code. The scanner makes a shallow clone into a temporary folder and deletes it when the scan ends.
- No customer data from this integration is sent to third-party LLMs.
Troubleshooting
| Message you see | Cause | Fix |
|---|---|---|
Invalid or expired access token | GitLab refused the token, or the token lacks read_api (a token with only read_repository cannot call the API) | Check the expiry and scopes, or create a new token with read_api and read_repository |
Failed to validate access token | Safeguard could not reach the GitLab server | Check the Server URL and that the server is reachable from the internet |
This server address isn't allowed: ... | The server address is private, internal or contains a user name and password | Use the server's public https address |
Failed to create configuration | The connection could not be saved, often because the token stopped working between Check and Next | Click Check again and retry |
Invalid repository URL | A URL on the Public tab is not a public GitLab project | Copy the URL from the project page, or connect it on the Private tab |
| No projects in the list | A project or group token sees only its own project or group; a personal token sees only projects its user is a member of | Use a group token on the right group, or add the user to the projects |
GitLab rejected the token for the container registry ... It needs the read_api scope to list registry repositories and read_registry to pull images ... | The token lacks a scope, expired, or was revoked | Add read_api and read_registry, or paste a new token |
The GitLab token cannot read the container registry of ... Its user needs at least the Reporter role on the project ... | The token's user has no role on that project, or the registry is private to members | Give the user (or the group token) the Reporter role |
git clone failed: ... (on a scan) | The token lacks read_repository, expired, or lost its role on the project | Add the scope or role, or paste a new token in the connection |
Rotation and disconnect
- Rotate: create a new token with the same role and scopes. Under Project Configurations on the Project/Product tab, open the connection's menu, choose Update, paste the new token into Access Token, click Check, and click Save Changes. Then revoke the old token in GitLab.
- Disconnect: choose Delete from the connection's menu under Project Configurations and confirm Delete configuration. Then revoke the token under Settings > Access tokens (or Edit profile > Access > Personal access tokens).
Vendor references
- Personal access tokens, checked 2026-10-16.
- Group access tokens, checked 2026-10-16.
- Project access tokens, checked 2026-10-16.
- Access token scopes, checked 2026-10-16.
- Container registry API, checked 2026-10-16.
- Deploy tokens, checked 2026-10-16.
- Roles and permissions, checked 2026-10-16.
- glab token create, checked 2026-10-16.
GitHub
Connect GitHub repositories to Safeguard. The permissions each token needs, which token types work, and step-by-step setup for GitHub.com and GitHub Enterprise Server.
Bitbucket
Connect Bitbucket Cloud repositories to Safeguard. The API token scopes Safeguard needs, which Bitbucket credentials work, and step-by-step setup.