go-audit: JSON Linux audit events with pluggable outputs
go-audit is an alternative to the auditd daemon that ships with many distros
At a glance
- What is it?
- go-audit replaces the distribution-provided auditd daemon on Linux by receiving kernel audit records through netlink and sending JSON to files, syslog, Graylog2, or stdout. It suits operators that need direct control over event formatting and output destinations, but its documentation leaves deployment and upgrade details incomplete.
- Who is it for?
- Operators who already require auditd-compatible kernel coverage but specifically need JSON records or custom output routing should consider go-audit. Operators who need a complete, distribution-integrated service with fully documented configuration should first inspect `go-audit.yaml.example`, the `contrib` service definitions, and the gap between the README's Go 1.14 instruction and `go.mod`, which currently declares `go 1.26.3`.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why go-audit replaces the distribution auditd daemon
go-audit addresses Linux hosts that produce audit records but need more control than a conventional daemon workflow provides. The README calls it an alternative to the `auditd` daemon shipped with many distributions and identifies its intended output as JSON. That is the central distinction. Teams can send records to a local file, syslog, Graylog2, or stdout, while additional destinations can be added through its pluggable pipeline. This makes the project most relevant to system operators, security engineers, and Go developers who connect audit events to log processing systems.
It is not presented as a general-purpose log collector. Its input comes from the Linux audit subsystem, and the stated connection mechanism is netlink. That distinction matters when selecting it against `auditd`: go-audit changes daemon implementation and output routing around kernel audit records, rather than offering a library for parsing arbitrary application logs. The README does not document supported Linux distributions, kernel compatibility ranges, privilege requirements, or a claim of complete parity with every `auditd` feature. Those omissions make a direct feature comparison impossible from the documentation.
The project is not archived, and the last push was on 2026-10-14. The recent release history includes `v1.2.2` on 2026-06-22, following `v1.2.1` on 2025-12-10 and the longer gap back to `v1.2.0` on 2023-04-07. The repository is under the MIT License. That permits use and modification under the license's terms, but organizations still need to review the actual `LICENSE` file and any policy requirements themselves.
Netlink collection, JSON parsing, and writer routing
The documented path begins at the Linux kernel audit interface. go-audit connects through netlink, receives audit messages, and converts the records into JSON before handing them to an output pipeline. The README names syslog, local files, Graylog2, and stdout as supported destinations. A local file or stdout can be useful during initial configuration because the event stream remains directly accessible, while Graylog2 provides a named structured-log destination.
The repository layout separates this work across files named for the main responsibilities: `client.go`, `parser.go`, `marshaller.go`, and `writer.go`. It also contains `audit.go`, plus extra processing files for cgroups and containers. The repository includes container dependencies in `go.mod`, and files such as `extras_containers.go` and `extras_containers_capsule8.go` indicate container-related handling in the codebase. The README itself does not describe the exact event schema or container enrichment behavior, so neither should be inferred from file names alone.
A genuine design constraint appears in the buffer troubleshooting guidance. If collection cannot keep pace with event generation, logs may contain `Error during message receive: no buffer space available`. The README recommends first reducing the amount of audit data handled or increasing the system-wide receive buffer. It then identifies `socket_buffer.receive` in the configuration as a possible adjustment. This is an explicit admission that event velocity can exceed processing or buffering capacity. Increasing one setting may postpone loss or failure, but it does not remove the underlying throughput requirement.
Building go-audit and checking the source tree
The README's installation procedure requires Go and a source checkout. It states that Go 1.14 or greater is required, then directs the reader to clone the repository, enter its directory, and build with `make`. No concrete clone URL appears in the documentation, so the repository source must be obtained from its published repository page rather than inventing a command here.
After entering the checkout, the default Makefile target runs a Go build. The binary produced by the documented build target is named `go-audit`.
makeThe README says to copy the resulting `go-audit` binary to the desired location. It does not give a copy command or specify a default configuration path, so neither is invented here. Configuration is referenced through `go-audit.yaml.example`, while service examples are located in `contrib`. Those two locations should be read together because the README provides no single deployment command that both installs the binary and loads a particular configuration.
The Go version instructions need attention. The README says version 1.14 or greater, but `go.mod` currently declares `go 1.26.3`. The module file is the more specific statement about the current source tree. An operator using an older toolchain should verify whether it can parse and build this module rather than relying only on the README's minimum-version statement.
A first real use through tests, configuration, and services
The repository provides a direct test command before deployment. This exercises the source tree without requiring the reader to invent a test binary or test flag.
make testThe README identifies this as the unit test suite. It also documents `make test-cov-html`, `make bench`, and `make bench-cpu`, although those targets add coverage output or profiling and are not necessary for a first build.
For configuration-based use, the documented starting point is `go-audit.yaml.example`. The README specifically names one key from this file:
socket_buffer:
receive: <some number bigger than (the current value * 2)>This snippet is guidance for the documented buffer failure, not a recommended initial value. A real operator should replace the placeholder with a numeric configuration value based on the current setting and the amount of data being generated. The README does not provide a complete minimal configuration, expected log format, or a command that loads `go-audit.yaml.example`.
For service installation, the README says to check the `contrib` folder for examples. It does not document whether those examples target systemd, another init system, or a specific distribution. The source layout does confirm that deployment examples exist. A cautious first use therefore consists of building with `make`, running `make test`, examining `go-audit.yaml.example`, and selecting a service definition from `contrib` for the host's actual service manager. The README does not document a rollback procedure.
Kernel filename gaps and duplicate syslog events
go-audit preserves an important limitation of kernel audit data. Some file access records contain only an `inode` and no `name`, because the kernel does not always know the filename. The README says that recovering a name from an inode is expensive and error prone. It presents `debugfs` as a possible mapping method, while warning that the resulting path may not be the path that triggered the audit record. Consumers therefore need to handle records without filenames rather than expecting every event to contain a resolved path.
The documentation also describes duplicate syslog entries. Its stated cause is that `journald` may be reading the same audit events. The documented mitigation is to mask the journald audit socket:
sudo systemctl mask systemd-journald-audit.socketThat command addresses a specific systemd environment and should not be treated as a general cleanup step. It prevents `journald` from reading audit events through that socket, but it also changes an existing local logging arrangement. The README does not state what recovery or rollback command should follow, so the previous service state should be recorded before applying the change.
These issues illustrate the operational boundary between collecting audit events and interpreting them. A JSON output does not fill in missing kernel context. Likewise, multiple consumers can create apparent duplicates even though neither is necessarily producing invalid records.
Choosing go-audit instead of auditd or a custom collector
The real alternative named by the project is the `auditd` daemon shipped with many Linux distributions. The documented difference is architectural: go-audit is a Go implementation that connects to kernel audit data through netlink and emits JSON through a pluggable pipeline. `auditd` is the distribution-provided daemon against which this approach is positioned. The README does not provide a feature matrix, event compatibility table, or statement that one produces a strict superset of the other's records.
A custom collector would be a different category rather than a named competitor. Such a collector could subscribe to the kernel audit interface and send records directly into an existing pipeline, but that would require implementing behavior that go-audit already places in its client, parser, marshaller, and writer structure. go-audit reduces that implementation work when its documented destinations and event handling meet the requirement. It is the wrong choice when exact `auditd` deployment compatibility or undocumented distro integration is the deciding criterion.
The pluggable pipeline is useful, but it is not the same as a documented plugin API. The README says additional outputs are easily written, yet it does not identify an interface, versioning promise, or third-party plugin catalog. Treat that as an architectural aspiration rather than a supported extension contract. The `examples/` directory includes destinations such as Elasticsearch, Elastalert, Kibana, rsyslog, and Streamstash, but their presence alone does not establish that every example is current with `v1.2.2`.
Editorial conclusion
Operators who already require auditd-compatible kernel coverage but specifically need JSON records or custom output routing should consider go-audit. Operators who need a complete, distribution-integrated service with fully documented configuration should first inspect `go-audit.yaml.example`, the `contrib` service definitions, and the gap between the README's Go 1.14 instruction and `go.mod`, which currently declares `go 1.26.3`. Adopt it only after confirming that the documented service setup and current toolchain build reproduce the required audit pipeline.
Frequently asked questions
How do I install and build go-audit?
The README requires Go 1.14 or greater, a checkout of the repository, and `make`. The current `go.mod` instead declares `go 1.26.3`, so the module requirement should be checked before choosing a toolchain version.
What should I do when go-audit reports `no buffer space available`?
The README says this can mean go-audit is not receiving data as quickly as the system generates it. It recommends reducing audit data first, increasing the system-wide receive buffer, or trying a larger `socket_buffer.receive` value.
Why are some go-audit file events missing a `name`?
The README states that the kernel does not always know the filename for a file access. It suggests a possible `debugfs` inode lookup but warns that resolving an inode is expensive, error prone, and may not produce the exact filename that triggered the record.
Why does go-audit produce duplicate syslog entries?
The README identifies `journald` as a likely second reader of the same audit events. Its documented mitigation is `sudo systemctl mask systemd-journald-audit.socket`, which changes the host's existing audit socket configuration.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/slackhq-go-audit)Was this useful?