Skip to content
env-sync-viewer
Menu

Product

The product

Three parts, each with one job: the collector writes drift snapshots, the database keeps them behind two narrow roles, and the viewer reads them.

The collector

apps/collector runs env-sync diff --format json as a subprocess, once per selector in the filtered inventory, and writes one collector run plus its drift snapshots in one transaction.

Before it collects, pre-flight checks every service against a reviewed allowlist and a probe proves that the pinned env-sync refuses targets outside its scope.

The database

packages/db is a Drizzle schema plus hand-written SQL: three tables (collector_runs, drift_snapshots, drift_snapshot_keys), a collector role that can only insert, a viewer role that can only select, and forced row-level security.

Each key row holds the key name, its key status and two 12-character fingerprints. There is no column for a secret value.

The viewer

apps/web is a read-only Next.js dashboard. It builds a minimal fleet view on the server, with no fingerprints in it, and renders the targets and the last 20 collector runs.

An access gate checks every request: a Supabase session and a confirmed email on the viewer allowlist.

At a glance

Runs on
Your infrastructure; there is no hosted service
Collector
A scheduled job (every 6 hours in the shipped workflow)
Storage
Postgres, in an env_sync schema
Shows
Key names and key states; never values or fingerprints
Writes to targets
Never: it only runs env-sync diff
Source code
Private repository; access by request

Know which secrets drifted, without seeing them

env-sync-viewer is self-hosted: you run the collector and the viewer in your own infrastructure. Access to the repository is by request.