rootly-catalog-sync is a standalone CLI tool that reconciles external sources of truth into Rootly’s Catalog. It pulls data from your existing systems — GitHub repos, Backstage, internal APIs, CSV files, or any command — and syncs it one-way into Rootly, keeping services, teams, and metadata up to date automatically.

Why use Catalog Sync?
- Single source of truth — your service catalog lives in GitHub, Backstage, or a database. Rootly mirrors it automatically.
- No manual data entry — add a service to your repo, it appears in Rootly on the next sync.
- Safe by default — deletes are opt-in, empty sources abort, prune ratio thresholds prevent mass deletion.
- Terraform-style workflow —
planto preview,applyto execute,statusto check drift.
Install
Quick start
Authentication
Two methods are supported, in priority order:API key (CI / non-interactive)
OAuth 2.0 (interactive)
ROOTLY_API_KEY is set, it always takes precedence over OAuth tokens.
Configuration
The sync tool uses a declarative config file that defines pipelines — each pipeline connects sources to catalog outputs..yaml (default), .jsonnet, or .hcl. Credentials use $(ENV_VAR) substitution.
Sources
| Source | Description |
|---|---|
inline | Entries defined directly in config |
local | YAML/JSON files from disk (glob patterns) |
github | Files from GitHub repositories (supports ** patterns) |
exec | Run a command, parse stdout as JSON/YAML |
backstage | Backstage catalog API with pagination |
graphql | Arbitrary GraphQL endpoint with cursor/offset pagination |
csv | CSV files with header row |
url | Fetch YAML/JSON from remote URLs |
http | Generic REST API with JSONPath extraction |
GitHub source example
Exec source example
URL source example
HTTP source example
Commands
| Command | Description |
|---|---|
plan | Preview changes (creates a saved plan file) |
apply <plan> | Apply a saved plan (validates freshness first) |
sync | Plan + apply in one step |
status | Read-only drift check (--fail-on-drift for CI gates) |
init | Create a config file (add --interactive for guided wizard) |
validate | Check config syntax |
doctor | Verify API key, connectivity, and permissions |
sources inspect | Dump raw source entries before mapping |
explain <id> | Trace one entry through source → mapping → diff |
adopt | Claim existing UI entries under sync management |
import | One-shot seed (no prune, no lock) |
watch | Continuous sync loop (--interval=5m) |
tui | Interactive terminal UI for selective apply |
login | Authenticate via browser OAuth 2.0 (PKCE) |
logout | Clear stored OAuth tokens |
Safety guarantees
- Deletes are opt-in —
--allow-prunerequired, off by default - Empty source aborts — never wipes a catalog on a source failure
- Prune ratio threshold — aborts if deletes exceed 20% of live entities (configurable via
--prune-threshold) - Manual entries are safe — only entries with
external_id(created by sync) are prunable - Order: create/update first, delete last — no window where entries are missing
- Plan freshness —
applyvalidates that live state hasn’t changed since the plan was created
CI/CD integration
GitHub Actions
Dry-run on PRs
Nightly drift detection
Environment variables
| Variable | Description | Default |
|---|---|---|
ROOTLY_API_KEY | API key (or use login for OAuth) | — |
ROOTLY_API_URL | Override base URL | https://api.rootly.com |
ROOTLY_API_PATH | Override API path prefix | /v1 |
Interactive TUI
Thetui command launches a full-screen terminal UI for reviewing and selectively applying changes:
- Browse changes with colored badges (CREATE/UPDATE/DELETE/NOOP)
- Toggle individual changes with
space, expand field diffs withenter - Filter by operation type (
c/u/d) or search (/) - Detail pane shows full entity fields on wide terminals
- Apply only selected changes with
A