Status: experimental (0.0.x). Keys are plain files for now (no TPM/HSM yet). Formats change without notice. Like all of weft, it is built heavily with AI; see How weft is made.
weft, the operator tool of weft: creates keys, signs the documents
devices obey, and checks them with weft-verifier
before they reach a device. Signing keys live here, never on devices.
export WEFT_TENANT=acme
weft key new root # root.key (secret, 0600) + root.pub: the fleet's trust anchor
weft key new site-a
# Delegate site-level config rights to site-a (narrowed, valid for 365 days by default).
weft delegate --key root.key --to site-a.pub --priorities site --actions config.write -o del-site-a.cose
# Fleet-wide config and a deployment.
echo '{"rate": 7, "mode": "auto"}' > fleet.json
weft config --key root.key --priority fleet --component app --version 1 --values fleet.json -o cfg.cose
weft deploy --key root.key --priority fleet --component app --version 1 --artifact @firmware.swu -o dep.cose
# Dry run: what would a device with these labels do? Exit 1 on rejections or conflicts.
weft check --anchor root.pub --label site=s1 --label line=l1 *.cose
weft inspect cfg.cose # signer, digest, contents as JSONweft check prints every document's status (accepted, superseded, not for this device,
rejected with the reason), conflicts such as ties between two issuers at the same priority, and
the resulting actions (install, apply-config with the effective configuration). Run it in CI
before a rollout.
| Command | Does |
|---|---|
weft key new <name> / key show <file> |
Ed25519 key pair; show a public key and its key id |
weft delegate |
Grant a subset of the issuer's rights (actions, priority range, components, required labels, validity) |
weft config |
Configuration fragment from a JSON file (integers, strings, booleans, null to delete, arrays, objects), with selectors and locks |
weft deploy |
Deployment of an artifact by SHA-256 (--artifact <hex> or @file) |
weft revoke |
Revocation of a key (trust anchors only) |
weft inspect |
Show documents |
weft check |
Dry run with weft-verifier for given device facts |
Priorities are numbers or the default profile names fleet (10), group (20), site (30),
device (40) and local (50). A new --version replaces the issuer's previous document for the
same priority and component completely; values merge across priorities.
Every document is parsed back with the verifier before it is signed, so weft cannot produce a
document devices would reject as malformed.
nix develop # or rustup (reads rust-toolchain.toml); needs ../weft-verifier next to this repo
just ciRequirements: requirements/cli.sdoc (CLI-001 to CLI-005), traced to code
and tests; cargo test fails when one is not covered.
MIT, see LICENSE. Security reports: SECURITY.md.