[](https://crates.io/crates/oth_rvault)
[](https://hub.docker.com/r/okieoth/rvault)
# rvault
A tool to encrypt or decrypt JSON or YAML files that contain partial Ansible vault encrypted values.
This is a Rust port from here: https://github.com/OkieOth/partial-vaults/tree/main
## Overview
rvault allows you to work with files that have a mix of plain text and Ansible Vault encrypted values. Unlike standard Ansible Vault which encrypts entire files, this tool lets you:
- Encrypt specific values within JSON or YAML files
- Decrypt specific values while leaving others encrypted
- Process nested structures with selective encryption
- Interactively edit encrypted values in-place
- Copy decrypted values to the clipboard with auto-clear
## Install
```bash
# install from crates.io
cargo install oth_rvault
# use
rvault --help
```
## Usage
rvault has four subcommands: `encrypt`, `decrypt`, `edit`, and `clip`.
### Password resolution
All subcommands need a vault password. It is resolved in this priority order:
1. `--password <PASSWORD>` — pass the password directly on the command line
2. `--pfile <FILE>` — read the password from a file
3. `MY_RVAULT_PWD` environment variable — path to a password file
```bash
# inline password
rvault decrypt -i secrets.yaml --stdout --password mypassword
# password from file
rvault decrypt -i secrets.yaml --stdout --pfile ~/.vault_pass
# password from environment (recommended for scripts)
export MY_RVAULT_PWD=~/.vault_pass
rvault decrypt -i secrets.yaml --stdout
```
### Output target
For `encrypt`, `decrypt`, and `edit`, exactly one output option must be given:
| `-o <FILE>` | Write result to a new file |
| `--overwrite` | Replace the input file in-place |
| `--stdout` | Print result to standard output |
---
### encrypt
Encrypt scalar values inside a JSON or YAML file using Ansible Vault AES256.
```
[-k <KEY>]...
[--level <DEPTH>]
[--ansible]
```
**Encrypt all values** in a file:
```bash
rvault encrypt -i example.json -o encrypted.json --password secret
```
**Encrypt specific keys** using dot-notation paths:
```bash
# single key
rvault encrypt -i example.json -o encrypted.json --password secret -k first.a
# multiple keys (repeat the flag or use comma-separation)
rvault encrypt -i example.json -o encrypted.json --password secret \
-k first.a -k first.z
rvault encrypt -i example.json -o encrypted.json --password secret \
-k first.a,first.z
```
**Encrypt by nesting depth** with `--level` (cannot be combined with `--key`):
```bash
# encrypt all values at the top level (depth 1)
rvault encrypt -i example.json -o encrypted.json --password secret --level 1
# encrypt all values two levels deep
rvault encrypt -i example.yaml --overwrite --password secret --level 2
```
**Overwrite the file in-place:**
```bash
rvault encrypt -i secrets.yaml --overwrite --password secret
```
**Print to stdout** (useful for piping):
```bash
rvault encrypt -i example.json --stdout --password secret
```
---
### decrypt
Decrypt some or all encrypted values in a partially-encrypted file.
```
[-k <KEY>]...
[--value-only]
[--interactive]
```
**Decrypt all values:**
```bash
rvault decrypt -i encrypted.json -o plain.json --password secret
```
**Decrypt specific keys:**
```bash
rvault decrypt -i encrypted.json --stdout --password secret -k second.a.v
```
**Value-only mode** (`--value-only` / `-v`) — output only the selected key(s) as a minimal nested document (requires at least one `--key` or `--interactive`):
```bash
# prints just the nested sub-document for the selected keys
rvault decrypt -i encrypted.json --stdout --password secret \
-k second.a.v --value-only
```
**Interactive (fuzzy) mode** — opens an interactive prompt to select which encrypted keys to decrypt:
```bash
rvault decrypt -i encrypted.json --stdout --password secret --interactive
# combine with --value-only to output only the selected values
rvault decrypt -i encrypted.json --stdout --password secret \
--interactive --value-only
```
---
### edit
Decrypt a value, open it in `$EDITOR`, then re-encrypt and save.
```
[-k <KEY>]...
[-a | --interactive]
```
**Edit a specific key:**
```bash
rvault edit -i secrets.yaml --overwrite --password secret -k database.password
```
**Edit multiple keys:**
```bash
rvault edit -i secrets.yaml --overwrite --password secret \
-k database.password -k api.token
```
**Fuzzy-select which key to edit** (default when no `--key` is given):
```bash
rvault edit -i secrets.yaml --overwrite --password secret
```
**Edit all encrypted values without selection** (`-a`):
```bash
rvault edit -i secrets.yaml --overwrite --password secret -a
```
---
### clip
Fuzzy-search encrypted values and copy the decrypted result to the clipboard. The clipboard is automatically cleared after a timeout.
```
rvault clip -i <INPUT> --password <PASSWORD>
[--timeout <SECONDS>]
[--pfile <FILE>]
```
```bash
# default: clear clipboard after 30 seconds
rvault clip -i secrets.yaml --password secret
# keep clipboard for 60 seconds
rvault clip -i secrets.yaml --password secret --timeout 60
# never clear the clipboard automatically
rvault clip -i secrets.yaml --password secret --timeout 0
```
---
## File format
rvault works with plain JSON or YAML files. Encrypted values are stored inline as Ansible Vault strings:
```yaml
# example.yaml — mixed plain/encrypted YAML
first:
z: last
a: first
m: middle
second:
a:
v: true # plain boolean
w: 14 # plain integer
x: "$ANSIBLE_VAULT;1.1;AES256\n..." # encrypted string
```
```json
{
"first": {
"z": "last",
"a": "$ANSIBLE_VAULT;1.1;AES256\n...",
"m": "middle"
}
}
```
The original Rust type (bool, integer, float, string) is preserved across an encrypt→decrypt round-trip.
---
## Docker
```bash
# decrypt a file
docker run --rm -u $(id -u):$(id -g) \
-v /path/to/input:/input \
-v /path/to/output:/output \
docker.io/okieoth/rvault:latest decrypt \
-i /input/secrets.yaml -o /output/decrypted.yaml \
--password mypassword
# encrypt a file
docker run --rm -u $(id -u):$(id -g) \
-v /path/to/input:/input \
-v /path/to/output:/output \
docker.io/okieoth/rvault:latest encrypt \
-i /input/plain.yaml -o /output/secrets.yaml \
--password mypassword
```
---
## Build
```bash
# build binary
cargo build
# run tests
cargo test
# build docker image
make docker-build
```
---
# Additional
* Password for `resources/tests/partial.yaml`: `aa`
* Password for `resources/tests/partial_encrypted_example.json`: `test999`
* Password for `resources/tests/partial_encrypted_example.yaml`: `test999`