{"id":48807780,"url":"https://github.com/axonops/audit","last_synced_at":"2026-04-17T06:06:34.794Z","repository":{"id":345065953,"uuid":"1184293767","full_name":"axonops/audit","owner":"axonops","description":"Structured, compile time schema-enforced audit logging for Go services. Taxonomy-driven validation, type-safe code generation, multi-output fan-out (file, syslog, webhook and more), CEF + JSON formatters, HMAC integrity checks, per-output event routing, sensitivity labels, and async delivery.","archived":false,"fork":false,"pushed_at":"2026-04-14T05:37:27.000Z","size":76250,"stargazers_count":0,"open_issues_count":31,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T06:33:21.157Z","etag":null,"topics":["audit","audit-logging","cef","code-generation","compliance","go","golang","hmac","security","siem","syslog","type-safety","webhook"],"latest_commit_sha":null,"homepage":"https://axonops.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/axonops.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":"audit.go","citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-17T12:57:21.000Z","updated_at":"2026-04-14T05:37:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/axonops/audit","commit_stats":null,"previous_names":["axonops/go-audit","axonops/audit"],"tags_count":120,"template":false,"template_full_name":null,"purl":"pkg:github/axonops/audit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axonops%2Faudit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axonops%2Faudit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axonops%2Faudit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axonops%2Faudit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axonops","download_url":"https://codeload.github.com/axonops/audit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axonops%2Faudit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31917372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audit","audit-logging","cef","code-generation","compliance","go","golang","hmac","security","siem","syslog","type-safety","webhook"],"created_at":"2026-04-14T06:05:33.416Z","updated_at":"2026-04-17T06:06:34.786Z","avatar_url":"https://github.com/axonops.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\".github/images/logo-readme.png\" alt=\"audit\" width=\"128\"\u003e\n\n  # audit\n\n  **Structured, Schema-Enforced Audit Logging for Go Services**\n\n  [![CI](https://github.com/axonops/audit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/axonops/audit/actions/workflows/ci.yml)\n  [![Go Reference](https://pkg.go.dev/badge/github.com/axonops/audit.svg)](https://pkg.go.dev/github.com/axonops/audit)\n  [![Go Report Card](https://goreportcard.com/badge/github.com/axonops/audit)](https://goreportcard.com/report/github.com/axonops/audit)\n  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n  ![Status](https://img.shields.io/badge/status-pre--release-orange)\n\n  [🚀 Quick Start](#-quick-start) | [✨ Features](#-key-features) | [📚 Examples](examples/) | [📖 API Reference](https://pkg.go.dev/github.com/axonops/audit)\n\u003c/div\u003e\n\n---\n## ⚠️ Status\n\nThis library is **pre-release (v0.x)**. The API may change between\nminor versions until v1.0.0. Pin your dependency version.\n\n---\n\n## 🔍 Overview\n\naudit is an audit logging library for Go. Audit logging is different\nfrom application logging — application logs record technical details\nfor debugging (`log/slog`, `zap`), while audit logs record **who did\nwhat, when, and to which resource** for compliance, forensics, and\naccountability. If your application handles user data, authentication,\nor financial transactions, regulations like SOX, HIPAA, and GDPR\nrequire structured audit trails that application loggers don't enforce.\n\nThe library splits audit configuration into two layers:\n\n- **Compile-time (taxonomy):** Your event schema — which event types\n  exist, which fields are required, what's optional — is defined in a\n  YAML file and embedded into your binary with `go:embed`. A code\n  generator (`audit-gen`) produces typed Go builders from this schema,\n  so invalid event names and missing required fields are caught by the\n  compiler, not at runtime. The taxonomy is your audit contract — it\n  ships with the binary and cannot be changed without recompiling.\n\n- **Runtime (outputs):** Where events go — files, syslog, webhooks —\n  is configured in a separate YAML file loaded at startup. Output\n  destinations, routing filters, formatters, and sensitivity label\n  exclusions can all change per environment without rebuilding.\n\nThe library validates events against the compiled taxonomy, delivers\nthem asynchronously to multiple outputs simultaneously, and supports\nboth [JSON](docs/json-format.md) and\n[CEF (Common Event Format)](docs/cef-format.md) for SIEM integration.\n\n---\n\n## ✨ Key Features\n\n\u003cdiv align=\"center\"\u003e\n\n| Feature | Description | Docs |\n|---------|-------------|------|\n| 📋 **Taxonomy Validation** | Define event schemas in YAML; every event validated at runtime | [Learn more](docs/taxonomy-validation.md) |\n| ⚙️ **Code Generation** | `audit-gen` generates typed builders; typos become compile errors | [Learn more](docs/code-generation.md) |\n| 🛡️ **CEF Format** | Common Event Format for SIEM platforms (Splunk, ArcSight, QRadar) | [Learn more](docs/cef-format.md) |\n| 📄 **JSON Format** | Line-delimited JSON with deterministic field order | [Learn more](docs/json-format.md) |\n| 📡 **5 Output Types** | File (rotation), syslog (RFC 5424), webhook (NDJSON), Loki (stream labels), stdout — fan-out to all simultaneously | [Learn more](docs/outputs.md) |\n| 🔀 **Event Routing** | Route events by category or severity to specific outputs | [Learn more](docs/event-routing.md) |\n| 🔒 **Sensitivity Labels** | Classify fields as PII/financial; strip per-output for compliance | [Learn more](docs/sensitivity-labels.md) |\n| ⚡ **Async Delivery** | Sub-microsecond enqueue; background drain goroutine | [Learn more](docs/async-delivery.md) |\n| 🌐 **HTTP Middleware** | Automatically captures HTTP request fields for audit logging | [Learn more](docs/http-middleware.md) |\n| 📊 **Metrics \u0026 Monitoring** | Track dropped events, delivery errors, and output health | [Learn more](docs/metrics-monitoring.md) |\n| 📝 **YAML Configuration** | Configure outputs in YAML with environment variable substitution | [Learn more](docs/output-configuration.md) |\n| 🔐 **HMAC Integrity** | Per-output tamper detection with NIST-approved algorithms | [Learn more](docs/hmac-integrity.md) |\n| 🧪 **Testing Support** | In-memory recorder with same validation as production | [Learn more](docs/testing.md) |\n\n\u003c/div\u003e\n\n---\n\n## ❓ Why Audit Logging?\n\nAudit logging is not application logging. They serve fundamentally\ndifferent purposes:\n\n| | 🔧 Application Logging | 📋 Audit Logging |\n|---|---|---|\n| **Purpose** | Debugging, troubleshooting, observability | Compliance, forensics, accountability |\n| **Audience** | Developers, SREs | Security teams, auditors, legal |\n| **Guarantees** | Best-effort — missing a log line is fine | Schema-enforced — missing a field is a compliance gap |\n| **Retention** | Days to weeks | Months to years (regulatory requirements) |\n| **Content** | Technical details (errors, stack traces) | Who did what, when, to which resource, and why |\n| **Destinations** | Log aggregator (OpenSearch, Datadog, Loki) | SIEM (Splunk, ArcSight, QRadar), compliance archives |\n\nIf your application handles user data, financial transactions,\nauthentication, or access control, regulations like SOX, HIPAA, GDPR,\nand PCI-DSS require audit trails. Application loggers (`log/slog`,\n`zap`, `zerolog`) do not enforce the structure, completeness, or\ndelivery guarantees that compliance demands.\n\n---\n\n## 💡 Why audit?\n\nNo existing Go library provides schema-enforced audit logging with\nmulti-output fan-out and SIEM-native format support:\n\n- 📋 **Schema enforcement** — every event validated against your taxonomy; missing required fields are rejected, not silently dropped\n- 🛡️ **SIEM-native output** — [CEF format](docs/cef-format.md) understood by Splunk, ArcSight, QRadar out of the box, alongside [JSON](docs/json-format.md) for log aggregators\n- 📡 **Multi-output fan-out** — send events to [files, syslog, webhooks, Loki, and stdout](docs/outputs.md) simultaneously, each with its own formatter and filters\n- 🔒 **Sensitive field stripping** — [classify fields as PII or financial](docs/sensitivity-labels.md); strip them per-output for GDPR/PCI compliance\n- ⚡ **Non-blocking** — sub-microsecond `AuditEvent()` calls; [async delivery](docs/async-delivery.md) via a background drain goroutine with completeness monitoring\n- 🔌 **No vendor lock-in** — [pluggable metrics interface](docs/metrics-monitoring.md); no Prometheus, OpenTelemetry, or logging framework dependency in core\n\n---\n\n## 🚀 Quick Start\n\nThe library uses a YAML-first workflow: define your events in a taxonomy\nfile, configure outputs in another, and generate type-safe Go code.\n\n### 1️⃣ Define your taxonomy (`taxonomy.yaml`) - This is your source code. \n\n```yaml\nversion: 1\n\ncategories:\n  write:\n    severity: 3\n    events:\n      - user_create\n  security:\n    severity: 8\n    events:\n      - auth_failure\n\nevents:\n  user_create:\n    description: \"A new user account was created\"\n    fields:\n      outcome:  { required: true }\n      actor_id: { required: true }\n\n  auth_failure:\n    description: \"An authentication attempt failed\"\n    fields:\n      outcome:  { required: true }\n      actor_id: { required: true }\n```\n\n\u003e 💡 Fields like `target_id`, `source_ip`, and `reason` are **reserved standard\n\u003e fields** — always available on every event without declaration. Use\n\u003e `.SetTargetID()`, `.SetSourceIP()`, etc. on any builder.\n\n### 2️⃣ Configure outputs (`outputs.yaml`) - This is your config. \n\n```yaml\nversion: 1\napp_name: my-service\nhost: \"${HOSTNAME:-localhost}\"\n\noutputs:\n  console:\n    type: stdout\n\n  siem_log:\n    type: file\n    file:\n      path: \"./audit-cef.log\"\n    formatter:\n      type: cef\n      vendor: \"MyCompany\"\n      product: \"MyApp\"\n      version: \"1.0\"\n```\n\n### 3️⃣ Generate type-safe code \n\n```bash\ngo run github.com/axonops/audit/cmd/audit-gen \\\n  -input taxonomy.yaml \\\n  -output audit_generated.go \\\n  -package main\n```\n\n\u003e 💡 `go run` fetches the tool automatically — no separate install needed.\n\n### 4️⃣ Use the generated builders\n\n```go\n// Required fields are constructor parameters — typos are compile errors\nerr := auditor.AuditEvent(\n    NewUserCreateEvent(\"alice\", \"success\").\n        SetTargetID(\"user-42\"),\n)\n```\n\n\u003e 📚 For the complete runnable application (taxonomy loading, output\n\u003e configuration, auditor creation), see\n\u003e [examples/02-code-generation](examples/02-code-generation/).\n\n### Output\n\n**📄 JSON** (default formatter):\n```json\n{\"timestamp\":\"...\",\"event_type\":\"user_create\",\"severity\":3,\"app_name\":\"my-service\",\"host\":\"prod-01\",\"timezone\":\"UTC\",\"pid\":12345,\"actor_id\":\"alice\",\"outcome\":\"success\",\"target_id\":\"user-42\",\"event_category\":\"write\"}\n```\n\n**🛡️ CEF** (SIEM formatter):\n```\nCEF:0|MyCompany|MyApp|1.0|user_create|A new user account was created|3|rt=... act=user_create deviceProcessName=my-service dvchost=prod-01 dvcpid=12345 suser=alice outcome=success cat=write\n```\n\n\u003e `app_name`, `host`, and `pid` are **framework fields** — set once in your\n\u003e outputs.yaml and automatically included in every event. The `host`,\n\u003e `timezone`, and `pid` values reflect your system — they will differ\n\u003e from the example above. `app_name` is set in `outputs.yaml` and stays\n\u003e constant across deployments. SIEMs use the CEF extension keys\n\u003e (`deviceProcessName`, `dvchost`, `dvcpid`) for automatic host-level\n\u003e correlation.\n\n---\n\n## 📦 Installation\n\nRequires **Go 1.26+**.\n\n```bash\ngo get github.com/axonops/audit             # core: auditor, taxonomy, validation, formatters, stdout output\ngo get github.com/axonops/audit/file         # file output with rotation\ngo get github.com/axonops/audit/syslog       # RFC 5424 syslog (TCP/UDP/TLS/mTLS)\ngo get github.com/axonops/audit/webhook      # batched HTTP webhook with SSRF protection\ngo get github.com/axonops/audit/loki         # Grafana Loki with stream labels and gzip\ngo get github.com/axonops/audit/outputconfig # YAML-based output configuration\n```\n\n\u003e 💡 The core module includes `StdoutOutput` (no additional dependency)\n\u003e and the `audittest` package for [testing](docs/testing.md).\n\n---\n\n## 🏗️ Module Structure\n\n| Module | Description |\n|--------|-------------|\n| `github.com/axonops/audit` | Core: Auditor, taxonomy validation, JSON + CEF formatters, HTTP middleware, stdout output, fan-out, routing, `audittest` |\n| `github.com/axonops/audit/file` | File output with size-based rotation and gzip compression |\n| `github.com/axonops/audit/syslog` | RFC 5424 syslog output (TCP/UDP/TLS/mTLS) |\n| `github.com/axonops/audit/webhook` | Batched HTTP webhook with retry and SSRF protection |\n| `github.com/axonops/audit/loki` | Grafana Loki output with stream labels, gzip, multi-tenancy |\n| `github.com/axonops/audit/outputconfig` | YAML-based output configuration with env var substitution |\n| `github.com/axonops/audit/outputs` | Convenience: single blank import registers all output factories |\n| `github.com/axonops/audit/secrets` | Secret provider interface for `ref+` URI resolution in YAML config |\n| `github.com/axonops/audit/secrets/openbao` | OpenBao KV v2 secret provider |\n| `github.com/axonops/audit/secrets/vault` | HashiCorp Vault KV v2 secret provider |\n| `github.com/axonops/audit/cmd/audit-gen` | Code generator: YAML taxonomy to typed Go builders |\n\nOutputs are isolated in separate modules so the core library carries\nminimal third-party dependencies. Import only the outputs you use —\nor `import _ \"github.com/axonops/audit/outputs\"` to register all of them.\n\n---\n\n## 🧪 Testing\n\nThe `audittest` package provides an in-memory recorder for testing audit events:\n\n```go\nfunc TestUserCreation(t *testing.T) {\n    auditor, events, _ := audittest.NewQuick(t, \"user_create\")\n\n    // Exercise the code under test...\n    err := auditor.AuditEvent(audit.NewEventKV(\"user_create\",\n        \"outcome\", \"success\", \"actor_id\", \"alice\"))\n    require.NoError(t, err)\n\n    // Assert immediately — NewQuick uses synchronous delivery.\n    assert.Equal(t, 1, events.Count())\n    assert.Equal(t, \"alice\", events.Events()[0].StringField(\"actor_id\"))\n}\n```\n\nSee [Example 4](examples/04-testing/) and [Testing docs](docs/testing.md) for more.\n\n---\n\n## 📚 Documentation\n\n| Resource | Description |\n|----------|-------------|\n| 📖 [Progressive Examples](examples/) | 17 examples from \"hello world\" to a [complete inventory demo](examples/17-capstone/) — every output type, TLS policy, routing, formatters, testing, and buffering |\n| 📘 [API Reference](https://pkg.go.dev/github.com/axonops/audit) | pkg.go.dev documentation |\n| 🏗️ [Architecture](ARCHITECTURE.md) | Pipeline design, module boundaries, thread safety |\n| 🤝 [Contributing](CONTRIBUTING.md) | Development setup, PR process, code standards |\n| 📝 [Changelog](CHANGELOG.md) | Release history and breaking changes |\n| ❌ [Error Reference](docs/error-reference.md) | Every error explained with recovery guidance |\n| 🔧 [Troubleshooting](docs/troubleshooting.md) | Common problems and how to fix them |\n| 🔒 [Security Policy](SECURITY.md) | Vulnerability reporting |\n| ⚡ [Benchmarks](BENCHMARKS.md) | Performance baseline and methodology |\n\n---\n\n## 🙏 Acknowledgements\n\naudit builds on excellent open-source projects. See\n[ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md) for full attribution and\nlicense details.\n\n- [github.com/goccy/go-yaml](https://github.com/goccy/go-yaml) — YAML parsing (MIT)\n- [github.com/axonops/srslog](https://github.com/axonops/srslog) — RFC 5424 syslog (BSD-3-Clause)\n- [github.com/rgooding/go-syncmap](https://github.com/rgooding/go-syncmap) — Generic sync.Map (Apache-2.0)\n\n---\n\n## 📄 License\n\n[Apache License 2.0](LICENSE) — Copyright 2026 AxonOps Limited.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003csub\u003eMade with ❤️ by \u003ca href=\"https://axonops.com\"\u003eAxonOps\u003c/a\u003e\u003c/sub\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxonops%2Faudit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxonops%2Faudit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxonops%2Faudit/lists"}