GitLab Issues
GitLab Issues integration allows your product to fetch, create, and manage issues in GitLab repositories (projects). This integration is widely used for DevSecOps workflows, vulnerability tracking, and ticket synchronization, where identified findings or alerts are automatically converted into GitLab issues for development teams to act on. It works with GitLab Cloud (gitlab.com) or self-hosted GitLab Enterprise instances.
Credentials Needed
To connect with the GitLab REST API, you need one of the following credentials:
Option 1 — Personal Access Token (PAT) (recommended for user-level integrations):
- GitLab Personal Access Token (PAT)
Option 2 — Project Access Token:
- Project Access Token (scoped to a specific GitLab project)
Option 3 — Group Access Token:
- Group Access Token (scoped to all projects under a group)
Always prefer read/write access only for issues — avoid giving full repo control unless necessary.
Permissions Needed / API Scopes
When creating a GitLab token, you must assign the correct scopes (permissions):
| Scope | Description |
|---|---|
api | Full access to all API endpoints (required for issue creation) |
read_api | Read-only access to issues, projects, and groups |
read_user | Read basic user information |
write_repository (optional) | Needed only if repository commits are part of automation |
read_repository (optional) | Read access to repository metadata |
Minimum Required Scope for Issue Management: api (for create/update) or read_api (for read-only access)
Creating Users / Access Tokens
Step 1: Generate a Personal Access Token
- Log in to your GitLab account
- Navigate to User Settings → Access Tokens: https://gitlab.com/-/profile/personal_access_tokens
- Give your token a name, e.g.,
GitLabIssuesIntegration - Select an expiration date (recommended: 90 days)
- Enable the scopes:
- ✅
api - (Optional)
read_user
- ✅
- Click Create Personal Access Token
- Copy and securely store the generated token — it will only be shown once
For Project Access Token
- Go to your Project → Settings → Access Tokens
- Name the token (e.g.,
IssueBotToken) - Set the role: Maintainer or Developer
- Enable scope:
api - Create and store the token securely
Test Connectivity
Example: List Projects
curl --header "PRIVATE-TOKEN: <GITLAB_TOKEN>" \
"https://gitlab.com/api/v4/projects?membership=true"
Example Response:
[
{
"id": 12345,
"name": "security-dashboard",
"path_with_namespace": "user/security-dashboard",
"visibility": "private",
"web_url": "https://gitlab.com/user/security-dashboard"
}
]
Example: List Issues for a Project
curl --header "PRIVATE-TOKEN: <GITLAB_TOKEN>" \
"https://gitlab.com/api/v4/projects/12345/issues"
Example Response:
[
{
"id": 67890,
"iid": 1,
"project_id": 12345,
"title": "Vulnerability: SQL Injection found",
"state": "opened",
"author": {"username": "security-bot"},
"web_url": "https://gitlab.com/user/security-dashboard/-/issues/1"
}
]
Create a New Issue
curl --request POST \
--header "PRIVATE-TOKEN: <GITLAB_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"title": "Critical SQL Injection vulnerability found in /api/auth",
"description": "A SQL injection was detected in the /api/auth endpoint during scan #1245. Immediate patch required.",
"labels": ["security", "critical"],
"assignee_ids": [101]
}' \
"https://gitlab.com/api/v4/projects/12345/issues"
Example Response:
{
"id": 67900,
"iid": 25,
"project_id": 12345,
"title": "Critical SQL Injection vulnerability found in /api/auth",
"state": "opened",
"web_url": "https://gitlab.com/user/security-dashboard/-/issues/25"
}
Save the Results in the Platform and Create Connection
- In your product's integration settings, securely store:
GITLAB_BASE_URL(e.g.,https://gitlab.comorhttps://gitlab.company.com)GITLAB_TOKEN(PAT or Access Token)
- Label the connection as GitLab Issues Integration
- Test the connection by retrieving a list of accessible projects
- On success, enable workflows such as:
- Auto-create GitLab issues for vulnerabilities or incidents
- Sync issue statuses or comments from GitLab back to your platform
- Assign tickets to developers automatically
Best Practices
- Use fine-grained tokens with minimal scopes (
apiorread_api) - Store tokens securely in a secret vault (never in environment files)
- Rotate access tokens every 90 days
- Use Project Access Tokens for per-project isolation instead of PATs
- Respect GitLab's rate limits (typically 600 requests/minute per user)
- Implement pagination (
?per_page=100&page=n) for large projects - Use GitLab webhooks for real-time sync of issue updates
- Log issue creation and updates for audit purposes
- For enterprise users, support both self-hosted GitLab URLs and gitlab.com
Useful GitLab API Endpoints
| Resource | Method | Endpoint | Description |
|---|---|---|---|
| List projects | GET | /api/v4/projects?membership=true | Fetch user-accessible projects |
| Get issues | GET | /api/v4/projects/{project_id}/issues | List all issues for a project |
| Get issue details | GET | /api/v4/projects/{project_id}/issues/{issue_iid} | Retrieve single issue |
| Create issue | POST | /api/v4/projects/{project_id}/issues | Create a new issue |
| Update issue | PUT | /api/v4/projects/{project_id}/issues/{issue_iid} | Edit title, description, or status |
| Comment on issue | POST | /api/v4/projects/{project_id}/issues/{issue_iid}/notes | Add comment to an issue |
| List labels | GET | /api/v4/projects/{project_id}/labels | Retrieve labels for tagging issues |
| List assignees | GET | /api/v4/projects/{project_id}/users | Get users assignable to issues |
Official API Docs: https://docs.gitlab.com/ee/api/issues.html
Webhook Integration (Optional)
Set up webhooks to automatically sync issue changes from GitLab to your platform.
- Go to Project → Settings → Webhooks
- Set URL = your platform's webhook endpoint
- Select Events:
- Issues events
- Note events (for comments)
- Label events (optional)
- Click Add Webhook
Your system will now receive payloads whenever an issue is created, updated, or closed in GitLab.
Example JSON Payload for Creating Issue
{
"title": "Open Port Detected on Production Server",
"description": "Port 22 is open and exposed to the public internet. Review firewall rules.",
"labels": ["security", "network"],
"assignee_ids": [52]
}
Example JSON Response
{
"id": 98765,
"iid": 12,
"title": "Open Port Detected on Production Server",
"state": "opened",
"labels": ["security", "network"],
"assignees": [{"id": 52, "username": "devops-team"}],
"web_url": "https://gitlab.com/devops/security-dashboard/-/issues/12"
}