Skip to main content

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

CI Pipeline

Every push to main and every pull request runs automatically via shared-workflows:

Job What it checks
Test pytest on Python 3.8 / 3.10 / 3.12 x Ubuntu + Windows (runs after lint and typecheck pass)
Lint ruff check + ruff format --check
Type Check mypy src/
Audit pip-audit — all dependencies scanned for known CVEs
Coverage pytest-cov — report posted to the Actions job summary

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)

Metadata

Release files for credential-bridge 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for credential-bridge 0.4.1
File Size Uploaded
credential_bridge-0.4.1.tar.gz 1.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for credential-bridge 0.4.1
File Interpreter ABI Platform
credential_bridge-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / credential_bridge-0.4.1.tar.gz

Download URL credential_bridge-0.4.1.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
aacae88c4172e602cdf6d9cc03161c6ddbd152eeacefce0dd20066fb6fef3f31
BLAKE2b-256 checksum
How to use checksums
cadaac7c29dc10f511c3eb3dfe3b4e5b13a3e6b7058a1b5e539362e04ccc095b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / credential_bridge-0.4.1-py3-none-any.whl

Download URL credential_bridge-0.4.1-py3-none-any.whl
Size 36.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b57bb1ec90060b7f2ac201c03d43861d4f06a5397437e4841b1ecbf52134d1ea
BLAKE2b-256 checksum
How to use checksums
70c173c113668111b32c279be925ca1b32335d12504f35aabba993e536976e19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page