I'm thrilled to announce the release of c5cli
version 1.1.1, a significant update that brings a major improvement to how you interact with your configuration files. This release is all about ergonomics and power, directly addressing feedback to make encrypting and decrypting secrets more intuitive and flexible, especially in complex, real-world configurations.
The star of the show? A brand new, expressive path syntax for the encrypt
and decrypt
commands.
Let's dive in.
The Old Way: Simple, But Limited
Until now, c5cli
only understood simple dot-notation paths, like database.user.password
. This worked great for simple, nested objects (what YAML calls "mappings"), but it hit a wall when you needed to target a value inside an array (a "sequence").
Consider this common configuration pattern:
# config.yaml
users:
- name: "alice"
role: "admin"
token: "plaintext_token_for_alice" # <-- How do we encrypt this?
- name: "bob"
role: "editor"
token: "plaintext_token_for_bob"
Previously, there was no straightforward way to tell c5cli
: "Go into the users
array, find the first element, and encrypt the token
." You had to resort to manual workarounds, which was clumsy and error-prone.
The New Way: Precise, Powerful, and Intuitive
With c5cli
v1.1.1, this is now trivially easy. We've introduced a new path parser that understands two powerful new constructs: array indexing and key-value querying.
1. Array Indexing with [index]
You can now directly target elements in an array by their zero-based index. To encrypt Alice's token in the example above, the command is exactly what you'd expect:
# Encrypt the token for the first user in the array (index 0)
$ c5cli encrypt config.yaml my_key.pub.pem "users[0].token" \
-v "a_super_secret_token_for_alice" --commit
# Resulting config.yaml:
# users:
# - name: "alice"
# role: "admin"
# token:
# .c5encval:
# - ecies_x25519
# - my_key.c5
# - "..."
# - name: "bob"
# role: "editor"
# token: "plaintext_token_for_bob"
Simple. Clean. Done.
2. Key-Value Querying with [key="value"]
This is where things get really exciting. What if you don't know (or don't want to rely on) the position of an element in an array? What if you want to find an object based on its properties?
Now you can. The new syntax allows you to find a unique object in an array by matching a key-value pair.
Let's encrypt Bob's token by finding him by his name
:
# Find the object in the 'users' array where name is "bob" and encrypt its token
$ c5cli encrypt config.yaml my_key.pub.pem 'users[name="bob"].token' \
-v "bobs_secure_token_456" --commit
# Resulting config.yaml:
# users:
# - name: "alice"
# ...
# - name: "bob"
# role: "editor"
# token:
# .c5encval: # <-- Bob's token is now encrypted!
# - ecies_x25519
# - my_key.c5
# - "..."
This is incredibly powerful for automation and scripting. You no longer need to hardcode array positions, making your secret management workflows more robust and less likely to break if the order of array elements changes.
A Note on Safety: The query syntax is designed to be safe. For a sensitive operation like encrypt
, the query must match exactly one element. If it finds zero matches or multiple matches, c5cli
will exit with an error, preventing you from accidentally modifying the wrong secret or failing silently.
Putting It All Together
Of course, all these syntax forms can be combined. For a deeply nested structure like this:
# auth.yaml
auth:
providers:
- name: "primary_ldap"
credentials:
- type: "password"
value: "plaintext_password" # <-- Let's target this!
The command is a beautiful, readable combination of all the path types:
# Find provider 'primary_ldap', then find the credential with type 'password'
$ c5cli encrypt auth.yaml auth_key.pub.pem 'auth.providers[name="primary_ldap"].credentials[type="password"].value' \
-v "the_real_deal_password" --commit
Under the Hood
This was made possible by replacing the simple path splitter in c5cli
with a proper, stateful tokenizer built with regular expressions. This new parser produces a structured sequence of navigation steps—Key
, Index
, or Query
—that allows the tool to safely traverse and modify complex YAML documents.
It's a perfect example of how real-world use cases drive a tool's evolution.
Get the Update!
These improvements, along with more helpful and detailed command-line help text, are available now in c5cli
v1.1.1. You can update using cargo:
$ cargo install c5cli --force
I'm really excited about how much easier this will make managing secrets in complex configurations. Give it a try and let me know what you think! You can find the project on GitHub and the crate on crates.io.