Which GitLab log files matter before you connect a SIEM
Before a SIEM receives anything from GitLab, decide which logs answer which questions. A security team needs authentication, access and audit-style events, while a platform team needs application errors, request performance and the health of the services underneath GitLab. Shipping every file to the SIEM at once creates noise, cost and a harder investigation path, so start by mapping each source to an owner and a use. The main sources are the GitLab application logs (including production_json.log and application.log), the authentication log, the Rails and Workhorse logs that handle web and Git HTTP requests, Gitaly for repository access, the bundled NGINX, PostgreSQL, Redis and Sidekiq logs, and the separate logs for Praefect and related components on larger installations. Confirm the exact file names, locations and log format for your GitLab version in the logging documentation, because component layouts change between releases and between install methods.
For security monitoring, the highest-value sources are usually the authentication and application events that record sign-ins, failed logins, token use, permission changes and project visibility changes. Operations teams usually start with Workhorse, NGINX and Sidekiq logs to diagnose slow requests, failed jobs and queue backlogs, and with PostgreSQL and Redis logs to catch connection or replication problems. Decide which of these sources are structured JSON in your version and which need parsing rules, since that choice drives the effort in the next steps. Also confirm whether audit events are stored in the database and exposed through the API or export features rather than in log files, because a SIEM collecting only files may miss them. Write down the retention you need for each source and who may read it, because logs often contain user names, IP addresses and request paths that count as personal or sensitive data in a regulated environment.
Which log sources answer operations and security questions
A self-managed GitLab instance writes logs from several components, and each one answers a different question. Start by mapping which component answers which operational or security question, then decide what reaches the SIEM. Confirm exact file names, fields and retention against the logging documentation for your GitLab version before you write parsers.
Production JSON for application activity
The production log records requests handled by the Rails application, including controller, status, duration and user context where available. Operations teams use it to find slow endpoints and error spikes, and security teams use it to trace who did what through the web interface and API. Because it is structured JSON, it is the usual first source to forward. Check which fields are present in your version, since field names change between releases and a parser built on one release can silently miss fields in another.
Authentication and sign-in events
Authentication logs record sign-in attempts, failures, token use and related account events. They answer whether a credential is being guessed, which account signed in from an unexpected source, and whether a sign-in method such as SAML or LDAP behaved as expected. Forward these with high priority and confirm that the SIEM alert rules match the event names your version actually emits. Pair them with identity provider logs so that failed sign-ins at GitLab can be correlated with the identity provider's view.
Audit events for administrative changes
Audit events record changes such as permission grants, project visibility changes, membership edits and administrator actions. They answer who changed access controls and when, which is the core question for change management and access reviews. Audit event coverage depends on the GitLab edition and tier, so confirm which events your tier records before relying on them as evidence. Test a deliberate change in a non-production instance and confirm the event reaches the SIEM with the actor and target fields intact.
Workhorse and NGINX access logs
Workhorse and the bundled NGINX write access logs for requests before they reach the application. They show request volume, client addresses, response codes and large transfers such as repository clones and package downloads. Operations teams use them to diagnose slow clones and load balancer behavior, and security teams use them to spot scraping, unusual download volume or requests from unexpected networks. If a reverse proxy sits in front of GitLab, decide whether the client address is recorded from the proxy headers and verify that trust settings are correct.
Gitaly and Sidekiq background processing
Gitaly logs repository operations on the storage nodes, and Sidekiq logs background jobs such as mirroring, imports, webhook delivery and pipeline housekeeping. Operations teams use them when pushes stall, repositories fall behind or jobs back up. Security teams use Sidekiq logs to see which background tasks ran on behalf of which user or integration. Because these components often run on separate hosts in larger deployments, confirm that each host forwards its logs and that the SIEM tags each event with its source host.
How to ship logs from a Linux package install versus the Helm chart
Linux package installs write logs to files on each node, with a subdirectory per component under /var/log/gitlab/. Application requests, background jobs, web server access and Git service activity land in separate files, so the forwarder has to cover several paths instead of one. Read the directory layout on your installed version before you write collector rules, because file names and components can change between releases.
- Main log directory: Start from
/var/log/gitlab/and list each subdirectory to find the files your version actually writes. - Rails and Sidekiq: Application and background job logs record user and API activity, so they are usually the first files to forward for security review.
- Web and Git services: Web server access logs and Git service logs show request sources and repository operations.
- File rotation: Configure the collector to follow rotated files so shipping does not stop after a logrotate cycle.
- Node coverage: Run the agent on every node that writes logs, including each Gitaly and Praefect host in a multi-node layout.
Check that every node in your deployment has a forwarder, and confirm the file list against your installed version before your detection rules depend on it.
Plain text logs need parsing rules that break when formats change. GitLab can emit structured JSON for several of its log files, which lets the SIEM index fields such as user, project, status and remote address directly. Confirm the exact setting name in the current gitlab.rb reference for your version, because which logs switch to JSON and how the option is named can vary.
- Enable in gitlab.rb: Set the JSON logging option in
/etc/gitlab/gitlab.rb, then rungitlab-ctl reconfigureon each node to apply it. - Mixed formats during rollout: Some components may remain in text, so keep parsers for both formats until every forwarded file is confirmed as JSON.
- Field mapping: Map timestamp, severity, user and source address fields to your SIEM schema before alerts depend on them.
- Sample events: Generate a successful sign-in, a failed sign-in and a project permission change, then confirm each event arrives with the expected fields.
- Consistency check: Confirm the reconfigure finished on every node, because a partial change leaves inconsistent formats across the cluster.
Compare the field names in a sample event against your detection rules before you turn on alerting.
The Helm chart runs GitLab components as containers, and those components write logs to standard output rather than to files on a host. Logs are read through the Kubernetes runtime, so the cluster must collect container output before anything reaches a SIEM. GitLab documents the Helm chart separately from the Linux package, so review the GitLab installation methods page and the chart documentation for your version before you design the pipeline.
- Per-pod output: Webservice, Sidekiq, Gitaly and Toolbox pods each emit their own stream, so the logs of one pod never give a complete picture.
- Short retention: Container logs are removed when pods are replaced during upgrades, so
kubectl logsis not an archive. - Namespace and labels: Confirm which namespace and pod labels the collector should select for GitLab workloads.
- Stateful services: Under GitLab's reference architectures, PostgreSQL and Redis are not run inside Kubernetes, so their logs come from VMs or managed services and need their own sources.
- Control plane audit: Kubernetes audit logs are a separate source from GitLab application logs and need their own collection.
Confirm that the collector captures the GitLab namespace and that logs from pods replaced during an upgrade still reach the SIEM.
A node-level agent, such as a log collector running as a daemon set (for example Fluent Bit or Filebeat), reads container output on each node and forwards it to Elasticsearch, OpenSearch or Splunk. The platform team usually owns this agent because it serves the whole cluster, so the security team should agree on fields, retention and access before the pipeline goes live. Confirm which agent your cluster platform already supports before you design parsers.
- Daemon set deployment: Run the agent on every node so the output of pods scheduled after the agent starts is also captured.
- Metadata enrichment: Attach namespace, pod and container names so events can be filtered by GitLab component.
- Multiline handling: Stack traces and multi-line messages need rules so one event does not split into many fragments.
- Buffering: Agree on buffer size and behavior during a SIEM outage so events are not dropped without a trace.
- Credentials: Store SIEM credentials as Kubernetes secrets with the narrowest scope the agent supports.
Test the path end to end by triggering a known event and confirming it appears in the SIEM with the expected pod metadata.
Choosing a SIEM target: Elasticsearch, OpenSearch or Splunk
This table compares the three common targets for GitLab JSON logs on licensing, operational ownership, index and retention planning, and fit with an existing SIEM. Read each row against your own contracts and staffing, because the licensing and pricing of Elasticsearch and Splunk must be confirmed directly with each vendor before you decide.
| Decision factor | OpenSearch | Elasticsearch | Splunk |
|---|---|---|---|
| Licensing | Apache License 2.0 for all project software; the OpenSearch FAQ does not describe a paid edition | Confirm current license terms and which features sit under each subscription with Elastic | Commercial license; confirm terms, features and entitlements with Splunk |
| Cost drivers | Infrastructure, storage, staff time and any support contract you choose to buy from a third party | Confirm pricing model with Elastic, including any subscription tiers needed for security features | Confirm pricing model with Splunk, typically tied to data ingest or workload; ask for a written quote |
| Lineage | Fork of open source Elasticsearch 7.10; OpenSearch Dashboards derives from Kibana 7.10.2 | The upstream product that OpenSearch forked from 7.10 | Separate proprietary platform with its own query language and add-on ecosystem |
| Operational ownership | You run the cluster, upgrades and security configuration, or contract that work out | You run the cluster, upgrades and security configuration, or use the vendor's hosted offering | Vendor-supplied software; you still own indexers, forwarders and capacity planning |
| Maintenance and patching | Versions receive bug fixes and security patches during maintenance but no new features | Confirm the vendor's support and patch windows for the version you run | Confirm support lifecycle and patch cadence in the vendor's support policy |
| Index and retention planning | Plan index lifecycle, shard sizing and retention for GitLab audit and production logs before go-live | Same planning need; confirm index lifecycle features available under your license | Plan indexes and retention per data source; confirm storage tiers included in your contract |
| Fit with an existing SIEM | Suits teams that already run OpenSearch or want an open-source analytics base for security analytics | Suits teams with existing Elastic stack skills or Elastic-based SIEM content | Suits organizations with an established Splunk SIEM, content library and analyst workflows |
| Migration and upgrade path | Rolling upgrades are supported from Elasticsearch 6.0 through 7.10 indices; confirm your source version | Confirm the upgrade path from your current version with the vendor | Confirm forwarder and index compatibility with your Splunk version before changing targets |
Steps to forward GitLab logs to a SIEM
This sequence moves GitLab log events from the instance into a SIEM in a form analysts can search, with known sources, parsed fields, encrypted transport and a documented check at each stage. The result is a forwarding path your security team can trust before any alert depends on it.
Confirm install method and GitLab version
Record how GitLab is installed (Linux package, Helm chart, GitLab Operator, Docker or source) and the exact running version. The log file locations, the way logs reach stdout and the configuration keys all depend on the install method, so the collector design follows from this record. Confirm the version against the GitLab upgrade paths and maintenance policy so the forwarding setup is planned for a release that is still supported. Done when the team has a written inventory of hosts or cluster workloads that run GitLab components, with the version of each.
Choose log sources and retention
Select the GitLab log sources that matter for operations and security, such as authentication and audit-related events, Rails application logs, Workhorse and NGINX access logs, and Gitaly and PostgreSQL logs where your team needs them. Agree with the SIEM owner how long each source is kept in the SIEM and how long the local copy stays on the GitLab host. Done when a source list with owners and retention periods is approved, and each retention period is taken from your own policy or the SIEM contract rather than assumed.
Enable structured JSON where supported
For each source, turn on JSON output where the GitLab release supports it and confirm the setting in the configuration file for your install method, such as gitlab.rb on Linux package installs or the chart values on Helm. Restart or roll out the affected components according to the upgrade and maintenance procedure you already use. Done when a sample line from each source parses as valid JSON and includes the timestamp, the component name and a request or correlation identifier where the source provides one. Confirm which fields each release emits before writing parsing rules.
Deploy the collector
Install a file shipper on Linux package hosts, or a cluster log agent that reads container stdout on Kubernetes, and point it at the log sources from the approved list. On Helm deployments, container logs go to stdout, so the agent must collect from the node or pod log path and tag events by workload. The collector runs under a service account with read access only to the log paths. Done when the agent reports healthy on every GitLab host or node and its own service logs show no read errors for the GitLab paths.
Set parsing and TLS to the SIEM
Configure the collector to parse the JSON fields into named attributes, map the timestamp to the event time and add a source tag that identifies the GitLab instance and environment. Send events to Elasticsearch, OpenSearch or Splunk over TLS, validate the certificate chain against your internal CA and keep credentials in your secrets store rather than in plain configuration files. Confirm the ingest endpoint and index or sourcetype names with the SIEM team before going live. Done when a test event reaches the SIEM with the expected fields populated and the transport shows a verified TLS connection.
Verify with test events and dashboards
Generate known test events, such as a failed sign-in from a test account and a project visibility change on a non-production project, and search for them in the SIEM within the collector's normal delivery window. Check that the timestamp, host, component and user fields match the source line and that no sensitive values appear where your data handling policy forbids them. Load the agreed dashboard or saved search and confirm it returns the test events. Done when each test event appears once with correct fields, and the team signs off the source list in writing.
Document and review after each upgrade
Record the final configuration, source list, field mappings and the test evidence in your runbook. Because log formats can change between GitLab releases, repeat the test events after each planned upgrade and after any change to the collector or SIEM. Done when the runbook names an owner, the test procedure is written down, and a post-upgrade check is added to the change ticket template used for GitLab upgrades.
How stdout logs work on the GitLab Helm chart
On the GitLab Helm chart, the component containers write their logs to standard output and standard error, and the container runtime hands those streams to the node. The practical consequence is that the cluster, not GitLab, decides how long those logs survive. Most distributions rotate container logs on the node and delete older files, so a SIEM that only reads from the node will miss anything that rotated out before collection. Before you design the pipeline, confirm with your Kubernetes distribution's documentation how log rotation is configured, how large the retained window is at your log volume, and whether the node-level log directory is readable by the collector.
The collector normally runs as a DaemonSet so that one agent per node reads container log files, with a sidecar as the fallback where node access is not allowed by policy. Either way, the collector needs read access to the node log path and the Kubernetes API permissions to enrich events with pod and namespace metadata. Use the pod labels the chart applies, such as the component label, to route events from Webservice, Sidekiq, Gitaly, Toolbox and the other components into separate indices or streams, and confirm the exact label keys in your chart version before writing filters. Restarts add a second risk: when a pod is replaced, its log file is tied to the old container, and a collector that restarts or falls behind can drop lines. Plan for buffering on disk, track collector offsets, and test a forced pod restart while traffic is flowing.
Some teams also write GitLab's own JSON log files to a persistent volume or send them through an extra shipper, which changes what must be confirmed. Ask your platform team whether the collector can access the node path, whether a persistent log volume is allowed in your cluster design, and how node log retention is set. Then run a controlled test: generate a known request, restart the target pod, and confirm the event reaches the SIEM with its component label intact. The result tells you whether stdout is sufficient for your retention requirement or whether a persistent path is needed.
Security risks in GitLab log pipelines
Logs from self-managed GitLab record who did what, when and from where, which makes them valuable to attackers and investigators alike. The risks below connect at the point where log data leaves GitLab hosts, travels across the network and lands in a SIEM or log store that many teams can query.
Sensitive data in log entries
GitLab request and error logs can capture query parameters, request paths and occasionally values that look like tokens or personal data. Once shipped, those values are copied into every index, backup and dashboard that receives the stream. Review what each log file records, confirm which parameter filtering GitLab applies in your version, and test with a sample request that uses a fake token before you forward anything. Confirm the current guidance in the GitLab hardening documentation for your release.
Access control on the log store
A SIEM or log index often gives analysts broader read access to logs than they have to the GitLab instance itself. Anyone who can query the store may see source code paths, usernames, IP addresses and project names. Map log access to roles, separate production from test indices, and log who searched or exported what. Ask your SIEM vendor how field-level filtering and audit logging are configured before you grant access beyond the security team.
Integrity and tamper evidence
Attackers who compromise a GitLab host often try to delete or alter the local log files that would show their activity. Forwarding logs off the host reduces that risk, but only if the shipper keeps a copy that the host cannot silently rewrite. Decide whether you need write-once storage, hashes or signed batches, and document who may delete indices. Test the chain by generating an event on a sandbox GitLab and confirming it appears in the store with the expected fields.
Transport encryption and authentication
Log shippers send events over the network, and a plaintext syslog or HTTP connection exposes usernames and project names to anyone on that path. Use TLS for every hop, verify the receiver certificate on the GitLab side, and restrict which hosts may connect to the ingest port. Confirm the TLS options supported by the shipper and receiver you select, because these differ between Elasticsearch, OpenSearch and Splunk ingestion paths.
Retention and deletion obligations
Logs that contain personal data are subject to the retention limits your privacy and sector rules set, and the SIEM copy may outlive the GitLab copy by years if no one owns its lifecycle. Define retention separately for GitLab local files, the forwarded stream and backups, and confirm deletion works in each place. Ask your compliance lead which records must be kept and which personal data must be removed on request.
Trust boundary between GitLab and the SIEM
The SIEM sits outside the GitLab trust zone, yet it holds detailed records of that zone. A compromise of the log platform can expose the security telemetry that defenders rely on, and a compromise of GitLab can flood the SIEM with misleading events. Place the log platform in a segment that GitLab administrators cannot change alone, limit the credentials the shipper uses to write-only where the platform allows it, and review both directions of traffic during your design review.
Questions teams ask before forwarding GitLab logs
Does the GitLab Free tier allow log forwarding to a SIEM?
Confirm this with GitLab before you plan, because the sources available here do not settle it. GitLab Free costs 0 US dollars, and the GitLab pricing page lists all three tiers for self-managed installations, but it does not map each log or audit output to a tier in a way that answers this question. Premium adds features such as advanced CI/CD and priority support, and Ultimate adds security and compliance features, so check whether any audit capability you need sits in one of those tiers. Shipping component logs from your own server to your own SIEM is a question about your instance, so test it on a non-production installation before you commit the scope. Ask GitLab in writing which outputs each tier includes for your version.
How much effort does a GitLab SIEM integration take?
Effort depends on how many log sources you forward, how clean their formats are, and what the SIEM must do with them. The main drivers are the number of components in scope (the application, background workers, web server, Git storage, database, cache and runners), whether each source already writes structured JSON or needs parsing, and how much field mapping the SIEM needs so events are searchable by user, project and action. Detection content, dashboards and alert tuning often take more time than the shipping itself. Scope also grows with multi-node and Cloud Native Hybrid layouts, because each node or pod adds a collection path. A written scope should list each source, its destination index or stream, the parsing rules and the alerts to be delivered, so the quote follows from specific work.
Can our in-house team forward GitLab logs without an outside partner?
Often yes, if the team already runs a log pipeline and a SIEM and has someone who knows GitLab's log layout. The work is mostly configuration: a shipper on each GitLab host or cluster, a destination index or stream, parsing and field mapping, access roles and a few dashboards. The harder parts are testing parsers against real traffic, keeping mappings stable across GitLab upgrades, and writing alerts that do not overwhelm analysts. A team with no GitLab administration experience should expect a learning curve on log locations and formats. A partner is useful when the work must be finished within a fixed window, when the same design must cover several platforms, or when internal capacity is committed elsewhere. DeployOpen plans and implements this work under a written scope, and your team keeps ownership of the SIEM afterward.
What does a log forwarding project need from our team?
Plan for four kinds of access and ownership before work starts. First, read access to the GitLab hosts or cluster, including log directories or pod logs, and a change window for editing gitlab.rb and applying configuration, since that file controls what GitLab writes. Second, sample logs from each component, ideally from a staging instance or a representative period, so parsers are tested against real records, including error cases. Third, SIEM administrator access to create indices or streams, roles, ingest rules and dashboards, with a named owner who can approve retention and access. Fourth, a security owner who decides which events must alert and who receives those alerts. Without these in place early, parsing and access questions tend to delay the schedule.
How should we estimate retention and storage costs for GitLab logs?
Estimate from measured volume, not from assumptions. Sample the daily log size for each source on your instance across a period that includes normal and heavy CI load, multiply by the retention period you need and by the number of copies your SIEM keeps, then add headroom for indexing overhead and growth. Costs split into three parts: the SIEM software or subscription, the storage and compute beneath it, and the people who run it. Commercial SIEM licensing often follows ingest volume or stored data, so ask each vendor to price your measured numbers. For a self-hosted OpenSearch cluster, the software is released under the Apache License, Version 2.0, and its FAQ does not describe a paid edition, so the cost is infrastructure and operations. Ask any quote to show its volume assumptions, retention per index, and which costs are one-time and which recur.
What should we check first when GitLab logs stop reaching the SIEM?
Trace the path from source to destination in order, and stop at the first broken link. Confirm the log file or pod log is still being written and growing on the GitLab side. Then check that the shipping agent is running and has a saved read position, since a reset or a permissions change can silently stop collection. Next, look for rejected events in the SIEM, which usually point to parse errors, field type conflicts or a mapping that changed after an upgrade. Check network reachability, TLS trust and clock synchronization, because skewed timestamps can place events outside the time window you search. Finally, check the destination: disk thresholds, index lifecycle rules and ingest limits can stop writes without any error on the GitLab host. Record what you found at each step so a support case can show the state of the pipeline.
Does Wazuh fit as the SIEM for GitLab logs?
Wazuh can fit when you want a self-hosted security analytics platform with agents, decoders, rules and a dashboard. It is distributed under the GNU General Public License version 2 with an exception that permits linking with OpenSSL. Its components are the Wazuh indexer, which stores alerts, the Wazuh server, which analyzes data with decoders and rules, the dashboard and agents on endpoints. Wazuh also collects syslog from agentless devices, so syslog forwarding is one route to test. Confirm before you commit: how it ingests structured JSON files from GitLab, whether you need custom decoders, and how the dashboard presents GitLab events. Its prebuilt compliance views cover frameworks such as PCI DSS, GDPR, HIPAA and NIST 800-53, which help with evidence mapping, but your own log design still determines what evidence exists.
Can we forward GitLab logs from the Helm chart stdout?
Yes, but the collection path differs from a Linux package install. Components deployed with the Helm chart write their logs to container standard output, so you collect them with the cluster's log agent from the node's container runtime. Confirm the exact pod and container names and the output format in the chart documentation for your version. Multiline entries, log rotation and pod restarts need checking, because a short-lived pod can lose its logs if nothing ships them first. Also note that GitLab's reference architecture documentation says PostgreSQL and Redis should not run inside Kubernetes, and the Cloud Native Hybrid layout keeps them on VMs or managed services. Those stateful components need their own file-based collection, so plan two collection paths that feed one set of field names.
How DeployOpen scopes and delivers GitLab log forwarding
DeployOpen starts every log forwarding engagement with a written scope that names the GitLab edition and install method in use, the log sources to be forwarded, the SIEM target and its version, and the people who will own alert content after handover. The scope also records what is out of bounds, such as changes to the GitLab application itself or to the SIEM's own sizing. Because the Linux package, Helm chart, GitLab Operator and Docker installs each place logs differently, the scope has to be fixed to one install method before any configuration work begins. Fixed-scope delivery means the deliverables and acceptance tests are agreed in writing before work starts, so the client can compare the proposal with an internal build on equal terms. Any quote follows from that written scope.
The inventory phase maps each log source to a collection path and a retention owner. For a Linux package install, this means the gitlab-rails, nginx, sidekiq, gitaly and gitlab-workhorse logs, along with any audit or security logs the instance writes. For a Helm deployment, it means confirming which logs reach stdout and which the cluster's log agent collects. The team also confirms the SIEM target's ingest path, including whether the destination is Elasticsearch, OpenSearch or Splunk, the TLS and authentication method, and the index or sourcetype naming. Clients should expect to supply a sample of real log lines, a volume estimate from their current instance, and a list of the detection use cases the security team needs.
Implementation is done in the client's own infrastructure, in a non-production environment first. The engagement includes shipper configuration, parsing and field mapping, and test cases that prove events arrive with the expected fields and timestamps. Acceptance testing covers sample searches, a forced failure of the shipper and the destination, and a check that the GitLab upgrade procedure does not silently break parsing. DeployOpen then writes runbooks for adding a new log source, rotating credentials, changing retention and recovering from a dropped shipper, and hands them over with the configuration in version control. DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports or certifications, which remain the job of independent auditors. Ongoing support, upgrades and continuous testing are available as a retainer, and clients should confirm the retainer's coverage in writing before the handover.

