Streaming encrypted archive tool for files, folders, and Unix-style pipelines.
- Standard age-compatible
.ravenvelope with a documented RAVP plaintext payload format. - Streaming-first encrypt/decrypt paths for files and Unix-style pipelines.
- Archive manifests record normalized UTF-8 paths, sizes, hashes, directories, files, and safe relative symlinks.
- Full archive verification authenticates the age stream, parses the payload, and checks manifest entry sizes and SHA-256 digests.
- Managed output commits use temporary files or directories to avoid replacing existing outputs with partial results.
- Release artifacts are produced by GitHub Actions with checksums, keyless cosign signatures, and GitHub artifact attestations.
| Area | Status |
|---|---|
| Cryptographic envelope | Uses the standard age file format for encryption, recipient handling, and stream authentication. |
| Archive path policy | Rejects absolute paths, traversal, backslashes, Windows drive-like paths, reserved names, duplicate normalized paths, and unsafe symlink targets. |
| Extraction safety | Extracts to a temporary directory inside the existing output parent and commits only after manifest and content verification succeeds. |
| Secret handling | Public API secret-bearing variants use SecretString; CLI debug output avoids dumping sensitive argument structs. |
| Automated validation | CI runs format, clippy, tests, audit, deny, and Rust 1.88 MSRV checks on Ubuntu, Windows, and macOS. |
| Fuzzing | Cargo-fuzz/libFuzzer targets cover RAVP prelude parsing, manifest parsing, archive path validation, and TAR entry path validation. |
| Release provenance | Release workflow publishes checksums, keyless cosign signature material, and GitHub artifact attestations for release archives. |
| Independent audit | Not yet independently audited by a third party. |
The security-sensitive review surface is the local CLI and Rust library behavior for encrypting, decrypting, packing, verifying, inspecting, and unpacking .rav files. In scope: age envelope integration, passphrase and identity handling, RAVP prelude and manifest parsing, archive path validation, TAR payload verification, managed output commits, temporary unpack behavior, release workflow provenance, dependency policy, and fuzz/CI coverage.
Out of scope: compromised hosts, malicious administrators, shell history or terminal capture, storage-layer forensic erasure, cloud sync behavior, key recovery, age plugin implementation trust, hardware-token security, and third-party package manager distribution channels. Ravencap also does not claim a completed independent third-party security audit.
This repository contains Ravencap v2.0.2: an age-compatible streaming encryption and archive tool with pack/unpack, manifest inspection, and quick/full verification workflows.
Ravencap is built around conservative security boundaries, explicit non-goals, safe archive extraction, and documented trust-model semantics. It has not undergone an independent third-party security audit.
Release validation and provenance expectations are documented in docs/release.md.
Copyright (c) 2026 VaV Labs.
A .rav file is a standard age-encrypted file. After age decryption, the plaintext begins with a Ravencap RAVP stream: a small prelude, a JSON manifest prefix, and the content stream.
Ravencap is focused on encrypted files, folders, and pipelines. It does not manage snapshots, retention, scheduling, deduplication, sync, cloud storage, or repositories.
Install Rust 1.88 or newer from https://rustup.rs/, then install the published CLI package:
cargo install ravencap-cliThis installs the ravencap binary:
ravencap --helpPrebuilt release archives are available from GitHub Releases for Linux x86_64, Windows x86_64, macOS x86_64, and macOS arm64.
ravencap pack --passphrase-file passphrase.txt ./folder -o folder.rav
ravencap verify folder.rav --passphrase-file passphrase.txt
ravencap unpack folder.rav --passphrase-file passphrase.txt -o restored-folderInstall Rust 1.88 or newer from https://rustup.rs/, then build the CLI from this repository:
cargo build --releaseThe binary is written to target/release/ravencap on Unix-like systems and target\release\ravencap.exe on Windows. In PowerShell, run the local binary with an explicit current-directory prefix:
.\target\release\ravencap.exe --helpPassword mode:
ravencap encrypt --passphrase-file passphrase.txt -i payload.ravp -o payload.rav
ravencap decrypt --passphrase-file passphrase.txt -i payload.rav -o payload.ravp
ravencap pack --passphrase-file passphrase.txt ./folder -o folder.rav
ravencap unpack folder.rav --passphrase-file passphrase.txt -o restored-folderPublic-key mode:
ravencap keygen -o alice.ravkey
ravencap pubkey alice.ravkey -o alice.ravpub
ravencap encrypt -r $(cat alice.ravpub) -i payload.ravp -o payload.rav
ravencap decrypt --identity alice.ravkey -i payload.rav -o payload.ravp
ravencap pack -r $(cat alice.ravpub) ./folder -o folder.rav
ravencap unpack folder.rav --identity alice.ravkey -o restored-folderUse --passphrase-file for scripted local tests where prompting is not practical. Omit passphrase options to use the interactive prompt. Private-key identity files passed with --identity are read as age secret keys, including standard age identity files with comment lines.
Age/rage interop:
age -d -i alice.ravkey folder.rav > folder.ravp
rage -d -i alice.ravkey folder.rav > folder.ravp
ravencap decrypt --identity alice.ravkey -i folder.rav -o folder.ravpThese commands are equivalent at the encryption layer: they produce decrypted RAVP bytes. Standard age-compatible tools do not parse Ravencap manifests or unpack Ravencap archives. Use ravencap inspect, ravencap verify, or ravencap unpack for RAVP semantics.
Hardware-key and plugin note: .rav files use the age file format, so external age/rage tooling may be used for plugin-backed decryption to RAVP plaintext. The Ravencap CLI currently supports passphrases and age secret-key identity files directly; it does not invoke age plugins itself.
Public metadata check:
ravencap info payload.rav
ravencap inspect payload.rav --passphrase-file passphrase.txt
ravencap inspect payload.rav --passphrase-file passphrase.txt --json
ravencap verify --quick payload.rav --passphrase-file passphrase.txt
ravencap verify payload.rav --passphrase-file passphrase.txt
ravencap verify payload.rav --passphrase-file passphrase.txt --jsoninfo only checks the public age header. inspect decrypts the RAVP prelude and manifest prefix, but does not verify the content stream. verify --quick authenticates the full outer age stream without archive semantics. Full verify authenticates the age stream, parses/decompresses the TAR payload, and validates manifest checksums.
Stdin/stdout raw stream usage:
ravencap encrypt --passphrase-file passphrase.txt < payload.ravp > payload.rav
ravencap decrypt --passphrase-file passphrase.txt < payload.rav > payload.ravpOmit -i or -o on encrypt/decrypt to use stdin or stdout. Use - as the archive input path for commands such as inspect, verify, and unpack when reading from stdin. Omit passphrase options to be prompted. --insecure-passphrase-cli exists only for controlled tests and prints a warning because command-line secrets can appear in process listings and shell history.
Managed -o writes are committed through a temporary file in the same directory. Existing output paths are preserved unless --overwrite is provided. This protects command-managed outputs from accidental replacement and avoids committing partial files when Ravencap returns an error.
Shell redirection is controlled by the shell, not Ravencap. Commands such as ravencap decrypt ... > output can leave partial files if interrupted or if the command fails after the shell creates the destination. Streaming decrypt emits plaintext before final authentication succeeds at EOF; use managed -o output or run verify first when writing files that should only appear after a fully authenticated read.
Archive unpack extracts to a temporary directory inside the existing parent directory of the requested output and renames it into place only after manifest and content verification succeeds. The requested output directory must not already exist, and its parent directory must already exist.
- Ravencap relies on the age layer for encryption, recipient handling, and stream authentication.
- Losing a passphrase or private key means Ravencap cannot recover the plaintext.
- Compromised machines, malicious administrators, keyloggers, and unsafe shell history can expose secrets before Ravencap sees them.
- Input trees should remain unchanged while
ravencap packis running. Ravencap verifies packed archives during laterverifyorunpack, but concurrent source changes can produce an archive whose manifest and payload no longer agree. - Archive paths are UTF-8, NFC-normalized, forward-slash relative paths. Absolute paths, traversal, Windows drive-like paths, reserved names, and unsafe symlink targets are rejected.
- Symlinks are restored only when the target stays inside the same top-level archive root component and resolves to a file or directory entry in the manifest. Multi-root archive symlink traversal across top-level components is intentionally unsupported in v1 format semantics.
- Ravencap restores file contents, directories, and safe relative symlinks. It does not preserve ownership, group, mtime, permissions, setuid/setgid bits, ACLs, or extended attributes. Restored regular files are created according to the current platform defaults and process umask.
- Extraction should happen in a parent directory controlled by the caller. Ravencap does not fully defend against a concurrent local attacker modifying the extraction parent during the final rename.
inspectis intentionally a partial read and must not be treated as content verification. Use fullverifybefore trusting archive contents.
Small compatibility fixtures live in tests/vectors and are validated by cargo test --workspace. A simple non-technical user guide is in docs/user-guide.md, more command examples are in docs/examples.md, and the v1 format is described in docs/file-format-v1.md.
crates/ravencap-cli: CLI binary surface.crates/ravencap-core: high-level APIs for encrypt/decrypt/pack/unpack.crates/ravencap-format: RAVP payload constants, prelude, manifest, parser.crates/ravencap-testkit: shared fixtures and helpers.tests/vectors: small format-stable compatibility fixtures.
ravencap-core exposes the v1 stable surface through top-level functions and option/report types: encrypt_stream, decrypt_stream, pack_path, unpack_archive, read_public_info, inspect_manifest, verify_archive, key helpers, and their associated options. Archive implementation modules are internal; manifest data types and path validators remain public for documented archive policy checks.
The full v1.0 closure roadmap is tracked in docs/v1-closure-plan.md.
- Keep CI green on every push.
- Run release-candidate checks from the closure plan.
- Keep docs aligned with tested CLI behavior.