What Fury gives you.
Four commands. One does the everyday encryption work; the others make identities, inspect files, and keep your key off the machines you do not trust.
The core
Encrypt with a public key, decrypt with your identity.
Generate an identity and Fury writes two files: the private identity you keep, and the public key you hand out. Anyone can encrypt to you; only you can open the result.
- File payloads: ChaCha20-Poly1305 in fixed 64 KiB chunks
- 32-byte random file key, per file
- Authenticated header; truncation and appended data both rejected
Key agreement
Two lattice families, one file key.
FrodoKEM-640-SHAKE and ML-KEM-768 both wrap the same file key. Breaking one is not enough — an attacker needs both to fall, for the same recipient, on the same day.
- Suite identity embedded in every key and file
- Decryption dispatches on the stanza tag it finds
- 256-bit keys preserve a post-quantum symmetric floor
Identities
Protected on disk, always.
Private identities are encrypted with Argon2id and XChaCha20-Poly1305 before they touch the filesystem. Change the passphrase whenever you like; inspect and manage unlock methods without exporting anything.
- Multi-slot format with passphrase and security-key recovery
- Existing identities migrate in place
- Public keys as
fury1…, fingerprints as furyfp1…
Authorship
Sign it, and prove both ways at once.
A separate signing identity produces a detached signature that is only valid when Ed25519 and ML-DSA-65 both verify. Neither component can be stripped, and neither can be downgraded to on its own.
- Signing keys are independent of encryption identities
- Signs the file digest and, optionally, the intended policy
- Keys as
furysig1…, fingerprints as furysigfp1…
Teams
Name a recipient set once, rotate it later.
A policy is a strictly parsed snapshot of up to 256 public keys with its own furypolicy1… digest. Encrypt to the policy, and when the team changes, rekey the ciphertext to a new one without re-encrypting the payload.
- Rekey authenticates every payload chunk before it rewrites the header
- Canonical member order; duplicate and unknown fields rejected
- Rotation, not revocation — an old copy stays readable to whoever kept it
Trust
Bind a person to their keys, and notice when that changes.
A signed profile ties a subject to exact encryption and signing keys, validity dates, a sequence number and revocation state, under an issuer you trust. Fury keeps durable local state and refuses anything that contradicts it.
- Rollback, equivocation and unlinked updates rejected
- Issuer-key changes need a deliberate trust migration
- Revocation is recorded before encryption is refused, so replay fails too
Private Vault
A store where the filenames are secrets too.
Names, exact sizes, modes, timestamps and history live only inside encrypted records. On disk there are random identifiers and size-bucketed objects — locally or over SSH. Add, list, get, rename and delete, with every change recorded inside the encrypted catalogue.
- Authenticated mode signs each record, so writers are attributable
fury audit reads back who changed what, and when they said so
- Retained, not permanent: the Reaper prunes old history on purpose
Backup
Snapshots that cannot be quietly rewritten.
Every snapshot manifest is encrypted, composite-signed and chained to its predecessor. The trust anchor lives outside the repository, so a rollback, a fork or a replaced snapshot is detected rather than accepted.
- Per-file objects — restore one path without unpacking the archive
- A second traversal catches files that moved while they were read
- Restore drills issue signed receipts bound to the exact snapshot
Hardware
Unlock with a security key.
Enrol a FIDO2 security key as an unlock method, so opening a file needs a physical touch as well as a passphrase — and losing the laptop is no longer the same as losing the archive.
- The key unwraps the container, it does not hold the identity
- Passphrase recovery is always retained, so a lost key is survivable
- Native helper built against
libfido2; stubs are refused
Remote work
Decrypt on the server without shipping your key to it.
The agent unlocks a header and returns only its file key, over a local or explicitly forwarded Unix socket. Identities, passphrases and plaintext never cross the protocol, and each request needs confirmation.
- Requests bound to a verified SSH session; unbound ones denied by default
- Optional policies per transport, host-key chain, identity and expiry
- Hash-linked local audit log, verifiable with
fury-agent audit verify
Inspection
Check it before you rely on it.
Describe an encrypted file — its suite, its recipient stanzas, its shape — without decrypting a byte. Then run the preflight: installation, identity permissions, recovery methods and authenticated backup continuity, all read-only.
- No passphrase needed to look, no security key touched by the preflight
- Signed drill receipts checked against the snapshot actually present
--json --strict for monitoring that should page somebody
For developers
A file format and a Go library, not just a binary.
The format is documented end to end — intro line, stanzas, header MAC, chunked payload, armour — and the same behaviour is available as a library, with the private-identity rule enforced in the API itself.
- Stable v1 wire format with published compatibility rules
- Reproducible release builds and a British-English handbook
- GPLv3, so you can read every line before trusting it
What Fury does not claim
Fury is not unbreakable, military-grade or zero-knowledge, and it does not use those words. A .fury file protects contents, not filenames and not exact sizes; there is no forward secrecy, so a compromised identity exposes every ciphertext already sent to it; and rekeying rotates a recipient set rather than revoking anyone who kept the old copy. A vault hides names and timestamps but still leaks size buckets, object counts and access timing, and nothing detects hostile storage that deletes, withholds or replays records. Backups detect forks and rollback only through the trust anchor you keep outside the repository. Fingerprints authenticate keys, not people — verify important ones through a separate channel. And Go cannot guarantee key material is erased from memory, which Fury states rather than glosses over.