GitLab Audit Events
Overview
GitLab provides audit events at instance, group, and project levels for compliance tracking. KYRA MDR collects these events via the GitLab Audit Events API to detect unauthorized access, permission escalation, and configuration changes across your GitLab environment.
Prerequisites
- KYRA MDR account (MDR tier or above)
- KYRA Collector installed with HTTPS access to your GitLab instance
- GitLab Premium or Ultimate tier (audit events API requires Premium+)
- Personal access token with
apiscope, or a group/project access token withread_apiscope - Instance-level events require an administrator account
Configuration
Step 1: Create a GitLab Access Token
- Go to GitLab > User Settings > Access Tokens
- Create a token with the
apiscope - Set an appropriate expiration date
For group-level only access:
- Go to Group > Settings > Access Tokens
- Create a token with
read_apiscope and Reporter role minimum
Step 2: Configure KYRA Collector
source: type: gitlab-audit base_url: "https://gitlab.example.com" # or https://gitlab.com token: "<ACCESS_TOKEN>" poll_interval: 300 # seconds collect: - instance # requires admin token - groups: - "your-group" - "another-group" - projects: - "your-group/your-project"kyra-collector reloadkyra-collector statusStep 3: Verify API Access
Test the Audit Events API directly:
# Instance-level audit events (admin only)curl -s --header "PRIVATE-TOKEN: <TOKEN>" \ "https://gitlab.example.com/api/v4/audit_events?created_after=2024-01-01" \ | jq '.[] | {id, author_id, entity_type, entity_path, details}'
# Group-level audit eventscurl -s --header "PRIVATE-TOKEN: <TOKEN>" \ "https://gitlab.example.com/api/v4/groups/<GROUP_ID>/audit_events?per_page=20" \ | jq '.[] | {id, author: .author.name, action: .details.custom_message, created_at}'
# Project-level audit eventscurl -s --header "PRIVATE-TOKEN: <TOKEN>" \ "https://gitlab.example.com/api/v4/projects/<PROJECT_ID>/audit_events?per_page=20" \ | jq '.[] | {id, author: .author.name, action: .details.custom_message, target: .details.target_details}'Step 4: Configure Audit Event Streaming (GitLab Ultimate)
GitLab Ultimate supports streaming audit events to external HTTP endpoints:
- Go to Group > Settings > Audit events > Streams (or Admin > Settings for instance-level)
- Click Add streaming destination
- Enter the KYRA Collector webhook URL:
https://<COLLECTOR_IP>:8443/webhook/gitlab-audit - Add a verification token for request authentication
- Optionally add custom headers for additional authentication
# Or configure via APIcurl --request POST \ --header "PRIVATE-TOKEN: <ADMIN_TOKEN>" \ --header "Content-Type: application/json" \ --data '{ "destination_url": "https://<COLLECTOR_IP>:8443/webhook/gitlab-audit", "verification_token": "<VERIFICATION_TOKEN>" }' \ "https://gitlab.example.com/api/v4/groups/<GROUP_ID>/audit_events/streaming/destinations"Step 5: Filter by Event Types
Control which events are streamed or collected:
# List available event type filterscurl -s --header "PRIVATE-TOKEN: <TOKEN>" \ "https://gitlab.example.com/api/v4/audit_events" \ | jq '[.[].details.custom_message] | unique'Key event categories to collect:
| Category | Example Events |
|---|---|
| Authentication | user_logged_in, user_logged_out, two_factor_disabled |
| Authorization | member_added, member_removed, access_level_changed |
| Repository | project_created, project_destroyed, repository_downloaded |
| CI/CD | ci_variable_created, ci_variable_updated, runner_registered |
| Compliance | merge_request_approved, protected_branch_created, approval_rule_updated |
| Security | deploy_key_added, personal_access_token_created, ssh_key_created |
Step 6: Verify on KYRA Collector
kyra-collector logs --source gitlab-audit --tail 10Collected Log Types
| Log Type | Description | Security Use |
|---|---|---|
| Instance Events | Server-wide admin actions, user management | Infrastructure security |
| Group Events | Group membership, settings, SAML/SCIM changes | Identity governance |
| Project Events | Repository access, CI/CD changes, protected branch updates | Code security |
| Authentication Events | Login, logout, token creation, SSH key additions | Account security |
| CI/CD Events | Variable changes, runner registration, pipeline triggers | Supply chain security |
Security-Critical GitLab Events
| Event | Indicator | Description |
|---|---|---|
two_factor_disabled | Security downgrade | User disabling MFA on their account |
project_visibility_changed to public | Data exposure | Internal/private project made public |
member_added with Owner/Maintainer | Privilege escalation | Elevated access granted to group or project |
deploy_key_added | Persistent access | Deploy key added to repository (no expiry by default) |
ci_variable_created with protected: false | Secret exposure | CI/CD variable exposed to unprotected branches |
project_destroyed | Data destruction | Repository permanently deleted |
personal_access_token_created with long expiry | Credential risk | Long-lived API token created |
Troubleshooting
- 403 Forbidden: Audit events API requires GitLab Premium or Ultimate. Verify your license tier at Admin > License.
- Empty response: Instance-level audit events require an administrator token. Group/project events require at least Reporter access.
- Missing events: Audit event retention is 1 year on GitLab.com. Self-managed instances retain events indefinitely unless purged.
- Streaming not delivering: Check the streaming destination health status at Group > Settings > Audit events > Streams. Verify the Collector webhook endpoint is reachable and returns HTTP 200.
- Rate limiting: GitLab.com has API rate limits of 400 requests per minute. Use
per_page=100andcreated_afterfilters to reduce pagination.
Contact kyra@seekerslab.com for integration support.