Add audit event for service account creation
What does this MR do and why?
Adds a new service_account_created audit event that fires whenever a service account is successfully created at the instance, group, or project level.
Currently, service account creation only triggers the generic user_created audit event (via the EE Users::CreateService prepend chain), which provides no service-account-specific context. This makes it difficult for administrators and SIEM integrations to distinguish service account creation from regular user creation — a gap in audit coverage given that service accounts have elevated access.
Changes
- New audit event type (
ee/config/audit_events/types/service_account_created.yml): Definesservice_account_createdwith scope[User, Group, Project],saved_to_database: true, andstreamed: true. - Audit call in base service (
ee/app/services/users/service_accounts/create_service.rb): Addedlog_service_account_audit_eventafter successful creation inexecute. Uses a polymorphicaudit_scopemethod that returns the created user (instance-level). - Scope override in namespace service (
ee/app/services/namespaces/service_accounts/create_service.rb): Overridesaudit_scopeto return the group or project resource. - Tests: Covers instance/group/project-level creation, scope correctness, dual event verification (
user_created+service_account_created),skip_owner_checkpath, and failure scenarios.
Note on duplicate audit events
Both user_created and service_account_created will fire on successful service account creation. This is intentional — they serve different purposes:
user_createdis a generic user lifecycle eventservice_account_createdis a security-specific event with the correct scope (group/project) for SIEM filtering
References
- Closes #595167
- Related: https://gitlab.com/gitlab-org/gitlab/-/issues/593021 (DAP auto-provisioned service accounts)
- Audit event development guide
Screenshots or screen recordings
Not applicable — no UI changes. This is a backend-only audit event addition.
How to set up and validate locally
- Ensure you have an Ultimate license (audit events require it)
- Create an instance-level service account via the API:
curl --request POST --header "PRIVATE-TOKEN: <admin_token>" \ "http://localhost:3000/api/v4/service_accounts" - Check audit events in rails console:
AuditEvent.where(event_name: 'service_account_created').last - Verify the event has the correct scope, target, and message
- Repeat for group-level and project-level service accounts:
# Group-level curl --request POST --header "PRIVATE-TOKEN: <token>" \ "http://localhost:3000/api/v4/groups/<group_id>/service_accounts" # Project-level curl --request POST --header "PRIVATE-TOKEN: <token>" \ "http://localhost:3000/api/v4/projects/<project_id>/service_accounts"
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.