---

augur logo

Getting Started   •   Getting Involved   •   Getting In Touch

Build Status Go Report Card GitHub release (latest by date including pre-releases)

Rules   •   Usage   •   Custom Policies   •   Library   •   Package

--- # augur A fast, opinionated linter for [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) configurations. Catches misconfigurations, security issues, and performance pitfalls before they hit production. Built with [OPA/Rego](https://www.openpolicyagent.org/) — every rule is a plain `.rego` file you can read, override, or extend.

augur demo

## Why The OpenTelemetry Collector is flexible, but that flexibility makes it easy to ship configs that silently drop data, leak secrets, or OOM under load. `augur` encodes hard-won operational knowledge into automated checks: - **No memory limiter?** You'll OOM in production. - **Hardcoded API key?** It'll end up in version control. - **Batch processor in the wrong position?** You're leaving performance on the table. ## Install ### Homebrew ```sh brew install --cask starkross/tap/augur ``` ### Go ```sh go install github.com/starkross/augur/cmd/augur@latest ``` ### Docker ```sh docker run --rm -v "$(pwd):/work" ghcr.io/starkross/augur:latest config.yaml ``` ### Binary releases Download from [GitHub Releases](https://github.com/starkross/augur/releases) — available for Linux, macOS, and Windows (amd64/arm64). ## Quick start ```sh augur otel-collector-config.yaml ``` ``` otel-collector-config.yaml FAIL OTEL-001: memory_limiter processor is not configured. Required to prevent OOM in production. FAIL OTEL-003: batch processor is not configured. Required for efficient data export. WARN OTEL-011: health_check extension is not configured. Recommended for k8s liveness/readiness probes. ✗ 2 failure(s), 1 warning(s) ``` Exit code `1` on any failure. Warnings are informational by default. ## Rules See [docs/RULES.md](docs/RULES.md) for the full list of built-in rules. ## Usage ``` augur [flags] [config.yaml | -]... ``` | Flag | Description | Default | |------|-------------|---------| | `-o, --output` | Output format: `text`, `json`, `github` | `text` | | `-s, --strict` | Treat warnings as errors | `false` | | `-q, --quiet` | Suppress warnings, show only failures | `false` | | `-k, --skip` | Comma-separated rule IDs to skip | | | `--no-color` | Disable colored output | `false` | | `-p, --policy` | Additional policy directory (merged with built-in rules) | | ### Multiple config files When you pass more than one file, augur deep-merges them into a single effective config before linting — the same way the OpenTelemetry Collector combines multiple `--config` flags. Use `-` in place of a filename to read from stdin (may only appear once): ```sh augur common.yaml client.yaml ``` Merge rules (matching the collector's confmap): | Value type | Behavior | |------------|----------| | Map | Deep-merged recursively. Later files add keys and override scalar leaves. | | Scalar | Later file wins. | | Slice | Replaced wholesale by the later file. | To lint several standalone configs independently, invoke augur once per file. ### Examples ```sh # Merge two files augur gateway.yaml overrides.yaml # Strict mode — warnings become errors augur --strict config.yaml # JSON output for programmatic consumption augur -o json config.yaml # Skip specific rules augur --skip OTEL-015,OTEL-016 config.yaml # Use custom policies augur --policy ./my-policies config.yaml # Read from stdin cat config.yaml | augur - # Mix stdin with file arguments augur base.yaml - overrides.yaml < patch.yaml ``` ## Custom policies All built-in rules live in `rules/policy/` as standard Rego files. To add your own: 1. Create a directory with your custom rules: ```rego # my-policies/main/custom.rego package main import future.keywords.contains import future.keywords.if deny contains msg if { not input.processors.filter msg := "CUSTOM-001: filter processor is required by our platform team." } ``` 2. Run with `--policy`: ```sh augur --policy ./my-policies config.yaml ``` Custom policies are **merged** with the built-in rules — your rules run alongside all default checks. ## Library usage `augur` can also be embedded directly in a Go program. Import the top-level package and construct a `Linter`: ```sh go get github.com/starkross/augur ``` ```go package main import ( "context" "fmt" "log" "github.com/starkross/augur" ) func main() { linter, err := augur.New() if err != nil { log.Fatal(err) } result, err := linter.LintFile(context.Background(), "otel-collector.yaml") if err != nil { log.Fatal(err) } for _, f := range result.Findings { fmt.Printf("%s [%s] %s\n", f.RuleID, f.Severity, f.Message) } } ``` Available entry points: | Method | Input | |--------|-------| | `Lint(ctx, label, map[string]any)` | Pre-parsed config map | | `LintYAML(ctx, label, []byte)` | Raw YAML bytes | | `LintFile(ctx, path)` | Single YAML file | | `LintFiles(ctx, paths)` | Multiple files (deep-merged, same semantics as the CLI) | Options passed to `augur.New`: | Option | Purpose | |--------|---------| | `WithPolicyDir(path)` | Add a filesystem directory of extra `.rego` policies | | `WithPolicyFS(fsys, root)` | Add a custom `io/fs.FS` policy source (works with `//go:embed`) | | `WithoutBuiltinRules()` | Exclude the bundled OTEL-* rule set | | `WithSkipRules(ids...)` | Drop findings for the given rule IDs | | `WithSeverities(sev...)` | Filter findings by severity (e.g., pass `SeverityDeny` for fail-only) | A `Linter` compiles its policies once and is safe for concurrent use — construct a single instance and share it across goroutines. See [examples/library](examples/library) for a runnable example. ## Security Every release is reproducibly built and signed: - **CycloneDX SBOMs** for every archive and every container image - **Cosign keyless signatures** (sigstore OIDC) on `checksums.txt` and on the published OCI image - **SLSA Level 3 build provenance** for binary artifacts Quick verification of a release: ```sh cosign verify ghcr.io/starkross/augur:vX.Y.Z \ --certificate-identity-regexp 'https://github.com/starkross/augur/\.github/workflows/release\.yml@refs/tags/v.*' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' ``` See [SECURITY.md](SECURITY.md) for the full verification recipe (binaries, images, SLSA provenance, SBOMs) and the vulnerability disclosure process.