The ENC CLI
enc is a git-style CLI for end-to-end encrypted, append-only data, built on the ENC
protocol kernel compiled to WASM. You init a repo, append signed events, snapshot the
state, and push to remotes — same shape as git, but every event is cryptographically signed,
every state hash is auditable, and every byte is verifiable from a Signed Tree Head down to
the last event.
enc init
enc identity new alice
enc commit -m "hello enc" --priv-key $(enc identity show alice)
enc log
enc push originThe verify commands run entirely against the locally embedded WASM kernel — no network, no
trust. See the Sparse Merkle Tree and
Certificate Transparency specs for what the proofs attest to, and
Run a Node for the server side that push/pull talk to.
Install
From source
git clone https://github.com/enc-protocol/impl-wasm
cd impl-wasm
cargo build --release --bin enc
sudo install target/release/enc /usr/local/bin/
enc --versionYou need a recent stable Rust toolchain (rustup install stable). The build embeds
enc-core.wasm (~256 KiB) at compile time — there's no separate kernel to install.
Verify the install
enc self-testIf that prints OK, you're done.
Quick tour
1. Create a repo
mkdir my-enc && cd my-enc
enc initThis writes .enc/ with state.bin (the enclave state) and keys/ (signing identities) —
the same shape as .git/.
2. Create a signing identity
enc identity new alice
enc identity list
enc identity show alice # prints alice's pubkeyIdentities are local Schnorr keypairs under .enc/keys/. Every commit needs one. Use
enc identity show alice for the pubkey; the private key lives in .enc/keys/alice.json.
3. Commit signed events
enc commit -m "first event" --priv-key <hex>Commits are signed normative events: they advance the seq counter and feed into the next bundle.
4. Inspect state
enc status # bundle counter, seq, memory
enc log # linear event log
enc log --limit 10 --json # machine-readable
enc events # raw event dump
enc find <event_id> # by hex id
enc show 0 # by index
enc cat <event_id> # raw content5. Close a bundle + read the STH
enc close-bundle # flush events into a sealed bundle
enc sth # current Signed Tree Head
enc inclusion 0 # inclusion proof for bundle 0
enc verify-sth # check STH integrityThe Signed Tree Head is the canonical hash anyone can use to verify this enclave's state without trusting you.
6. Snapshot + restore (offline backup)
enc snapshot ./backup.enc # full enclave dump
enc verify-pack ./backup.enc # check pack integrity
enc restore ./backup.enc # load it backSnapshots round-trip byte-identically, and the same pack works on any host — CLI, Worker, or browser.
Working with remotes
enc remote add origin https://your-node.example.com
enc remote list
enc remote set-default origin
enc push # send local bundles to the default remote
enc push origin
enc pull # pull bundles + STH from a remote
enc fetch origin # fetch without applying
# clone runs init + fetch + apply in one step:
enc clone https://your-node.example.com/enclaves/<hex_id> ./freshPoint a remote at any ENC node — a Cloudflare Worker, a self-hosted encd,
whatever speaks the protocol.
Proofs
The protocol gives you a cryptographic proof for everything:
enc proof commit --commit-hash <h> # commit proof
enc proof inclusion --bundle 0 # bundle inclusion proof
enc proof consistency --from 0 --to 5 # consistency proof
enc verify --proof <hex> # verify any proof
enc verify-pack ./backup.enc # pack integrity
enc verify-sth # STH integrityOther operations
Crypto primitives
enc sha256 hello
enc generate-session --priv-key <h>
enc ecdh --priv-key <h> --pub-key <h>
enc derive-key --shared <h> --label app
enc encrypt --key <h> --plaintext "secret"
enc decrypt --key <h> --content <hex>Migrate the sequencer key
enc migrate --to <new-priv>Migrates the enclave to a new sequencer key. The old key is invalid afterward and future commits sign under the new one — but old bundles stay verifiable.
Append raw bytes (low-level)
enc append "0102030405"Skips the normative event-signing pipeline. Use only when you know exactly what you're doing.
Full command list
Repo lifecycle
init Initialize a new enclave repository
init-with-priv Initialize from a specific sequencer key
clone Clone a remote enclave
migrate Migrate to a new sequencer key
Identity
identity new <alias> Create a new signing identity
identity show <alias> Print pubkey
identity list List local identities
Events
commit Append a signed normative event
append Append raw bytes (low-level)
status Show enclave state
log Linear event log
events Raw event dump
find <event_id> Find by event_id
show <ref> Inspect by index or ref
cat <event_id> Raw content
cat-file <ref> Typed object retrieval
reflog Recent ref movements
Bundles + packs
close-bundle Seal the current bundle
snapshot <out> Full enclave dump
restore <input> Load a .enc pack
verify-pack <input> Pack integrity check
Proofs
sth Current Signed Tree Head
inclusion <idx> Bundle inclusion proof
verify-sth STH integrity
verify --proof <h> Verify any proof
proof <kind> Build a typed proof
Network
remote add | list | remove | set-url | set-default
pull [<remote>] Pull bundles + STH
push [<remote>] Push local bundles
fetch [<remote>] Fetch without applying
Crypto
sha256 SHA-256
self-test Kernel self-test suite
generate-session Signed session token
verify-session Check session token
ecdh ECDH key agreement
derive-key KDF
encrypt AEAD encrypt
decrypt AEAD decrypt
Config
config Read or write enclave-local configRun enc <cmd> --help for full flags.
Where things live
.enc/
state.bin linear-memory snapshot of the WASM enclave
keys/ signing identities (Schnorr)
config local config overridesOverride the kernel (for testing) or the state directory:
enc --wasm /path/to/custom.wasm <cmd>
enc --state-dir /elsewhere <cmd>