Help us shape the future of Go! Take the 2026 Go Developer Survey

groundtruth

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2026 License: Apache-2.0

README

groundtruth

Self-hosted, open-source drift detection for Terraform and OpenTofu.

driftctl, previously the leading open-source tool for this, has been in maintenance mode since 2023. The alternatives that exist today are either paid SaaS platforms or early/unmaintained projects. groundtruth is a free, self-hosted replacement focused on one thing: periodically running terraform plan -refresh-only against your existing workspaces, showing you exactly what changed outside of Terraform, and alerting you when it does.

  • Read-only. groundtruth detects and reports drift; it never runs apply and cannot modify your infrastructure.
  • No cloud credentials stored. Credentials are supplied by the operator at runtime (an env file you mount yourself) and are never written to groundtruth's database.
  • No shell, no hand-rolled parsing. Terraform/OpenTofu are invoked via their official Go libraries (terraform-exec/tofu-exec), and plan output is parsed with HashiCorp's own terraform-json.
  • Single binary, single process. An embedded SQLite database and an embedded frontend — nothing else to run to self-host this.

See docs/ARCHITECTURE.md for the full security model and the reasoning behind these decisions.

Quickstart

mkdir groundtruth && cd groundtruth
curl -O https://raw.githubusercontent.com/carlosalbertorg/groundtruth/main/deploy/docker-compose.yml
mkdir modules
# Put a Terraform or OpenTofu root module in ./modules - its own backend
# block controls where its real state lives (S3, GCS, Terraform Cloud,
# a local backend, ...). groundtruth only reads it.
docker compose up -d

Then open http://localhost:8080, create the first admin account, and add a workspace pointing at /modules/<your-module> (the path inside the container — see the volume mount in docker-compose.yml).

If your module's provider needs credentials that aren't already available to it (an attached IAM role, ambient environment variables, etc.), mount a dotenv-format file and point the workspace's "credential env file" at its in-container path. It's read fresh on every check and never stored — see docs/ARCHITECTURE.md.

Configuration

Environment variables, all optional:

Variable Default Meaning
GROUNDTRUTH_ADDR :8080 HTTP listen address
GROUNDTRUTH_DATA_DIR ./data Where the SQLite database, plugin cache, and check scratch space live
GROUNDTRUTH_BASE_URL unset groundtruth's externally-visible URL. Set this (with https://) once behind TLS, so the session cookie is marked Secure, and so alert payloads can include a dashboard link
GROUNDTRUTH_MAX_CONCURRENT_CHECKS 3 How many drift checks the scheduler runs at once, across all workspaces

Building from source

make build-frontend   # builds web/ and embeds it into internal/webassets
go build ./cmd/groundtruth

See CONTRIBUTING.md for the full development setup, including running the test suite.

Contributing

Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request — in particular, open an issue first for anything beyond a small fix. This project follows the Code of Conduct. Security issues should be reported privately per SECURITY.md, not as a public issue.

License

Apache-2.0

Directories

Path Synopsis
cmd
groundtruth command
Command groundtruth runs the groundtruth server: a self-hosted drift detector for Terraform and OpenTofu.
Command groundtruth runs the groundtruth server: a self-hosted drift detector for Terraform and OpenTofu.
internal
alerting
Package alerting notifies configured destinations (a generic webhook or Slack) when a workspace's drift status changes, and logs every delivery attempt.
Package alerting notifies configured destinations (a generic webhook or Slack) when a workspace's drift status changes, and logs every delivery attempt.
auth
Package auth implements groundtruth's dashboard authentication: password hashing, opaque database-backed sessions, and the HTTP middleware that enforces them.
Package auth implements groundtruth's dashboard authentication: password hashing, opaque database-backed sessions, and the HTTP middleware that enforces them.
buildinfo
Package buildinfo exposes version metadata set at build time via -ldflags.
Package buildinfo exposes version metadata set at build time via -ldflags.
checks
Package checks runs a drift check against a workspace and persists the result, shared by both the synchronous "check now" HTTP endpoint and (from phase 5 on) the periodic scheduler - so there's exactly one place that decides how a check's outcome becomes database rows.
Package checks runs a drift check against a workspace and persists the result, shared by both the synchronous "check now" HTTP endpoint and (from phase 5 on) the periodic scheduler - so there's exactly one place that decides how a check's outcome becomes database rows.
config
Package config loads groundtruth's runtime configuration from environment variables.
Package config loads groundtruth's runtime configuration from environment variables.
drift
Package drift turns a raw *tfjson.Plan from a refresh-only Terraform plan into groundtruth's own, already-redacted representation - the only form of a plan that's ever persisted or returned by the API.
Package drift turns a raw *tfjson.Plan from a refresh-only Terraform plan into groundtruth's own, already-redacted representation - the only form of a plan that's ever persisted or returned by the API.
httpapi
Package httpapi wires groundtruth's HTTP routes: the JSON API under /api, a health check for container orchestrators, and the embedded SPA for everything else.
Package httpapi wires groundtruth's HTTP routes: the JSON API under /api, a health check for container orchestrators, and the embedded SPA for everything else.
scheduler
Package scheduler periodically runs drift checks for every enabled workspace that's due, bounding how many run at once.
Package scheduler periodically runs drift checks for every enabled workspace that's due, bounding how many run at once.
store
Package store owns groundtruth's SQLite database: connecting to it, running its versioned migrations, and (via the sqlc subpackage) running type-safe queries against it.
Package store owns groundtruth's SQLite database: connecting to it, running its versioned migrations, and (via the sqlc subpackage) running type-safe queries against it.
store/migrations
Package migrations embeds groundtruth's versioned SQL schema migrations so they ship inside the binary instead of as loose files on disk.
Package migrations embeds groundtruth's versioned SQL schema migrations so they ship inside the binary instead of as loose files on disk.
store/storetest
Package storetest gives tests a real, migrated, temporary SQLite database — matching this project's testing philosophy of exercising a real database rather than mocking the DB layer.
Package storetest gives tests a real, migrated, temporary SQLite database — matching this project's testing philosophy of exercising a real database rather than mocking the DB layer.
terraform
Package terraform runs terraform/tofu plans safely: each check gets an isolated, disposable working directory, credentials are read fresh from an operator-supplied file and never persisted, and no shell is ever invoked.
Package terraform runs terraform/tofu plans safely: each check gets an isolated, disposable working directory, credentials are read fresh from an operator-supplied file and never persisted, and no shell is ever invoked.
webassets
Package webassets embeds the built frontend (web/dist, copied here by `make build-frontend`) into the Go binary.
Package webassets embeds the built frontend (web/dist, copied here by `make build-frontend`) into the Go binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL