{"id":50371391,"url":"https://github.com/ihassan8/credential-bridge","last_synced_at":"2026-05-30T07:03:25.546Z","repository":{"id":355390239,"uuid":"1227747121","full_name":"ihassan8/credential-bridge","owner":"ihassan8","description":"A unified Python library for secrets management across HashiCorp Vault, the OS system keyring, and .env files","archived":false,"fork":false,"pushed_at":"2026-05-30T03:34:53.000Z","size":1348,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T05:12:53.381Z","etag":null,"topics":["env","hashicorp-vault","keyring","python","secrets"],"latest_commit_sha":null,"homepage":"https://ihassan8.github.io/credential-bridge/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ihassan8.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T05:31:48.000Z","updated_at":"2026-05-30T03:34:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ihassan8/credential-bridge","commit_stats":null,"previous_names":["vertex-ai-automations/credential-bridge","ihassan8/credential-bridge"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/ihassan8/credential-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihassan8%2Fcredential-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihassan8%2Fcredential-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihassan8%2Fcredential-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihassan8%2Fcredential-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ihassan8","download_url":"https://codeload.github.com/ihassan8/credential-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ihassan8%2Fcredential-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33682998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["env","hashicorp-vault","keyring","python","secrets"],"created_at":"2026-05-30T07:03:24.740Z","updated_at":"2026-05-30T07:03:25.538Z","avatar_url":"https://github.com/ihassan8.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://github.com/ihassan8/credential-bridge/raw/main/docs/img/credential_bridge.png\" alt=\"Credential Bridge Logo\" width=\"420\"\u003e\n\n\u003cbr/\u003e\n\n[![PyPI version](https://img.shields.io/pypi/v/credential-bridge?color=indigo\u0026logo=pypi\u0026logoColor=white)](https://pypi.org/project/credential-bridge/)\n[![Python versions](https://img.shields.io/pypi/pyversions/credential-bridge?color=indigo\u0026logo=python\u0026logoColor=white)](https://pypi.org/project/credential-bridge/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-indigo.svg)](https://github.com/ihassan8/credential-bridge/blob/main/LICENSE.txt)\n[![CI](https://img.shields.io/github/actions/workflow/status/ihassan8/credential-bridge/ci.yml?branch=main\u0026label=CI\u0026logo=github)](https://github.com/ihassan8/credential-bridge/actions/workflows/ci.yml)\n\n\u003cbr/\u003e\n\n\u003cp\u003e\n\u003ca href=\"https://ihassan8.github.io/credential-bridge\"\u003e\u003cstrong\u003eDocumentation\u003c/strong\u003e\u003c/a\u003e\n\u0026nbsp;·\u0026nbsp;\n\u003ca href=\"https://github.com/ihassan8/credential-bridge/issues/new\"\u003eReport Bug\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/div\u003e\n\n# credential-bridge\n\nA unified Python library for secrets management across HashiCorp Vault, the OS system keyring, and `.env` files.\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [CLI Usage](#cli-usage)\n- [Backends](#backends)\n- [Custom Backends](#custom-backends)\n- [Error Handling](#error-handling)\n- [Environment Variables](#environment-variables)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n## Features\n\n- **Three backends**: HashiCorp Vault (KV-v2), OS system keyring, and `.env` files\n- **`SecretsManager` facade**: switch backends without changing application code\n- **Plugin architecture**: register third-party backends with one call\n- **Typed exceptions**: granular hierarchy rooted at `CredentialBridgeError`\n- **Typer + Rich CLI**: `cb`, `vault-cli`, `keyring-cli`, `env-cli`, and `run-wizard` entry points\n- **Cross-platform**: works on Linux, macOS, and Windows\n\n---\n\n## Installation\n\n```bash\npip install credential-bridge\n\n# With dev dependencies\npip install \"credential-bridge[dev]\"\n```\n\n---\n\n## Quick Start\n\n### Using SecretsManager\n\n```python\nfrom credential_bridge import SecretsManager\n\n# HashiCorp Vault (set VAULT_ADDR env var first)\nsm = SecretsManager(\"vault\", vault_token=\"s.xxx\")\nsm.add_secret(\"myapp/database\", {\"user\": \"admin\", \"pass\": \"s3cr3t\"})\nsecret = sm.get_secret(\"myapp/database\")\n\n# System keyring\nsm = SecretsManager(\"keyring\", service_name=\"myapp\")\nsm.add_secret(\"api_key\", {\"api_key\": \"sk-abc123\"})\n\n# .env file\nsm = SecretsManager(\"env\", path=\".env\")\nsm.add_secret(\"DATABASE\", {\"DB_HOST\": \"localhost\", \"DB_PORT\": \"5432\"})\n```\n\n### Using backends directly\n\n```python\nfrom credential_bridge import VaultBackend, KeyringBackend, EnvFileBackend\n\n# Vault with AppRole auth\nvault = VaultBackend(\n    vault_url=\"https://vault.example.com\",\n    vault_role_id=\"\u003crole-id\u003e\",\n    vault_secret_id=\"\u003csecret-id\u003e\",\n)\nvault.add_secret(\"myapp/db\", {\"password\": \"hunter2\"})\n\n# Keyring\nkr = KeyringBackend(service_name=\"myapp\")\nkr.add_secret(\"token\", {\"value\": \"sk-abc123\"})\n\n# .env file\nenv = EnvFileBackend(path=\".env\")\nenv.add_secret(\"DATABASE\", {\"DB_HOST\": \"localhost\", \"DB_PORT\": \"5432\"})\n```\n\n---\n\n## CLI Usage\n\n```bash\n# Show all commands\ncb --help\n\n# Vault\ncb vault add myapp/db --secret user=admin --secret pass=s3cr3t\ncb vault get myapp/db\ncb vault list\ncb vault delete myapp/db\n\n# Keyring\ncb keyring add api_key --secret api_key=sk-abc123 --service-name myapp\ncb keyring get api_key --service-name myapp\ncb keyring delete api_key --service-name myapp\n\n# .env file\ncb env add DATABASE --secret DB_HOST=localhost --secret DB_PORT=5432\ncb env get DB_HOST\ncb env list\ncb env delete DB_HOST\n\n# Interactive wizard\ncb wizard\n```\n\n---\n\n## Backends\n\n| Backend | Best use case |\n|---------|---------------|\n| **Vault** | Production workloads requiring audit logs, dynamic secrets, fine-grained policies, and centralized governance |\n| **Keyring** | Developer machines and CI environments where OS-level credential storage is available |\n| **.env file** | Local development, Docker Compose setups, and twelve-factor apps that read config from the environment |\n\n---\n\n## Custom Backends\n\nImplement `BaseSecretBackend` and register it with `SecretsManager`:\n\n```python\nfrom credential_bridge import BaseSecretBackend, SecretsManager\nfrom credential_bridge.manager import register_backend\nfrom typing import Any, Dict, List\n\nclass RedisBackend(BaseSecretBackend):\n    backend_name = \"redis\"  # required — omitting raises TypeError\n\n    def add_secret(self, name: str, secret: Dict[str, Any]) -\u003e None: ...\n    def get_secret(self, name: str) -\u003e Dict[str, Any]: ...\n    def update_secret(self, name: str, secret: Dict[str, Any]) -\u003e None: ...\n    def delete_secret(self, name: str) -\u003e None: ...\n    def list_secrets(self, path: str = \"\") -\u003e List[str]: ...\n\nregister_backend(\"redis\", RedisBackend)\n\nsm = SecretsManager(\"redis\", host=\"localhost\", port=6379)\n```\n\n---\n\n## Error Handling\n\nAll exceptions inherit from `CredentialBridgeError`:\n\n```\nCredentialBridgeError\n├── BackendError\n│   ├── VaultError\n│   │   ├── VaultAuthError          — bad token / AppRole credentials\n│   │   ├── VaultConnectionError    — unreachable server\n│   │   └── VaultSecretNotFoundError — secret path does not exist\n│   ├── KeyringError\n│   └── EnvFileError\n│       ├── EnvFileNotFoundError    — key not found\n│       └── EnvFileKeyExistsError   — add_secret called on existing key\n├── BackendNotRegisteredError\n└── ConfigurationError\n```\n\n```python\nfrom credential_bridge import (\n    SecretsManager,\n    VaultAuthError,\n    VaultConnectionError,\n    VaultSecretNotFoundError,\n    CredentialBridgeError,\n)\n\nsm = SecretsManager(\"vault\", vault_token=\"s.xxx\")\n\ntry:\n    secret = sm.get_secret(\"myapp/database\")\nexcept VaultSecretNotFoundError:\n    print(\"Secret path does not exist\")\nexcept VaultAuthError:\n    print(\"Authentication failed — check your token or AppRole credentials\")\nexcept VaultConnectionError:\n    print(\"Could not reach Vault — check VAULT_ADDR\")\nexcept CredentialBridgeError as exc:\n    print(f\"Unexpected error: {exc}\")\n```\n\n---\n\n## Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `VAULT_ADDR` | Vault server URL (e.g. `https://vault.example.com`) |\n| `VAULT_TOKEN` | Token for Token auth method |\n| `VAULT_ROLE_ID` | Role ID for AppRole auth method |\n| `VAULT_SECRET_ID` | Secret ID for AppRole auth method |\n\nResolution order for `VaultBackend`: constructor argument → environment variable → `~/.vault_config.json`.\n\n---\n\n## Development\n\n```bash\n# Install in editable mode with dev dependencies\npip install -e \".[dev]\"\n\n# Run unit tests\npytest tests/unit/\n\n# Run integration tests (requires external services)\npytest tests/integration/ -m integration\n\n# Lint\nruff check src/\n\n# Type check\nmypy src/\n\n# Serve docs locally\nmkdocs serve\n```\n\n\n### CI Pipeline\n\nEvery push to `main` and every pull request runs automatically via [shared-workflows](https://github.com/ihassan8/shared-workflows):\n\n| Job | What it checks |\n|-----|----------------|\n| **Test** | pytest on Python 3.8 / 3.10 / 3.12 x Ubuntu + Windows (runs after lint and typecheck pass) |\n| **Lint** | `ruff check` + `ruff format --check` |\n| **Type Check** | `mypy src/` |\n| **Audit** | `pip-audit` — all dependencies scanned for known CVEs |\n| **Coverage** | `pytest-cov` — report posted to the Actions job summary |\n---\n\n## Contributing\n\nAll contributions are welcome! Fork the repo, make your changes, and open a pull request. You can also open an issue with the label `enhancement`.\n\n[View all contributors](https://github.com/ihassan8/credential-bridge/graphs/contributors)\n\n---\n\n## License\n\nMIT — see [LICENSE.txt](LICENSE.txt) for details.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fihassan8%2Fcredential-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fihassan8%2Fcredential-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fihassan8%2Fcredential-bridge/lists"}