oth_rvault 0.3.0

Partial Ansible Vault encoder and decoder
Documentation

crates.io Docker Hub

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

# 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
# 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:

Flag Behaviour
-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.

rvault encrypt -i <INPUT> (-o <OUTPUT> | --overwrite | --stdout)
               --password <PASSWORD>
               [-k <KEY>]...
               [--level <DEPTH>]
               [--ansible]

Encrypt all values in a file:

rvault encrypt -i example.json -o encrypted.json --password secret

Encrypt specific keys using dot-notation paths:

# 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):

# 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:

rvault encrypt -i secrets.yaml --overwrite --password secret

Print to stdout (useful for piping):

rvault encrypt -i example.json --stdout --password secret

decrypt

Decrypt some or all encrypted values in a partially-encrypted file.

rvault decrypt -i <INPUT> (-o <OUTPUT> | --overwrite | --stdout)
               --password <PASSWORD>
               [-k <KEY>]...
               [--value-only]
               [--interactive]

Decrypt all values:

rvault decrypt -i encrypted.json -o plain.json --password secret

Decrypt specific keys:

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):

# 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:

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.

rvault edit -i <INPUT> (-o <OUTPUT> | --overwrite | --stdout)
            --password <PASSWORD>
            [-k <KEY>]...
            [-a | --interactive]

Edit a specific key:

rvault edit -i secrets.yaml --overwrite --password secret -k database.password

Edit multiple keys:

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):

rvault edit -i secrets.yaml --overwrite --password secret

Edit all encrypted values without selection (-a):

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>]
# 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:

# 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
{
  "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

# 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

# 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