svccat
Service catalog drift detection for multi-service repositories.
svccat reads your declared service manifest and compares it against what actually exists in the repo, flagging missing services, undeclared additions, and stale metadata before they become operational toil. It runs in your terminal and in CI, so your declared architecture stays honest.
Install
This puts a svccat binary on your PATH. (Or clone the repo and run
cargo build --release; the binary lands at target/release/svccat.)
Getting started
After installing, see svccat work immediately with the built-in demo, which runs a narrated walkthrough against a throwaway sample repo (no setup, nothing touched in your own files):
Then point it at your own repo:
And gate CI on a clean catalog:
Inside GitHub Actions, svccat check automatically emits inline PR annotations.
Quick start
Commands are grouped by task. Run svccat <command> --help for the full flags of any
command.
Set up a manifest
svccat initscaffolds aservices.yamlfrom your repo (--forceto overwrite), inferring each service'slanguageandplatformfrom files it finds on disksvccat import --from backstage|docker-compose|openapiseeds it from another sourcesvccat lintvalidates the manifest for structural issuessvccat install-hooksinstalls a pre-commit hook (--hook pre-pushfor pre-push)svccat completions bashprints a shell completion script (alsozsh,fish)
Check for drift
svccat checkinspects drift in the current reposvccat check --fail-on-driftexits 1 on any drift (CI gate)svccat check --depth 2also discovers services nested one level deepersvccat check --team platformlimits the check to one team's servicessvccat check --since HEAD~1 --fail-on-new-driftexits 1 only on new driftsvccat check --pingverifies that each serviceurlis reachable
Add --format <fmt> to change the output, where <fmt> is one of compact, csv,
json, sarif, markdown, junit, github-annotation, slack, teams, or datadog.
Fix drift
svccat fixadds undeclared services to the manifest, inferringlanguageandplatformfor each (--pruneremoves missing ones,--dry-runpreviews)
Visualize and report
svccat graphrenders a Mermaid diagram (--format dot|plantuml|markdown,--team,--filter)svccat reportwrites a full ownership and drift report (--format html,--history N,--badge)svccat scorecardscores each service on completeness, drift, and policysvccat statsprints a field-coverage summary with ASCII bar charts
Snapshots and diffs
svccat export --format json > snap.jsonsaves a catalog snapshot (csvalso works)svccat diff before.json after.jsoncompares two snapshotssvccat snapshot save|list|delete|diff <name>manages named drift snapshots
Watch and serve
svccat watchre-runs drift detection on every file change (--notify,--interval 30)svccat serveserves a live HTML report at http://localhost:7777 (--port,--refresh)
Audit, policy, and CI
svccat auditruns lint + drift + score in one pass (add--ping)svccat policychecks required/recommended fields (add--fail-on-violations)svccat ciruns lint + drift + policy in one CI-friendly pass
Query the catalog
svccat search authsearches by substring;svccat search team:platformby fieldsvccat depsanalyzes inter-service dependencies (--format mermaid|json)svccat tag add|remove <service> <tag>edits tags
Multiple repositories
svccat workspace checkchecks drift across every repo in a[workspace]section ofsvccat.toml, with aggregated reporting and cross-repo dependency analysis
Manifest is auto-detected: svccat tries svccat.yaml, svccat.yml, services.yaml,
services.yml in order. Most commands accept --output <file> and --format json.
Manifest format
# svccat.yaml (or services.yaml)
version: "1"
discovery: # optional: where to look for services
paths:
markers:
ignore:
policy: # optional: fields every service must declare (error if missing)
require_fields:
services:
- name: api-gateway # required
language: Go
platform: Cloud Run
role: Rate-limiting reverse proxy # required (error if missing)
url: https://gateway.example.com # enables --ping health checks
team: platform # optional ownership
oncall: platform@example.com
docs: docs/api-gateway.md # optional: warn if the file is missing
depends_on: # rendered as graph edges; validated for cycles
Declared services are matched to the repo by path:, then submodule:, then by name
against discovered directories. When discovery.paths is empty, svccat tries
services/*, microservices/*, apps/*, and packages/*.
Drift types
| Kind | Severity | Description |
|---|---|---|
declared_missing_from_repo |
error | Declared in the manifest but its directory is missing. |
undeclared_in_repo |
warning | A service directory exists but is not in the manifest. |
missing_field |
error / warning | A recommended field is absent (role = error; language, platform = warning). |
missing_referenced_file |
warning | A docs: or ci: path is declared but the file is missing. |
policy_violation |
error | A field required by policy.require_fields is absent. |
dangling_dependency |
error | A depends_on entry references an undeclared service. |
circular_dependency |
error | A cycle was detected in the depends_on graph. |
Errors and warnings both count toward --fail-on-drift.
Use it as a library
svccat ships as both a binary and a library, so you can call into the same modules the CLI uses:
use Path;
use ;
let manifest = load?;
let discovered = discover_services;
let report = analyze;
println!;
See examples/demo.rs (cargo run --example demo) and the API docs
on docs.rs/svccat.
Learn more
svccat <command> --helpdocuments every command and flag.- CHANGELOG.md for release history.
- SECURITY.md for the threat model and supported versions.
Support
svccat is free and open source. If it saves you some toil, you can buy me a coffee:
Contributing
Bug reports and pull requests welcome. Please run cargo clippy -- -D warnings and
cargo fmt before opening a PR.
License
MIT. See LICENSE.