Registries
Subscribe DefenseClaw to public or internal skill / MCP catalogs. Sources are fetched, scanned, and clean entries are auto-promoted into asset_policy so admission decisions can attribute the rule back to its origin.
A registry source is a fetchable manifest of skills and/or MCP servers that DefenseClaw ingests on demand. Public catalogs (clawhub, smithery, skills.sh), internal HTTPS YAMLs / JSONs, git repos, and on-disk YAMLs are all supported. Synced entries flow through the existing skill / MCP scanners; clean ones land in asset_policy.{skill,mcp}.registry so a later admission decision can say "approved by registry:<id>" instead of "approved by an unattributed rule someone wrote in 2024."
Why registries matter
Without a registry, every new skill / MCP that lands on disk is admission-evaluated against ad-hoc operator-authored rules. With one or more registries, the catalog drives admission: clean entries get auto-promoted, everything else is held for review, and toggling registry_required flips the asset class to deny-by-default for anything the catalog hasn't blessed.
Guided example · Registry sync is on demand
Turn a catalog entry into an admission decision
On-demand sync verifies source integrity, routes through a scanner, and promotes, reviews, or denies a pre-authored variant.
asset_policy: skill: registry: workspace-helper@1.2.0: action: allow reason: registry:internal-catalogasset_policy: skill: registry: workspace-helper@1.2.0: action: allow reason: registry:internal-catalog
Integrity verified and scanner result is clean
Write attributed asset_policy rule
What DefenseClaw did — and did not do
What it did
- Run registry sync on demand
- Verify source integrity and route through existing scanners
- Attribute promoted rules to the registry source
What it did not do
- Poll registries automatically at runtime
- Let registry trust bypass scanner findings unless policy allows it
- Read a credential value from auth_env
What you just saw
An on-demand registry sync verified source integrity, routed an entry through its existing scanner, and selected a deterministic outcome: promote a clean entry, hold a warning for review, or deny an unknown asset when registry_required=true. Stored sync settings do not create a runtime poller.
The seven registry kinds
Prop
Type
Three worked examples
Most enterprises run a curated mirror inside their own DNS:
defenseclaw registry add corp-skills \
--kind http_yaml \
--url https://catalog.corp.example.com/skills.yaml \
--content skill \
--auth-env CORP_CATALOG_TOKEN \
--non-interactive
export CORP_CATALOG_TOKEN="$(vault kv get -field=token kv/defenseclaw/catalog)"
defenseclaw registry test corp-skills # dry-run: fetch + parse, no writes
defenseclaw registry sync corp-skills # fetch + scan + promoteThe --auth-env option takes the name of an env var; the literal token never lands in config.yaml. SHA-256 is required on every entry's source_url for http_yaml, http_json, git, and file kinds — the manifest publisher computes it once.
For the smithery.ai public MCP catalog:
defenseclaw registry add smithery-public \
--kind smithery \
--content mcp \
--non-interactive
defenseclaw registry sync smithery-publicEach entry is run through the MCP scanner; clean ones land in asset_policy.mcp.registry so an MCP listed in the catalog passes admission with the registry named as the reason. Remote (URL) entries are scanned directly. Scanning a stdio entry starts the publisher's package on your machine, so it happens only with registry sync --scan-stdio; without that flag the entry stays pending and is not promoted. Use --scan-stdio only for a catalog whose packages you are willing to run.
ClawHub lists OpenClaw plugins, so it matters mainly for OpenClaw installs. No URL and no auth are needed:
defenseclaw registry add clawhub \
--kind clawhub \
--content skill \
--non-interactive
defenseclaw registry sync clawhubThe first sync downloads the manifest, runs the skill scanner on every entry, and promotes the clean ones into asset_policy.skill.registry.
All twelve subcommands
Prop
Type
The lifecycle of an entry
List view for small screens. Use the expand button to open the drawing.
- Add a sourceregistry addsaved in config.yaml
- Sync the source
- Sync the sourceregistry syncfetch the manifest
- Scan each entry
- Scan each entryskill scanner or MCP scanner
- Scan result?
- Scan result?
- cleanAdded to asset policy
- anything elseHeld for review
- Held for reviewwarning or blockederror or pending
- you approveAdded to asset policy
- you rejectNever promoted
- Never promotedlisted as blocked
- Added to asset policyrule tagged registry:<id>
Promote and require — the deny-by-default story
Once entries are flowing in, asset_policy.<type>.registry_required flips the corresponding asset class to deny-by-default:
defenseclaw registry require --type skill --enabled
defenseclaw registry require --type mcp --enabled --enforceThe requirement is enforced only while asset policy is on:
asset_policy.enabled: true and asset_policy.mode: action. A per-user
install starts with enabled: false and mode: observe, so require alone
blocks nothing and the CLI says so. Add --enforce to turn both on in the same
save, or set them in the TUI config editor (Setup → c → Asset Policy). In
observe mode an unregistered asset is logged, not blocked. To turn
enforcement back off, run
defenseclaw registry require --type mcp --disabled --no-enforce
(--no-enforce sets mode: observe).
A registry rule that pins transport treats http and streamable-http as
the same HTTP transport, and a URL server added without --transport counts as
http.
An unscoped operation is broad operator intent: it updates the global default
and clears only the targeted registry_required override on every active
connector, so stale opposite overrides cannot keep enforcement disabled. All
other per-connector fields and the global registry rule/filter lists remain
unchanged. --connector <name> changes only that connector's explicit
override. Known but inactive connector overrides are preserved so future
activation does not silently inherit a weaker or stronger posture than the one
previously saved.
When registry_required=true:
- An asset whose name matches a rule in
asset_policy.<type>.registryfollows that rule. - An asset whose name does not match any rule falls through to the configured
registry_empty_action(defaultdeny). - An empty registry list with
require=onblocks every asset of that class by default until the nextsyncpopulates it. Settingregistry_empty_action: warnorallowrelaxes only this empty-registry gate and falls through to the type default;warnis non-blocking. The CLI warns you in colour when you fliprequire=onagainst an empty list — read the warning carefully.
The Go gateway tags every admission decision with Reason="registry:<id>" (or
"registry:operator-approved" for manually approved entries). Inspect the TUI
or run defenseclaw-gateway audit export --output - to see which catalog won;
an optional JSONL destination contains only the records its v8 route selects.
What --auth-env, --allow-private, and SHA-256 actually do
| Knob | Default | Purpose |
|---|---|---|
--auth-env <ENV> | "" | Name of an env var holding a bearer token sent on every fetch. The CLI rejects values that look like literal secrets. |
--allow-private | off | A registry test and registry sync flag (not add). Permits RFC 1918 / ULA destinations: off in production, on for an internal mirror on a private subnet. |
--scan-stdio | off | A registry sync flag. Also scans stdio MCP entries, which starts each publisher-controlled package on this machine. |
--non-interactive | off | Required for CI; missing required flags exit non-zero with a clear error: --foo is required. |
SHA-256 on source_url | required for http_yaml / http_json / git / file | Per-entry integrity; the scanner refuses to download an entry whose computed digest does not match. |
Registry fetches use the same hardened URL path in test and sync: loopback, link-local, cloud-metadata, and private-network destinations are refused by default, including DNS resolutions that rebind into a reserved range. Use --allow-private only for a registry mirror you intentionally run on an internal network. Local file registries must use absolute paths, and remote entry downloads must pass the per-entry SHA-256 check before scanner promotion can happen.
Inspect what landed
This is a real file source with two stdio MCP entries, synced without
--scan-stdio, so both entries are still pending:
Registry sources
----------------
ID KIND CONTENT ON ENTRIES LAST SYNC URL
------------------------ ------------ -------- --- ------------------ ---------------------- --------------------------------
corp-mcp file mcp yes 2 (0/0/0) 2026-10-03T04:25:28Z /tmp/corp-mcp.yaml
ENTRIES column: total (clean/warning/blocked) Entries for corp-mcp
--------------------
NAME TYPE STATUS SEV A/R
-------------------------------- ------ ---------- -------- ---
context7 mcp pending - --
filesystem mcp pending - --ENTRIES reads total, then clean, warning and blocked counts; a dash means the
source was never synced. A/R shows whether you approved or rejected an entry.
defenseclaw registry list # one row per source, with cached counts
defenseclaw registry show corp-skills # full detail + verdict summary
defenseclaw registry entries corp-skills --status warning
defenseclaw registry approve corp-skills my-skill --type skill
defenseclaw registry reject corp-skills evil-skill --type skillapprove and reject re-promote against the cached manifest immediately by default, so the new rule lands without a network round-trip. Pass --no-repromote if you want to defer the change to the next registry sync. --type is optional when the source holds one content type (--content skill or --content mcp) or the entry name exists under one type only.
Sync schedules
Today, syncing is on demand: scheduled sync is not available yet, and add / edit refuse --auto-sync and --sync-interval-hours. Run registry sync --all on a schedule (cron, a systemd timer or a CI schedule) until scheduled sync ships in a future release.
DefenseClaw configuration is per user, so schedule the sync as the user who
runs DefenseClaw, for example in that user's crontab (crontab -e):
0 * * * * defenseclaw registry sync --allKeep the gateway running: registry sync records an audit event and exits with
an error when the gateway is unavailable. Use the full path to defenseclaw if
cron's PATH does not include it.
Common gotchas
Reference
cli/defenseclaw/commands/cmd_registry.py— every subcommand, validator, and the lifecycle helpers.cli/defenseclaw/registries/— adapters, manifest schema, sync engine, promotion rules.- Reference → CLI — full CLI catalog.
- Skill scanner and MCP scanner — what the scanners look at when verdicts get computed.
- Policies — how
asset_policydecisions blend with repo policies and the LLM judge.
MCP scanner
Behavioural scan of every Model Context Protocol server an agent might call. DefenseClaw wraps cisco-ai-mcp-scanner to surface hidden tool intents and shadow capabilities, and maps each verdict through the mcp_actions admission policy.
AI Discovery
Find AI agents, installed local models, running model servers, MCP servers, skills, and providers on the host, and see which of them actually ran. DefenseClaw runs a continuous fingerprinting scanner and three runtime detection planes in the gateway, plus defenseclaw agent discover for an instant connector inventory.