CiscoCiscoDefenseClaw
Setup

Setup 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), 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, suspicious ones are quarantined for review, and toggling registry_required flips the asset class to deny-by-default for anything the catalog hasn't blessed.

The seven registry kinds

Prop

Type

Three worked examples

The friendly default. No URL, no auth, just opt in to the catalog:

defenseclaw registry add clawhub \
  --kind clawhub \
  --content skill \
  --non-interactive

defenseclaw registry sync clawhub

The first sync downloads the manifest, runs the skill scanner on every entry, and promotes the clean ones into asset_policy.skill.registry.

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 + promote

The --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-public

Each entry is run through the MCP scanner (transport probe + behavioral introspection); clean ones land in asset_policy.mcp.registry so an MCP listed in the catalog passes admission attribution-clean.

All twelve subcommands

Prop

Type

The lifecycle of an entry

skill
mcp
clean
warning
blocked
Operator runs`registry add`
Source persistedto config.yaml
`registry sync`fetches manifest
Per entry:skill or MCP?
Skill scannerSHA-256 + permissions+ LLM second opinion
MCP scannertransport probe+ behavioral introspection
Verdict
Auto-promote toasset_policy.{skill,mcp}.registryReason='registry:<id>'
Cached, NOT promoted.Operator reviews via `entries`and runs `approve` / `reject`.
Cached, NEVER promotedunless `approve` overrides.
From `registry add` to admission decision: every entry is fetched, scanned per type (skill or MCP), and either auto-promoted into `asset_policy`, parked for operator review, or hard-blocked.

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

When registry_required=true:

  • An asset whose name matches a rule in asset_policy.<type>.registry follows that rule.
  • An asset whose name does not match any rule falls through to the configured registry_empty_action (default deny).
  • An empty registry list with require=on blocks every asset of that class until the next sync populates it. The CLI warns you in colour when you flip require=on against 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) so you can grep ~/.defenseclaw/gateway.jsonl to see which catalog won.

What --auth-env, --allow-private, and SHA-256 actually do

KnobDefaultPurpose
--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-privateoffPermit RFC1918 / ULA destinations. Off in production; on for an internal mirror behind a private subnet. Same flag exists on test and sync.
--non-interactiveoffRequired for CI; missing required flags exit non-zero with a clear error: --foo is required.
SHA-256 on source_urlrequired for http_yaml / http_json / git / filePer-entry integrity; the scanner refuses to download an entry whose computed digest does not match.

Inspect what landed

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 skill

approve 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.

Sync schedules

Today, syncing is on demand. The --auto-sync and --sync-interval-hours flags on add / edit are persisted but the runtime does not poll. Run registry sync --all from a cron / systemd timer / GitHub Actions schedule until scheduled sync ships in a future release:

# /etc/cron.d/defenseclaw-registry
0 * * * * defenseclaw registry sync --all

Common gotchas

Reference