c5cli

Crates.ioc5cli
lib.rsc5cli
version1.1.1
created_at2025-05-17 00:11:18.061405+00
updated_at2025-09-04 05:09:11.665927+00
descriptionCommand-line interface for c5store secret management, enabling encryption, decryption, and key generation for YAML configurations.
homepagehttps://github.com/normano/c5store/tree/main/cli/c5cli
repositoryhttps://github.com/normano/c5store.git
max_upload_size
id1677550
size131,128
Norm O (normano)

documentation

README

c5cli - Command Line Interface for c5store Secret Management

c5cli is a command-line tool for managing secrets within YAML configuration files, designed to work with the c5store configuration library's secret format. It allows you to encrypt, decrypt, and generate cryptographic keys for securing sensitive data.

This tool leverages the c5_core library for its underlying cryptographic and YAML manipulation capabilities.

Features

  • Encrypt:
    • Encrypt string values or the content of files.
    • Store encrypted secrets in a structured YAML format (.c5encval arrays).
    • Re-encrypt existing secrets with new keys.
    • Dry-run mode to preview changes.
  • Decrypt:
    • Decrypt secrets stored in the c5store format from YAML files.
    • Output decrypted content to a file or stdout.
  • Generate Keys:
    • Generate ECIES X25519 key pairs (PEM format) for use with c5store secrets.
    • Generate Ed25519 SSH key pairs (private key in PKCS#8 PEM, public key in OpenSSH format).

Installation

Prerequisites

  • Rust programming language and Cargo (Rust's package manager). Install from rustup.rs.

Building from Source

  1. Clone this repository (or the parent repository containing c5cli):

    git clone <repository_url>
    cd <repository_name>/cli
    
  2. Build the c5cli tool:

    cargo build --release -p c5cli
    
  3. The executable will be located at target/release/c5cli. You can copy this to a directory in your PATH, e.g., /usr/local/bin.

    # Example:
    # cp target/release/c5cli /usr/local/bin/
    

Usage

c5cli provides several subcommands: encrypt, decrypt, and gen.

c5cli <COMMAND> --help

General Options

  • --config-root-dir <PATH>: Root directory for configuration files (default: config).
  • --public-key-dir <PATH>: Directory for public keys (for encrypt, default: config/public_keys).
  • --private-key-dir <PATH>: Directory for private keys (for decrypt, default: config/private_keys).
  • --secret-segment <SEGMENT>: The YAML key used to store the secret array (default: .c5encval).

1. Generating Key Pairs (gen)

Generate c5store ECIES Key Pair

Used for encrypting and decrypting c5store secrets.

c5cli gen kp [OPTIONS] [OUTPUT_NAME_PREFIX]
  • [OUTPUT_NAME_PREFIX]: Prefix for the output key files (default: c5key).
    • Public key: <prefix>.c5.pub.pem
    • Private key: <prefix>.c5.key.pem
  • --algo <ALGORITHM>: Cryptographic algorithm (default: ecies_x25519).
  • -d, --output-dir <PATH>: Directory to save the keys (default: current directory).
  • -y, --force: Overwrite existing key files.

Example:

# Generate keys in the current directory with default prefix "c5key"
c5cli gen kp

# Generate keys for "my_service" in the "keys/" directory
mkdir -p keys
c5cli gen kp my_service --output-dir keys

Generate SSH Ed25519 Key Pair

c5cli gen ssh [OPTIONS] [OUTPUT_NAME_PREFIX]
  • [OUTPUT_NAME_PREFIX]: Prefix for the output key files (default: id_ed25519).
    • Private key: <prefix>
    • Public key: <prefix>.pub
  • --algo <ALGORITHM>: SSH key algorithm (default: ed25519).
  • -d, --output-dir <PATH>: Directory to save the keys (default: current directory).
  • -C, --comment <COMMENT>: Add a comment to the public key.
  • --no-save-private-key: Print public key to stdout and do not save the private key.
  • -y, --force: Overwrite existing key files.

Example:

# Generate SSH keys in "./ssh_keys" with a comment
mkdir -p ssh_keys
c5cli gen ssh my_ssh_key --output-dir ssh_keys -C "user@example.com"

2. Encrypting Secrets (encrypt)

Encrypts a value or file content and prepares it for inclusion in a YAML configuration file. By default, it performs a dry run. Use --commit to write changes.

c5cli encrypt [OPTIONS] <CONFIG_FILE_NAME> <PUBLIC_KEY_FILE_NAME> <KEY_PATH>
  • <CONFIG_FILE_NAME>: Name of the YAML config file (e.g., app.yaml). Searched in --config-root-dir.
  • <PUBLIC_KEY_FILE_NAME>: Name of the public key PEM file (e.g., service_a.c5.pub.pem). Searched in --public-key-dir.
  • <KEY_PATH>: Dot-separated path within the YAML where the secret should be stored (e.g., database.password).

Input Options (choose one):

  • -v, --value <PLAINTEXT_VALUE>: The string value to encrypt.
  • -f, --file <INPUT_FILE_PATH>: Path to a file whose content will be encrypted.
    • --encoding <ENCODING>: Encoding of the input file if it's text (default: utf8). For binary files, encoding is usually ignored.
  • --reencrypt: Re-encrypt an existing secret at <KEY_PATH>. Requires --old-private-key-file.
    • --old-private-key-file <OLD_PRIVATE_KEY_FILE>: Path to the old private key needed to decrypt the existing secret.

Output Options:

  • --commit: Actually write the changes to the <CONFIG_FILE_NAME> or --output-file.
  • --output-file <OUTPUT_FILE_PATH>: (Requires --commit) Write the modified YAML to a different file instead of in-place.

Example: Encrypting a password (dry run)

# Assuming config/app.yaml and config/public_keys/my_service.c5.pub.pem exist
c5cli encrypt app.yaml my_service.c5.pub.pem api.credentials.token -v "s3cr3tV@lu3"

Example: Encrypting a file and committing to a new output file

echo "sensitive file content" > /tmp/secret.txt
c5cli encrypt base_config.yaml service_key.c5.pub.pem certs.private_content \
    -f /tmp/secret.txt \
    --commit \
    --output-file config/production.yaml

3. Decrypting Secrets (decrypt)

Decrypts a secret from a YAML configuration file.

c5cli decrypt [OPTIONS] <CONFIG_FILE_NAME> <KEY_PATH> <PRIVATE_KEY_FILE_NAME> [OUTPUT_FILE_PATH]
  • <CONFIG_FILE_NAME>: Name of the YAML config file.
  • <KEY_PATH>: Dot-separated path within the YAML where the secret is stored.
  • <PRIVATE_KEY_FILE_NAME>: Name of the private key PEM file.
  • [OUTPUT_FILE_PATH]: Path to save the decrypted content. Required unless --to-stdout is used.

Output Options:

  • --to-stdout: Print decrypted content to standard output instead of a file.
  • -y, --force: (Requires OUTPUT_FILE_PATH) Overwrite the output file if it exists.
  • --output-encoding <ENCODING>: When using --to-stdout, attempt to interpret decrypted bytes using this encoding (default: utf8). If not valid UTF-8, raw bytes may be hinted.

Example: Decrypting a token to stdout

# Assuming config/app.yaml and config/private_keys/my_service.c5.key.pem exist
c5cli decrypt app.yaml api.credentials.token my_service.c5.key.pem --to-stdout

Example: Decrypting a secret to a file

c5cli decrypt app.yaml certs.private_content service_key.c5.key.pem /tmp/decrypted_cert.txt -y

Configuration Secret Format

c5cli (and c5store) expect secrets to be stored in YAML as an array under a specific key (default .c5encval):

some_service:
  api_key:
    ".c5encval": # This is the secret_segment
      - "ecies_x25519"                     # Algorithm
      - "my_key_name"                      # Key name (derived from public key filename)
      - "Base64EncodedCiphertextGoesHere=" # Ciphertext

Development

(Instructions for developers contributing to c5cli)

  1. Ensure Rust is installed.
  2. Navigate to the cli directory within the project.
  3. Run tests:
    cargo test -p c5cli
    cargo test -p c5_core
    
  4. Build debug version:
    cargo build -p c5cli
    
    Executable: target/debug/c5cli

License

This project is licensed under the Mozilla Public License Version 2.0 (MPL-2.0).

Commit count: 0

cargo fmt