credential-bridge 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- credential_bridge-0.1.0/.github/workflows/publish-zensical.yml +123 -0
- credential_bridge-0.1.0/.github/workflows/release.yml +116 -0
- credential_bridge-0.1.0/.gitignore +97 -0
- credential_bridge-0.1.0/CLAUDE.md +89 -0
- credential_bridge-0.1.0/LICENSE.txt +21 -0
- credential_bridge-0.1.0/PKG-INFO +316 -0
- credential_bridge-0.1.0/README.md +270 -0
- credential_bridge-0.1.0/docs/backends/comparison.md +55 -0
- credential_bridge-0.1.0/docs/backends/env-file.md +275 -0
- credential_bridge-0.1.0/docs/backends/keyring.md +195 -0
- credential_bridge-0.1.0/docs/backends/vault.md +313 -0
- credential_bridge-0.1.0/docs/cli/cb.md +66 -0
- credential_bridge-0.1.0/docs/cli/env.md +262 -0
- credential_bridge-0.1.0/docs/cli/keyring.md +187 -0
- credential_bridge-0.1.0/docs/cli/vault.md +310 -0
- credential_bridge-0.1.0/docs/css/extra.css +120 -0
- credential_bridge-0.1.0/docs/getting-started/installation.md +76 -0
- credential_bridge-0.1.0/docs/getting-started/quickstart.md +130 -0
- credential_bridge-0.1.0/docs/img/credential_bridge.png +0 -0
- credential_bridge-0.1.0/docs/img/credential_bridge_192x192.png +0 -0
- credential_bridge-0.1.0/docs/img/favicon/favicon.ico +0 -0
- credential_bridge-0.1.0/docs/index.md +69 -0
- credential_bridge-0.1.0/docs/js/extra.js +95 -0
- credential_bridge-0.1.0/docs/overrides/PLACEHOLDER +0 -0
- credential_bridge-0.1.0/docs/reference/base.md +3 -0
- credential_bridge-0.1.0/docs/reference/env_file_backend.md +3 -0
- credential_bridge-0.1.0/docs/reference/exceptions.md +110 -0
- credential_bridge-0.1.0/docs/reference/keyring_backend.md +3 -0
- credential_bridge-0.1.0/docs/reference/secrets_manager.md +3 -0
- credential_bridge-0.1.0/docs/reference/vault_backend.md +3 -0
- credential_bridge-0.1.0/docs/secrets-manager.md +126 -0
- credential_bridge-0.1.0/docs/wizard.md +128 -0
- credential_bridge-0.1.0/mkdocs.yml +234 -0
- credential_bridge-0.1.0/pyproject.toml +78 -0
- credential_bridge-0.1.0/requirements-dev.txt +4 -0
- credential_bridge-0.1.0/requirements-docs.txt +7 -0
- credential_bridge-0.1.0/requirements.txt +7 -0
- credential_bridge-0.1.0/setup.cfg +4 -0
- credential_bridge-0.1.0/src/credential_bridge/__init__.py +45 -0
- credential_bridge-0.1.0/src/credential_bridge/__main__.py +3 -0
- credential_bridge-0.1.0/src/credential_bridge/_version.py +24 -0
- credential_bridge-0.1.0/src/credential_bridge/backends/__init__.py +7 -0
- credential_bridge-0.1.0/src/credential_bridge/backends/base.py +53 -0
- credential_bridge-0.1.0/src/credential_bridge/backends/env_file.py +120 -0
- credential_bridge-0.1.0/src/credential_bridge/backends/keyring.py +95 -0
- credential_bridge-0.1.0/src/credential_bridge/backends/vault.py +315 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/__init__.py +0 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/__main__.py +3 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/_output.py +60 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/env_cli.py +137 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/keyring_cli.py +118 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/main.py +51 -0
- credential_bridge-0.1.0/src/credential_bridge/cli/vault_cli.py +189 -0
- credential_bridge-0.1.0/src/credential_bridge/exceptions.py +49 -0
- credential_bridge-0.1.0/src/credential_bridge/manager.py +53 -0
- credential_bridge-0.1.0/src/credential_bridge/prompt_wizard.py +556 -0
- credential_bridge-0.1.0/src/credential_bridge/py.typed +0 -0
- credential_bridge-0.1.0/src/credential_bridge/utils.py +95 -0
- credential_bridge-0.1.0/src/credential_bridge/welcome_banner.txt +8 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/PKG-INFO +316 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/SOURCES.txt +82 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/dependency_links.txt +1 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/entry_points.txt +6 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/requires.txt +18 -0
- credential_bridge-0.1.0/src/credential_bridge.egg-info/top_level.txt +1 -0
- credential_bridge-0.1.0/tests/__init__.py +0 -0
- credential_bridge-0.1.0/tests/conftest.py +26 -0
- credential_bridge-0.1.0/tests/integration/__init__.py +0 -0
- credential_bridge-0.1.0/tests/integration/test_keyring_integration.py +25 -0
- credential_bridge-0.1.0/tests/integration/test_vault_integration.py +21 -0
- credential_bridge-0.1.0/tests/unit/__init__.py +0 -0
- credential_bridge-0.1.0/tests/unit/test_base.py +49 -0
- credential_bridge-0.1.0/tests/unit/test_env_cli.py +47 -0
- credential_bridge-0.1.0/tests/unit/test_env_file_backend.py +155 -0
- credential_bridge-0.1.0/tests/unit/test_exceptions.py +47 -0
- credential_bridge-0.1.0/tests/unit/test_keyring_backend.py +101 -0
- credential_bridge-0.1.0/tests/unit/test_keyring_cli.py +39 -0
- credential_bridge-0.1.0/tests/unit/test_main_cli.py +28 -0
- credential_bridge-0.1.0/tests/unit/test_manager.py +79 -0
- credential_bridge-0.1.0/tests/unit/test_prompt_wizard.py +80 -0
- credential_bridge-0.1.0/tests/unit/test_utils.py +48 -0
- credential_bridge-0.1.0/tests/unit/test_vault_backend.py +241 -0
- credential_bridge-0.1.0/tests/unit/test_vault_cli.py +73 -0
- credential_bridge-0.1.0/zensical.toml +201 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# 📚 Reusable Workflow: Deploy Zensical Docs to GitHub Pages
|
|
3
|
+
# ==============================================================================
|
|
4
|
+
# USAGE — call this from your project repo:
|
|
5
|
+
#
|
|
6
|
+
# jobs:
|
|
7
|
+
# docs:
|
|
8
|
+
# uses: your-org/.github/.github/workflows/publish-zensical.yml@main
|
|
9
|
+
# with:
|
|
10
|
+
# python-version: '3.11' # must be 3.10+ (Zensical requirement)
|
|
11
|
+
# docs-requirements: 'requirements-docs.txt'
|
|
12
|
+
# src-layout: true
|
|
13
|
+
# secrets: inherit
|
|
14
|
+
#
|
|
15
|
+
# SETUP:
|
|
16
|
+
# 1. Store this file in your shared `.github` repo under .github/workflows/
|
|
17
|
+
# 2. Create requirements-docs.txt with pinned docs dependencies:
|
|
18
|
+
# zensical>=0.0.39
|
|
19
|
+
# mkdocstrings[python]>=0.24
|
|
20
|
+
# mkdocs-autorefs>=1.0
|
|
21
|
+
# 3. Add zensical.toml to your project root (config file for Zensical)
|
|
22
|
+
# 4. Enable GitHub Pages: Settings → Pages → Source: GitHub Actions
|
|
23
|
+
# ==============================================================================
|
|
24
|
+
|
|
25
|
+
name: 📚 Deploy Zensical Docs to GitHub Pages
|
|
26
|
+
|
|
27
|
+
on:
|
|
28
|
+
workflow_call:
|
|
29
|
+
inputs:
|
|
30
|
+
python-version:
|
|
31
|
+
description: "Python version (must be 3.10+ — Zensical requirement)"
|
|
32
|
+
type: string
|
|
33
|
+
default: "3.11"
|
|
34
|
+
docs-requirements:
|
|
35
|
+
description: "Path to pip requirements file for docs dependencies"
|
|
36
|
+
type: string
|
|
37
|
+
default: "requirements-docs.txt"
|
|
38
|
+
src-layout:
|
|
39
|
+
description: "Set true if project uses src/ layout (adds src/ to PYTHONPATH)"
|
|
40
|
+
type: boolean
|
|
41
|
+
default: false
|
|
42
|
+
working-directory:
|
|
43
|
+
description: "Working directory (monorepo support)"
|
|
44
|
+
type: string
|
|
45
|
+
default: "."
|
|
46
|
+
|
|
47
|
+
# Allow direct triggering for testing
|
|
48
|
+
workflow_dispatch:
|
|
49
|
+
inputs:
|
|
50
|
+
python-version:
|
|
51
|
+
description: "Python version (must be 3.10+)"
|
|
52
|
+
type: string
|
|
53
|
+
default: "3.11"
|
|
54
|
+
|
|
55
|
+
# Minimal, scoped permissions (principle of least privilege)
|
|
56
|
+
permissions:
|
|
57
|
+
contents: read
|
|
58
|
+
pages: write
|
|
59
|
+
id-token: write
|
|
60
|
+
|
|
61
|
+
# Prevent concurrent deployments — queue them instead of cancelling
|
|
62
|
+
concurrency:
|
|
63
|
+
group: "pages-deploy"
|
|
64
|
+
cancel-in-progress: false
|
|
65
|
+
|
|
66
|
+
jobs:
|
|
67
|
+
build-docs:
|
|
68
|
+
name: 🔨 Build Docs
|
|
69
|
+
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
defaults:
|
|
72
|
+
run:
|
|
73
|
+
working-directory: ${{ inputs.working-directory || '.' }}
|
|
74
|
+
|
|
75
|
+
steps:
|
|
76
|
+
- name: 🔄 Checkout repository
|
|
77
|
+
uses: actions/checkout@v4
|
|
78
|
+
with:
|
|
79
|
+
fetch-depth: 0 # Full history — useful for version tags and future git plugins
|
|
80
|
+
|
|
81
|
+
- name: 🐍 Set up Python ${{ inputs.python-version || '3.11' }}
|
|
82
|
+
uses: actions/setup-python@v5
|
|
83
|
+
with:
|
|
84
|
+
python-version: ${{ inputs.python-version || '3.11' }}
|
|
85
|
+
|
|
86
|
+
# Cache pip downloads to speed up repeat builds
|
|
87
|
+
- name: 💾 Cache pip dependencies
|
|
88
|
+
uses: actions/cache@v4
|
|
89
|
+
with:
|
|
90
|
+
path: ~/.cache/pip
|
|
91
|
+
key: docs-pip-${{ runner.os }}-${{ inputs.python-version || '3.11' }}-${{ hashFiles(inputs.docs-requirements || 'requirements-docs.txt') }}
|
|
92
|
+
restore-keys: |
|
|
93
|
+
docs-pip-${{ runner.os }}-${{ inputs.python-version || '3.11' }}-
|
|
94
|
+
|
|
95
|
+
- name: 📦 Install doc dependencies
|
|
96
|
+
run: |
|
|
97
|
+
pip install --upgrade pip
|
|
98
|
+
pip install -r ${{ inputs.docs-requirements || 'requirements-docs.txt' }}
|
|
99
|
+
|
|
100
|
+
- name: 🔧 Configure PYTHONPATH for src layout
|
|
101
|
+
if: ${{ inputs.src-layout == true }}
|
|
102
|
+
run: echo "PYTHONPATH=$PYTHONPATH:$(pwd)/src" >> $GITHUB_ENV
|
|
103
|
+
|
|
104
|
+
- name: 🔨 Build Zensical site
|
|
105
|
+
run: zensical build
|
|
106
|
+
|
|
107
|
+
# Upload using the official GitHub Pages artifact action
|
|
108
|
+
- name: 📤 Upload Pages artifact
|
|
109
|
+
uses: actions/upload-pages-artifact@v3
|
|
110
|
+
with:
|
|
111
|
+
path: ${{ inputs.working-directory || '.' }}/public
|
|
112
|
+
|
|
113
|
+
deploy-docs:
|
|
114
|
+
name: 🚀 Deploy to GitHub Pages
|
|
115
|
+
needs: build-docs
|
|
116
|
+
runs-on: ubuntu-latest
|
|
117
|
+
environment:
|
|
118
|
+
name: github-pages
|
|
119
|
+
url: ${{ steps.deploy.outputs.page_url }}
|
|
120
|
+
steps:
|
|
121
|
+
- name: 🚀 Deploy to GitHub Pages
|
|
122
|
+
id: deploy
|
|
123
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# 🚢 Release Workflow — Project Caller
|
|
3
|
+
# ==============================================================================
|
|
4
|
+
# Save this file in YOUR PROJECT repo at:
|
|
5
|
+
# .github/workflows/release.yml
|
|
6
|
+
#
|
|
7
|
+
# TRIGGERS & JOB MATRIX:
|
|
8
|
+
#
|
|
9
|
+
# Event │ docs │ publish
|
|
10
|
+
# ─────────────────┼──────┼────────
|
|
11
|
+
# Push to main │ ✅ │ ⛔
|
|
12
|
+
# Push tag X.X.X │ ⛔ │ ✅
|
|
13
|
+
# Manual dispatch │ ✅ │ ⛔
|
|
14
|
+
#
|
|
15
|
+
# PUBLISH TARGET FLAG (controls where the package is published):
|
|
16
|
+
#
|
|
17
|
+
# publish-target: 'both' → TestPyPI first, then PyPI ← default
|
|
18
|
+
# publish-target: 'pypi' → PyPI only
|
|
19
|
+
# publish-target: 'testpypi' → TestPyPI only
|
|
20
|
+
#
|
|
21
|
+
# RELEASE FLOW:
|
|
22
|
+
# 1. Merge PRs to main as normal — docs deploy automatically
|
|
23
|
+
# 2. When ready to release, push a bare SemVer tag:
|
|
24
|
+
# git tag 1.2.1
|
|
25
|
+
# git push origin 1.2.1
|
|
26
|
+
# 3. The publish job runs: validate → test → build → testpypi → pypi
|
|
27
|
+
#
|
|
28
|
+
# SECRETS REQUIRED (Settings → Secrets and variables → Actions):
|
|
29
|
+
# TEST_PYPI_API_TOKEN — from test.pypi.org/manage/account/token/
|
|
30
|
+
# PYPI_API_TOKEN — from pypi.org (only if not using Trusted Publishing)
|
|
31
|
+
#
|
|
32
|
+
# PRE-REQUISITES (once per project):
|
|
33
|
+
#
|
|
34
|
+
# 1. Enable GitHub Pages:
|
|
35
|
+
# Settings → Pages → Source → GitHub Actions
|
|
36
|
+
#
|
|
37
|
+
# 2. Create GitHub Environments:
|
|
38
|
+
# Settings → Environments → New environment
|
|
39
|
+
# - "pypi" (real PyPI — add Required reviewers for safety)
|
|
40
|
+
# - "test-pypi" (TestPyPI sandbox — no reviewers needed)
|
|
41
|
+
#
|
|
42
|
+
# 3. Register Trusted Publisher on pypi.org:
|
|
43
|
+
# pypi.org → your project → Publishing → Add publisher
|
|
44
|
+
# owner = vertex-ai-automations
|
|
45
|
+
# repo = THIS-REPO-NAME
|
|
46
|
+
# workflow = release.yml
|
|
47
|
+
# env = pypi
|
|
48
|
+
#
|
|
49
|
+
# 4. Create requirements-docs.txt:
|
|
50
|
+
# zensical>=0.0.39
|
|
51
|
+
# mkdocstrings[python]>=0.24
|
|
52
|
+
# mkdocs-autorefs>=1.0
|
|
53
|
+
#
|
|
54
|
+
# CUSTOMISE PER PROJECT:
|
|
55
|
+
# python-version — match your project's Python version
|
|
56
|
+
# test-command — your test runner command
|
|
57
|
+
# publish-target — 'both' | 'pypi' | 'testpypi'
|
|
58
|
+
# src-layout — true if you use a src/ directory layout
|
|
59
|
+
# mkdocs-strict — false to allow doc build warnings
|
|
60
|
+
# ==============================================================================
|
|
61
|
+
|
|
62
|
+
name: 🚢 Release
|
|
63
|
+
|
|
64
|
+
on:
|
|
65
|
+
push:
|
|
66
|
+
branches:
|
|
67
|
+
- main # Docs deploy only
|
|
68
|
+
tags:
|
|
69
|
+
- "*.*.*" # Publish only — bare SemVer e.g. 1.2.1
|
|
70
|
+
workflow_dispatch: # Manual trigger — docs only
|
|
71
|
+
|
|
72
|
+
jobs:
|
|
73
|
+
|
|
74
|
+
# ============================================================
|
|
75
|
+
# 📚 Deploy Zensical Docs to GitHub Pages
|
|
76
|
+
# Runs on: push to main, manual dispatch
|
|
77
|
+
# ============================================================
|
|
78
|
+
docs:
|
|
79
|
+
name: 📚 Deploy Docs
|
|
80
|
+
uses: vertex-ai-automations/shared-workflows/.github/workflows/publish-zensical.yml@main
|
|
81
|
+
permissions:
|
|
82
|
+
contents: read
|
|
83
|
+
pages: write
|
|
84
|
+
id-token: write
|
|
85
|
+
with:
|
|
86
|
+
python-version: "3.11" # must be 3.10+ (Zensical requirement)
|
|
87
|
+
docs-requirements: "requirements-docs.txt"
|
|
88
|
+
src-layout: true # ← set false if not using src/ layout
|
|
89
|
+
secrets: inherit
|
|
90
|
+
|
|
91
|
+
# ============================================================
|
|
92
|
+
# 📦 Build and Publish Package
|
|
93
|
+
# Runs on: tag push only (tag guard is enforced inside the
|
|
94
|
+
# reusable workflow — non-tag pushes skip cleanly)
|
|
95
|
+
#
|
|
96
|
+
# publish-target controls which registries receive the package:
|
|
97
|
+
# 'both' → TestPyPI first, then PyPI (recommended)
|
|
98
|
+
# 'pypi' → PyPI only
|
|
99
|
+
# 'testpypi' → TestPyPI only
|
|
100
|
+
#
|
|
101
|
+
# No permissions block needed — declared inside python-publish.yml
|
|
102
|
+
# ============================================================
|
|
103
|
+
publish:
|
|
104
|
+
name: 📦 Publish Package
|
|
105
|
+
uses: vertex-ai-automations/shared-workflows/.github/workflows/python-publish.yml@main
|
|
106
|
+
permissions:
|
|
107
|
+
contents: read
|
|
108
|
+
id-token: write
|
|
109
|
+
with:
|
|
110
|
+
python-version: "3.11"
|
|
111
|
+
run-tests: true
|
|
112
|
+
test-command: "pytest tests/ -v --tb=short"
|
|
113
|
+
publish-target: "both" # 'both' | 'pypi' | 'testpypi' — publishes to TestPyPI first, then PyPI
|
|
114
|
+
use-trusted-publishing: false # set false to use PYPI_API_TOKEN instead (must be set in Settings → Secrets → Actions)
|
|
115
|
+
secrets: inherit
|
|
116
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# ── Generated files ────────────────────────────────────────────────────────────
|
|
2
|
+
# setuptools_scm writes this at build/install time — never commit it
|
|
3
|
+
src/credential_bridge/_version.py
|
|
4
|
+
|
|
5
|
+
# ── Python ─────────────────────────────────────────────────────────────────────
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
*.so
|
|
10
|
+
*.egg-info/
|
|
11
|
+
*.egg
|
|
12
|
+
MANIFEST
|
|
13
|
+
.installed.cfg
|
|
14
|
+
|
|
15
|
+
# Build / dist
|
|
16
|
+
build/
|
|
17
|
+
dist/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
develop-eggs/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
sdist/
|
|
24
|
+
parts/
|
|
25
|
+
var/
|
|
26
|
+
lib/
|
|
27
|
+
lib64/
|
|
28
|
+
downloads/
|
|
29
|
+
.Python
|
|
30
|
+
|
|
31
|
+
# ── Virtual environments ────────────────────────────────────────────────────────
|
|
32
|
+
.env
|
|
33
|
+
.venv
|
|
34
|
+
env/
|
|
35
|
+
venv/
|
|
36
|
+
ENV/
|
|
37
|
+
env.bak/
|
|
38
|
+
venv.bak/
|
|
39
|
+
|
|
40
|
+
# ── Testing ─────────────────────────────────────────────────────────────────────
|
|
41
|
+
.pytest_cache/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
htmlcov/
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
nosetests.xml
|
|
52
|
+
.hypothesis/
|
|
53
|
+
cover/
|
|
54
|
+
|
|
55
|
+
# ── Type checkers ──────────────────────────────────────────────────────────────
|
|
56
|
+
.mypy_cache/
|
|
57
|
+
.dmypy.json
|
|
58
|
+
dmypy.json
|
|
59
|
+
.pyre/
|
|
60
|
+
.pytype/
|
|
61
|
+
|
|
62
|
+
# ── Docs build output ──────────────────────────────────────────────────────────
|
|
63
|
+
/public
|
|
64
|
+
/site
|
|
65
|
+
|
|
66
|
+
# ── Internal planning (spec/plan files) ────────────────────────────────────────
|
|
67
|
+
docs/superpowers/
|
|
68
|
+
|
|
69
|
+
# ── Playwright MCP test artifacts ──────────────────────────────────────────────
|
|
70
|
+
.playwright-mcp/
|
|
71
|
+
|
|
72
|
+
# ── EnvFileBackend atomic write temp files ─────────────────────────────────────
|
|
73
|
+
*.env.tmp
|
|
74
|
+
|
|
75
|
+
# ── Editors / IDEs ─────────────────────────────────────────────────────────────
|
|
76
|
+
.vscode/
|
|
77
|
+
.idea/
|
|
78
|
+
.ropeproject
|
|
79
|
+
.spyderproject
|
|
80
|
+
.spyproject
|
|
81
|
+
|
|
82
|
+
# ── System ─────────────────────────────────────────────────────────────────────
|
|
83
|
+
.DS_Store
|
|
84
|
+
*.swp
|
|
85
|
+
*.log
|
|
86
|
+
*.err
|
|
87
|
+
|
|
88
|
+
# ── Jupyter ────────────────────────────────────────────────────────────────────
|
|
89
|
+
*.ipynb_checkpoints
|
|
90
|
+
profile_default/
|
|
91
|
+
ipython_config.py
|
|
92
|
+
|
|
93
|
+
# ── PyInstaller ────────────────────────────────────────────────────────────────
|
|
94
|
+
*.manifest
|
|
95
|
+
|
|
96
|
+
# ── PEP 582 ────────────────────────────────────────────────────────────────────
|
|
97
|
+
__pypackages__/
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**credential-bridge** is a Python 3.8+ secrets management library with a plugin backend architecture. It supports HashiCorp Vault (KV-v2), OS system keyring, and .env files through a unified interface. Ships five CLI entry points: `cb`, `vault-cli`, `keyring-cli`, `env-cli`, and `run-wizard`.
|
|
8
|
+
|
|
9
|
+
## Development Setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install with dev dependencies
|
|
13
|
+
pip install -e ".[dev]"
|
|
14
|
+
|
|
15
|
+
# Run tests
|
|
16
|
+
pytest tests/unit/
|
|
17
|
+
|
|
18
|
+
# Run integration tests (requires external services)
|
|
19
|
+
pytest tests/integration/ -m integration
|
|
20
|
+
|
|
21
|
+
# Serve docs locally (Zensical — uses zensical.toml)
|
|
22
|
+
zensical serve
|
|
23
|
+
|
|
24
|
+
# Build docs
|
|
25
|
+
zensical build
|
|
26
|
+
|
|
27
|
+
# Lint
|
|
28
|
+
ruff check src/
|
|
29
|
+
|
|
30
|
+
# Type check
|
|
31
|
+
mypy src/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Version is auto-generated from git tags via `setuptools_scm` — never commit `_version.py` (it is in `.gitignore`). Run `pip install -e .` to regenerate it after tagging.
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
src/credential_bridge/
|
|
40
|
+
├── backends/
|
|
41
|
+
│ ├── base.py # BaseSecretBackend ABC — 5 abstract methods + backend_name
|
|
42
|
+
│ ├── vault.py # VaultBackend: HashiCorp Vault KV-v2
|
|
43
|
+
│ ├── keyring.py # KeyringBackend: OS keyring (JSON-serialised dict per entry)
|
|
44
|
+
│ └── env_file.py # EnvFileBackend: .env file CRUD with atomic writes
|
|
45
|
+
├── cli/
|
|
46
|
+
│ ├── main.py # Unified `cb` entry point (Typer, composes sub-apps)
|
|
47
|
+
│ ├── vault_cli.py # vault-cli (Typer + Rich)
|
|
48
|
+
│ ├── keyring_cli.py # keyring-cli (Typer + Rich)
|
|
49
|
+
│ └── env_cli.py # env-cli (Typer + Rich)
|
|
50
|
+
├── exceptions.py # Typed hierarchy: CredentialBridgeError → BackendError → ...
|
|
51
|
+
├── manager.py # SecretsManager facade + class-level backend registry
|
|
52
|
+
├── prompt_wizard.py # Interactive wizard (prompt_toolkit)
|
|
53
|
+
└── utils.py # Config I/O (~/.vault_config.json), get_session()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Key design decisions:**
|
|
57
|
+
- `BaseSecretBackend` enforces `backend_name` via `__init_subclass__` — forgetting to set it raises `TypeError` at class definition time.
|
|
58
|
+
- `SecretsManager._registry` is a class-level dict. `register_backend("name", MyBackend)` is how third-party backends plug in. Tests must use a `clean_registry` autouse fixture to isolate state.
|
|
59
|
+
- `VaultBackend` URL resolution: `vault_url` arg → `VAULT_ADDR` env var → `~/.vault_config.json` → `ConfigurationError`.
|
|
60
|
+
- `VaultBackend(persist=False)` is the default — credentials are NOT written to `~/.vault_config.json` unless `persist=True` is explicitly passed.
|
|
61
|
+
- `KeyringBackend` serialises the secret dict to JSON before storing (keyring stores one string per key). `get_secret` deserialises on retrieval.
|
|
62
|
+
- `EnvFileBackend` uses `os.replace()` for atomic writes (write to `.env.tmp`, rename). Values with spaces or special chars are double-quoted.
|
|
63
|
+
- All logging goes through `PyLogShield` for sensitive data masking. Both `VaultBackend` and `KeyringBackend` accept an optional `logger: PyLogShield` parameter.
|
|
64
|
+
- TLS verification is enabled by default (`verify=True`). Pass `cert="/path/to/ca.pem"` for custom CA bundles.
|
|
65
|
+
|
|
66
|
+
## Exception Hierarchy
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
CredentialBridgeError
|
|
70
|
+
├── BackendError
|
|
71
|
+
│ ├── VaultError
|
|
72
|
+
│ │ ├── VaultAuthError — bad token / AppRole
|
|
73
|
+
│ │ ├── VaultConnectionError — unreachable server
|
|
74
|
+
│ │ └── VaultSecretNotFoundError — secret path does not exist
|
|
75
|
+
│ ├── KeyringError
|
|
76
|
+
│ └── EnvFileError
|
|
77
|
+
│ ├── EnvFileNotFoundError — key not found
|
|
78
|
+
│ └── EnvFileKeyExistsError — add_secret on existing key
|
|
79
|
+
├── BackendNotRegisteredError
|
|
80
|
+
└── ConfigurationError
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Backwards Compatibility
|
|
84
|
+
|
|
85
|
+
`VaultManager` and `KeyringManager` are aliases for `VaultBackend` and `KeyringBackend` in `__init__.py`. Existing code using the old names continues to work.
|
|
86
|
+
|
|
87
|
+
## Docs
|
|
88
|
+
|
|
89
|
+
MkDocs + Material theme. Content at `docs/`. API reference pages in `docs/reference/` are auto-generated from numpy-style docstrings via `mkdocstrings`. Keep docstrings in numpy format when adding or modifying public methods.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Muhammad Hassan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|