Your IT estate, as code. A live, git-versioned mirror of every system you run.
Your org's real state — who has access to what, what the firewall actually
allows, which devices exist — lives smeared across dozens of admin consoles,
and nowhere else. weave weaves it together: one CLI, one grammar, every
system. Look anything up across your whole estate, snapshot reality into
YAML you commit to git, diff it to see what changed since, and roll back
or carefully push edits when you need to.
weave whoami alice@example.com # find a human across every system at once
weave okta snapshot groups # your Okta groups, as YAML, in git
weave cloudflare diff dns --zone example.com # what changed since the snapshot?
weave meraki find client 00:11:22:33:44:55
weave pagerduty show oncall
weave vault list policies
weave github find repo andy-broyles/weavewhatever
weave sentry list issues --org my-org --project my-app87 modules, all live — identity, MDM, networking, comms, code, observability, secrets — with 255 snapshotable state kinds across them.
📖 Docs & catalog: https://weavewhatever.com
curl -fsSL https://weavewhatever.com/install.sh | bashirm https://weavewhatever.com/install.ps1 | iexThe installer bootstraps uv if needed and drops
the weave binary on your PATH as an isolated tool. Python 3.11+ required,
no sudo needed.
Other install methods (uv tool, pipx, from source, air-gapped, pinning a
version): see https://weavewhatever.com/install.html.
weave is a verb-noun CLI:
weave <module> <verb> <noun> [args] [--flags]
Six universal verbs, used everywhere they make sense:
| Verb | Purpose |
|---|---|
find |
Live lookup for a single entity |
show |
Full record for one entity |
list |
Bulk listing, paginated |
set |
Idempotent property update |
do |
One-shot action (suspend, reset-mfa, wipe, …) |
watch |
Long-poll a stream of changes |
Plus three top-level commands:
| Command | Purpose |
|---|---|
weave modules |
List every installed module, its status, and capabilities |
weave doctor |
Diagnose env-var readiness across every module |
weave whoami ID |
Cross-module identity lookup — find the same person in every system |
whoami is the killer move: it asks every installed module "do you know
anything about alice@example.com (or 00:11:22:33:44:55, or serial:C02XYZ)?".
It sequentially queries the 12 modules that ship a whoami resolver today
(Okta, Entra, Google Workspace, Active Directory, AWS IAM, GitHub, Slack,
PagerDuty, Datadog, Meraki, Tailscale, and more) and aggregates the results.
No central identity provider required — every module is a peer.
| Category | Count | Examples |
|---|---|---|
| Identity & SSO | 15 | okta, entra, googleworkspace, activedirectory, auth0, duo |
| Endpoints & MDM | 13 | intune, jamf, kandji, applebusinessmanager, crowdstrike, sentinelone |
| Networking | 21 | meraki, cloudflare, tailscale, paloalto, unifi, netbox |
| Comms & Incident | 7 | slack, teams, pagerduty, opsgenie, zoom, statuspage |
| Code & DevOps | 8 | github, gitlab, jira, linear, awx |
| Observability | 11 | datadog, sentry, grafana, splunk, elastic |
| Secrets & Config | 4 | vault, onepassword, doppler, infisical |
| SaaS / Business | 8 | servicenow, zendesk, stripe, snowflake, launchdarkly |
Full catalog with per-module commands: https://weavewhatever.com/modules/
weave reads credentials from environment variables. How those env vars get
into your shell is your choice — 1Password, HashiCorp Vault, Doppler, Infisical,
AWS Secrets Manager, a sourced .env file, GitHub Actions secrets, or manual
export. weave has no runtime dependency on any secrets manager.
Don't want to read vendor API docs to figure out where tokens even come from? Let weave walk you through it:
weave connect okta
# → exactly where to click in the admin console
# → the LEAST-PRIVILEGE scopes for mirror mode (never a god token to start)
# → paste the values (hidden input, never written to disk)
# → verified with a real API call, module enabled, storage options shownexport OKTA_DOMAIN=acme.okta.com
export OKTA_TOKEN=00aBcD...
weave enable okta
weave doctor --missing-only
weave okta find user alice@example.comOptional label for weave doctor output: export WEAVE_SECRETS_SOURCE=op-run
(or vault-agent, doppler, direnv, …).
# Examples — pick one backend your org already uses
op run --env-file=opvars -- weave okta find user alice@example.com
doppler run -- weave okta find user alice@example.comPer-backend recipes: docs/secrets-backends.md ·
onboarding guide
weave secrets backends # how to inject env vars (patterns, not vendor lock-in)
weave secrets list # env vars per module (read-only)
weave secrets check # WEAVE_SECRETS_SOURCE + per-module set/missing
weave login # PROVE the creds work: one real API call per moduleweave login doesn't just check that env vars exist — it exercises them:
"okta: token of svc-weave (ACTIVE)", "vault: weave-ro, policies:
read-only". A typo'd token fails here, not three commands later. Modules
that don't ship a verifier yet say so honestly (unverified); pass
--env-only to skip the API calls.
Live reality is the source of truth; YAML state files in your repo are an editable mirror of it, captured on demand. Snapshots are committed to git — that's how your estate gets history, peer review, and rollback for free. Diff anytime to feel the drift ("what changed since Friday?") with no intent to push anything. And when you do want to push: three verbs round-trip config between the file and the device.
weave drift # every snapshotted kind vs. reality, one digest
weave drift --refresh # reality won — update the mirror files
weave drift --commit # …and git-commit the refreshed snapshots
weave drift --json # for automation; exit 0 = clean, 4 = driftokta groups (acme) +1 ~0 -0 since 2026-06-06T22:11:04Z
+ group 'Contractors-Q3' new in reality
meraki ports (headquarters/main-office) +0 ~2 -0 since 2026-06-06T22:11:09Z
~ Q2XX-XXXX port 12
vlan: 10 → 20
Drift: 3 change(s) across 2 kind(s) (21 clean, 0 error(s)).
Drift is read-only and reports in mirror direction — "new in reality", "gone from reality" — because someone fixing things in a dashboard is not an error. Run it on a schedule and your git history becomes a flight recorder for the whole estate. Any scheduler works — the whole job is three steps, and weave doesn't care who runs them:
# 1. check out the repo holding .weave-state/
# 2. inject credentials (your secrets backend — see Authentication above)
# 3. refresh the mirror, push whatever changed
weave drift --commit --json
git push(Don't chain step 3 with && — drift exits 4 when it finds and refreshes
drift, which is exactly when there's a commit to push. 0 and 4 are both
healthy outcomes for a scheduled run; alert on exit 1, a real error.)
Plain cron on any box with the repo checked out:
0 6 * * * cd /srv/it-mirror && weave drift --commit --json; git pushThe same three steps drop into whatever your org already runs — a GitLab CI
schedule, a GitHub Actions schedule: workflow, Jenkins, Windows Task
Scheduler, systemd timers. weave has no favorite scheduler, the same way it
has no favorite secrets manager.
(If you're coming from Terraform: this is the inverse model. No desired state to enforce, no lock file, no drift to fight — someone fixing a port in the dashboard at 3am is not an error, you just snapshot again.)
# 1. Capture the truth
weave meraki snapshot ports --network "Main Office"
# → .weave-state/meraki/<org>/<network>/ports.yaml (commit this to git)
# 2. Edit the YAML — bulk-change VLANs, rename ports, swap a serial for
# a hardware migration, whatever. Your editor of choice.
# 3. Preview the diff
weave meraki diff ports --network "Main Office"
# ~ switch-port Q2XX-... port 12 vlan: 10 → 20
# 4. Push it back
weave meraki apply ports --network "Main Office" # confirms first
weave meraki apply ports --network "Main Office" --yes --dry-run # CI-friendlyEvery apply is wrapped in trust machinery:
- Automatic pre-apply snapshot — live state is captured before anything is pushed, every time.
weave <module> rollback <kind>— one command undoes the last apply (and a rollback can itself be rolled back). For deeper history,git checkout HEAD~1 .weave-state/...+weave applyrestores any committed state.- Post-apply verification — weave re-snapshots after applying and
proves the changes took:
Verified: live state matches the file — 0 residual differences.Changes an API silently rejected are reported, not discovered at the next diff.
Highlights:
- No central state file, no lock file, no provider engine. Each state file is independent and human-readable.
- Hardware migration becomes find-and-replace — swap a serial in the
YAML, run
apply, you're done. - Drift is not an error. Someone fixed a port in the dashboard at
3am? Just
snapshotagain — the file catches up.
255 state kinds across 86 of 87 modules. Every kind supports
snapshot and diff; most also apply (kinds whose write path would be
unsafe to genericize are deliberately snapshot-only and say so when you
try). A few highlights:
Networking & devices
| Module | Kind | What rounds-trips |
|---|---|---|
meraki |
ports |
Every switch port in a network (per-switch) |
meraki |
vlans |
Every appliance VLAN in a network |
cloudflare |
dns |
Every DNS record on a zone |
fortinet |
policies |
Every IPv4 firewall policy on a FortiGate |
paloalto |
security-rules |
Every security rule on the firewall (vsys1) |
unifi |
wlans |
Every WLAN/SSID configuration on a UniFi site |
mikrotik |
firewall-filter |
Every /ip/firewall/filter rule on a router |
tailscale |
acl |
The whole tailnet ACL document |
Identity & access
| Module | Kind | What rounds-trips |
|---|---|---|
okta |
groups |
Every group + member logins |
entra |
groups |
Every directory group + member UPNs |
googleworkspace |
groups |
Every Workspace group + member emails |
activedirectory |
group-memberships |
Direct members of a single AD/Entra group |
aws_iam |
policies |
Every customer-managed IAM policy on the account |
Endpoints & MDM
| Module | Kind | What rounds-trips |
|---|---|---|
intune |
configuration-profiles |
Every device-configuration profile (keyed by name + type) |
jamf |
configuration-profiles |
Every macOS configuration profile in the Jamf tenant |
mosyle |
profiles |
Every Mosyle profile (snapshot + diff; apply via dashboard) |
Collaboration & comms
| Module | Kind | What rounds-trips |
|---|---|---|
teams |
teams |
Every Team with settings + owner UPNs (keyed by displayName) |
Dev / ops / observability
| Module | Kind | What rounds-trips |
|---|---|---|
github |
branch-protection |
Branch protection rules on every protected branch |
slack |
channels |
Every public channel (rename / topic / archive) |
pagerduty |
services |
Every service (name, description, escalation) |
sentry |
projects |
Every project in a Sentry org (slug, platform, team) |
datadog |
monitors |
Every monitor (keyed by name + type) |
Security & secrets
| Module | Kind | What rounds-trips |
|---|---|---|
vault |
policies |
Every ACL policy, HCL body inlined |
crowdstrike |
prevention-policies |
Every prevention (AV/EDR) policy in the tenant |
The lone holdout, onepassword, is Events-API only and can't host
group/profile state without a Connect/SCIM credential — left out
intentionally rather than half-implemented.
Adding new kinds is three small functions per module —
see State management →
or CONTRIBUTING.md.
By default, weave autodetects whether stdout is a TTY:
- Interactive (terminal): Rich-rendered tables, colored.
- Piped (jq, tee, file): JSON.
Override anywhere with --format auto|table|json, --json, or
WEAVE_OUTPUT=json in the environment.
weave okta list users # table
weave okta list users --json | jq . # JSON for pipelines
weave okta list users | tee out.json # also JSON, autodetectedweave is alpha. The verb-noun grammar, manifest format, and module API
are stable enough to build against, but expect occasional sharp edges and
breaking changes before 1.0. File issues, send PRs, the maintainer reads
everything.
If you're considering it for production: the read-only find / list /
show paths are safe. The mutating do / set paths work but should be
exercised in a non-prod tenant first.
Adding a new module is intentionally cheap — a manifest + a Typer app, usually 200–400 lines of Python, and the catalog page regenerates itself from the manifests.
See CONTRIBUTING.md for:
- Adding a brand-new module
- The shared HTTP client + OAuth helpers
- Manifest fields and module categories
- Wiring a module into
weave whoami - Adding state kinds (snapshot / diff / apply)
The fastest path to a useful contribution: a missing system your org runs,
a new state kind on an existing module, or a whoami resolver.
git clone https://github.com/andy-broyles/weavewhatever.git
cd weavewhatever
uv sync --dev
uv pip install -e .
weave --help
weave modulesTests will land alongside the live-module rollout. For now:
make format # ruff format + ruff check --fix
python -m compileall -q src # smoke-check the whole treeThe docs site is a single static docs/ directory. To preview it locally:
make docs # serves at http://localhost:8000The catalog page (docs/modules/index.html) is generated from the manifests
themselves — never hand-edit it. Run:
python scripts/build_modules_page.pyTo add a new module, copy the layout of an existing one (okta, github,
and entra cover the common auth styles) — see CONTRIBUTING.md. New
modules ship complete: manifest, real API wiring, and tests.
weave/
├── src/weave/
│ ├── main.py # top-level CLI (modules, doctor, login, whoami)
│ ├── core/
│ │ ├── manifest.py # Manifest, Capability, module registry
│ │ ├── discovery.py # auto-imports every module under modules/
│ │ ├── http.py # shared HttpClient + ApiError / NotFound
│ │ ├── graph.py # Microsoft Graph OAuth helper (entra/intune/teams)
│ │ ├── criticality.py # vibe-check safety gate for apply
│ │ └── output.py # TTY-aware table/JSON rendering
│ └── modules/
│ ├── okta/ # one package per integration
│ ├── meraki/
│ └── … # 86 total
├── docs/ # static site (Tailwind via CDN, zero build step)
├── audit/ # internal quality/smoke reports (not deployed)
├── scripts/
│ ├── build_modules_page.py # regenerate docs/modules/index.html
│ ├── audit_modules.py # module quality audit → audit/
│ └── smoke_test_modules.py # static + opt-in live smoke checks
├── pyproject.toml
├── vercel.json # static-site deploy config
└── LICENSE
MIT © 2026 Andy Broyles.
weave is built on top of Typer,
Rich, httpx,
and uv. The verb-noun grammar is shamelessly
inspired by kubectl. The "every-module-is-a-peer" architecture is what
falls out when you genuinely commit to no central identity provider.