Skip to content

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 api scope, or a group/project access token with read_api scope
  • Instance-level events require an administrator account

Configuration

Step 1: Create a GitLab Access Token

  1. Go to GitLab > User Settings > Access Tokens
  2. Create a token with the api scope
  3. Set an appropriate expiration date

For group-level only access:

  1. Go to Group > Settings > Access Tokens
  2. Create a token with read_api scope and Reporter role minimum

Step 2: Configure KYRA Collector

/etc/kyra-collector/sources.d/gitlab-audit.yaml
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"
Terminal window
kyra-collector reload
kyra-collector status

Step 3: Verify API Access

Test the Audit Events API directly:

Terminal window
# 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 events
curl -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 events
curl -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:

  1. Go to Group > Settings > Audit events > Streams (or Admin > Settings for instance-level)
  2. Click Add streaming destination
  3. Enter the KYRA Collector webhook URL: https://<COLLECTOR_IP>:8443/webhook/gitlab-audit
  4. Add a verification token for request authentication
  5. Optionally add custom headers for additional authentication
Terminal window
# Or configure via API
curl --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:

Terminal window
# List available event type filters
curl -s --header "PRIVATE-TOKEN: <TOKEN>" \
"https://gitlab.example.com/api/v4/audit_events" \
| jq '[.[].details.custom_message] | unique'

Key event categories to collect:

CategoryExample Events
Authenticationuser_logged_in, user_logged_out, two_factor_disabled
Authorizationmember_added, member_removed, access_level_changed
Repositoryproject_created, project_destroyed, repository_downloaded
CI/CDci_variable_created, ci_variable_updated, runner_registered
Compliancemerge_request_approved, protected_branch_created, approval_rule_updated
Securitydeploy_key_added, personal_access_token_created, ssh_key_created

Step 6: Verify on KYRA Collector

Terminal window
kyra-collector logs --source gitlab-audit --tail 10

Collected Log Types

Log TypeDescriptionSecurity Use
Instance EventsServer-wide admin actions, user managementInfrastructure security
Group EventsGroup membership, settings, SAML/SCIM changesIdentity governance
Project EventsRepository access, CI/CD changes, protected branch updatesCode security
Authentication EventsLogin, logout, token creation, SSH key additionsAccount security
CI/CD EventsVariable changes, runner registration, pipeline triggersSupply chain security

Security-Critical GitLab Events

EventIndicatorDescription
two_factor_disabledSecurity downgradeUser disabling MFA on their account
project_visibility_changed to publicData exposureInternal/private project made public
member_added with Owner/MaintainerPrivilege escalationElevated access granted to group or project
deploy_key_addedPersistent accessDeploy key added to repository (no expiry by default)
ci_variable_created with protected: falseSecret exposureCI/CD variable exposed to unprotected branches
project_destroyedData destructionRepository permanently deleted
personal_access_token_created with long expiryCredential riskLong-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=100 and created_after filters to reduce pagination.

Contact kyra@seekerslab.com for integration support.