Skip to main content

A Python library for unified secrets management across HashiCorp Vault, system keyring, and .env files.

Project description

credential-bridge

A unified Python library for secrets management across HashiCorp Vault, the OS system keyring, and .env files.


Table of Contents


Features

  • Three backends: HashiCorp Vault (KV-v2), OS system keyring, and .env files
  • SecretsManager facade: switch backends without changing application code
  • Plugin architecture: register third-party backends with one call
  • Typed exceptions: granular hierarchy rooted at CredentialBridgeError
  • Typer + Rich CLI: cb, vault-cli, keyring-cli, env-cli, and run-wizard entry points
  • Cross-platform: works on Linux, macOS, and Windows

Installation

pip install credential-bridge

# With dev dependencies
pip install "credential-bridge[dev]"

Quick Start

Using SecretsManager

from credential_bridge import SecretsManager

# HashiCorp Vault (set VAULT_ADDR env var first)
sm = SecretsManager("vault", vault_token="s.xxx")
sm.add_secret("myapp/database", {"user": "admin", "pass": "s3cr3t"})
secret = sm.get_secret("myapp/database")

# System keyring
sm = SecretsManager("keyring", service_name="myapp")
sm.add_secret("api_key", {"api_key": "sk-abc123"})

# .env file
sm = SecretsManager("env", path=".env")
sm.add_secret("DATABASE", {"DB_HOST": "localhost", "DB_PORT": "5432"})

Using backends directly

from credential_bridge import VaultBackend, KeyringBackend, EnvFileBackend

# Vault with AppRole auth
vault = VaultBackend(
    vault_url="https://vault.example.com",
    vault_role_id="<role-id>",
    vault_secret_id="<secret-id>",
)
vault.add_secret("myapp/db", {"password": "hunter2"})

# Keyring
kr = KeyringBackend(service_name="myapp")
kr.add_secret("token", {"value": "sk-abc123"})

# .env file
env = EnvFileBackend(path=".env")
env.add_secret("DATABASE", {"DB_HOST": "localhost", "DB_PORT": "5432"})

CLI Usage

# Show all commands
cb --help

# Vault
cb vault add myapp/db --secret user=admin --secret pass=s3cr3t
cb vault get myapp/db
cb vault list
cb vault delete myapp/db

# Keyring
cb keyring add api_key --secret api_key=sk-abc123 --service-name myapp
cb keyring get api_key --service-name myapp
cb keyring delete api_key --service-name myapp

# .env file
cb env add DATABASE --secret DB_HOST=localhost --secret DB_PORT=5432
cb env get DB_HOST
cb env list
cb env delete DB_HOST

# Interactive wizard
cb wizard

Backends

Backend Best use case
Vault Production workloads requiring audit logs, dynamic secrets, fine-grained policies, and centralized governance
Keyring Developer machines and CI environments where OS-level credential storage is available
.env file Local development, Docker Compose setups, and twelve-factor apps that read config from the environment

Custom Backends

Implement BaseSecretBackend and register it with SecretsManager:

from credential_bridge import BaseSecretBackend, SecretsManager
from credential_bridge.manager import register_backend
from typing import Any, Dict, List

class RedisBackend(BaseSecretBackend):
    backend_name = "redis"  # required — omitting raises TypeError

    def add_secret(self, name: str, secret: Dict[str, Any]) -> None: ...
    def get_secret(self, name: str) -> Dict[str, Any]: ...
    def update_secret(self, name: str, secret: Dict[str, Any]) -> None: ...
    def delete_secret(self, name: str) -> None: ...
    def list_secrets(self, path: str = "") -> List[str]: ...

register_backend("redis", RedisBackend)

sm = SecretsManager("redis", host="localhost", port=6379)

Error Handling

All exceptions inherit from CredentialBridgeError:

CredentialBridgeError
├── BackendError
│   ├── VaultError
│   │   ├── VaultAuthError          — bad token / AppRole credentials
│   │   ├── VaultConnectionError    — unreachable server
│   │   └── VaultSecretNotFoundError — secret path does not exist
│   ├── KeyringError
│   └── EnvFileError
│       ├── EnvFileNotFoundError    — key not found
│       └── EnvFileKeyExistsError   — add_secret called on existing key
├── BackendNotRegisteredError
└── ConfigurationError
from credential_bridge import (
    SecretsManager,
    VaultAuthError,
    VaultConnectionError,
    VaultSecretNotFoundError,
    CredentialBridgeError,
)

sm = SecretsManager("vault", vault_token="s.xxx")

try:
    secret = sm.get_secret("myapp/database")
except VaultSecretNotFoundError:
    print("Secret path does not exist")
except VaultAuthError:
    print("Authentication failed — check your token or AppRole credentials")
except VaultConnectionError:
    print("Could not reach Vault — check VAULT_ADDR")
except CredentialBridgeError as exc:
    print(f"Unexpected error: {exc}")

Environment Variables

Variable Description
VAULT_ADDR Vault server URL (e.g. https://vault.example.com)
VAULT_TOKEN Token for Token auth method
VAULT_ROLE_ID Role ID for AppRole auth method
VAULT_SECRET_ID Secret ID for AppRole auth method

Resolution order for VaultBackend: constructor argument → environment variable → ~/.vault_config.json.


Development

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# Run unit tests
pytest tests/unit/

# Run integration tests (requires external services)
pytest tests/integration/ -m integration

# Lint
ruff check src/

# Type check
mypy src/

# Serve docs locally
mkdocs serve

Contributing

All contributions are welcome! Fork the repo, make your changes, and open a pull request. You can also open an issue with the label enhancement.

View all contributors


License

MIT — see LICENSE.txt for details.

(back to top)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

credential_bridge-0.2.5.tar.gz (1.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

credential_bridge-0.2.5-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file credential_bridge-0.2.5.tar.gz.

File metadata

  • Download URL: credential_bridge-0.2.5.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for credential_bridge-0.2.5.tar.gz
Algorithm Hash digest
SHA256 2deb39e12bf909f1fea25c317c11f4b5d3194cd4855457c33e6cf7479eea3fcc
MD5 6d1aee5bc25e454f70381c6faadc288e
BLAKE2b-256 b525382136002fc28374a7adf45ea85580eb7b4b2e009c61f2ee0fb84710f47d

See more details on using hashes here.

File details

Details for the file credential_bridge-0.2.5-py3-none-any.whl.

File metadata

File hashes

Hashes for credential_bridge-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 fcf029ad167bd942143b513006b0499571d1e6a248fe9e653a6821238ed9a600
MD5 d42966d09a267891a39cb8c4a826a4f5
BLAKE2b-256 377b233b82bf39ae3c6b1de6a76e24ba5f8c04673372bfc9d16d3d2b749a2329

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page