secretsmith: a Python helper for Vault and OpenBao

After building numerous applications that needed to connect to HashiCorp Vault or OpenBao, I found myself copying the same configuration parsing and client connection code over and over again.

The Python hvac library is powerful but verbose for common operations, especially when dealing with KV2 secrets engines.

Today, I’m excited to announce secretsmith – a clean, opinionated Python wrapper that eliminates this repetition and lets applications shift connection setup from code to configuration files.

The problem

Every time I needed to integrate a Python application with Vault, I’d end up writing variations of the same code:

  • Parsing configuration files to extract Vault connection details
  • Handling different authentication methods: tokens, AppRole, etc.
  • Managing misc connection properties like TLS verification, namespaces
  • Writing helper functions to simplify KV2 secret retrieval

This became particularly painful in the Nasqueron infrastructure where we use Salt to provision consistent configuration files across services. Each application would implement its own configuration parser, leading to inconsistencies and maintenance overhead.

The Solution

Secretsmith provides a clean, standardized way to connect to Vault from configuration files and retrieve secrets with minimal boilerplate.

Simple Configuration-Based Authentication

Instead of scattered connection logic, secretsmith reads from a standard configuration format:

vault:
  server:
    url: https://vault.domain.tld
    verify: /path/to/ca.crt
    namespace: my-namespace
  auth:
    method: approle
    role_id: your-role-id
    secret_id: your-secret-id

Then connect with a single line:

from secretsmith.vault.client import login

client = login("/path/to/config.yaml")

Streamlined Secret Operations

The hvac library requires verbose nested calls for simple KV2 operations. Secretsmith provides clean helpers:

from secretsmith.vault.secrets import read_secret, get_username, get_password

# Read entire secret k/v
data = read_secret(client, "secret", "myapp/database")

# Or get specific fields directly
username = get_username(client, "secret", "myapp/database")
password = get_password(client, "secret", "myapp/database")

# Custom field retrieval
api_key = get_field(client, "secret", "myapp/api", "key")

Of couse, you can directly hvac too, those helpers are provided as sugar syntax.

Metadata Support

Need to work with secret metadata? Secretsmith has you covered:

from secretsmith.vault.secrets import read_secret_with_metadata, read_secret_with_custom_metadata

# Get data and metadata separately
data, metadata = read_secret_with_metadata(client, "secret", "myapp/database")

# Automatically merge custom metadata into the main metadata dict
data, metadata = read_secret_with_custom_metadata(client, "secret", "myapp/database")

Real-World Integration

In our Salt-managed infrastructure, we can now provision identical configuration files across all services:

vault:
  server:
    url: {{ vault.addr }}
    verify: /usr/local/share/certs/nasqueron-vault-ca.crt
  auth:
    method: approle
    role_id: {{ vault.approle.role_id }}
    secret_id: {{ vault.approle.secret_id }}

Each application just needs:

from secretsmith.vault.client import login

client = login("/usr/local/etc/secrets/someservice.conf")

This consistency has eliminated configuration drift and made our Vault integrations much more maintainable.

Getting started

I’m happy to share that secretsmith is now published on PyPI.

To install secretsmith with pip:

pip install secretsmith

What’s next?

For now, secretsmith focuses on the basics: login and kv2 reads. Future versions might expand to other back-ends and write operations if there’s demand.

Feedback and contributions are very welcome! You can find the source code and issue tracker in the links below.

Conclusion

Secretsmith represents the kind of tool that emerges from real-world usage patterns — it solves a specific problem we encountered repeatedly and does so with minimal complexity. If you’re working with Vault in Python and find yourself writing similar configuration and helper code across projects, give secretsmith a try.

The goal is simple: make Vault integration so straightforward that you can focus on your application logic instead of wrestling with connection details and verbose API calls.

Happy secret managing!


Links

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.