agent-credential-broker: fork of vaultwarden-agent-broker + OpenBao backend

Mechanical rename (package agent_credential_broker; entry points
agent-broker{,-mcp,-plugin}; env AGENT_BROKER_*; paths agent-broker;
agent-browser credential provider 'broker'; MCP server name agent-broker).

New backend 'openbao': stdlib-only HTTP client for OpenBao/Vault KV v2
(approle login or token file/env; metadata-only ref index; lazy re-login
on 401/403; token renewal). bitwarden-cli backend kept as transition.
This commit is contained in:
me committed 2026-10-14 13:27:33 -06:00
commit be87900794
35 files changed
+5003

No files matched your search

@@ -0,0 +1,70 @@
"""Vault backend abstraction -- the ONLY layer that talks to the vault.
bitwarden-cli official `bw` subprocesses against a
Bitwarden-compatible server (transition backend).
openbao OpenBao/Vault HTTP API (KV v2 + AppRole), stdlib
urllib only -- the target backend for agent
credentials.
A failing backend surfaces as VAULT_BACKEND_ERROR; there is no fallback.
The backend owns authentication, the unlocked session and vault reads.
Everything else (policy, refs, adapters, sanitizer, MCP, unix socket)
is backend-agnostic.
"""
from __future__ import annotations
from ..errors import BrokerError
class VaultBackend:
"""Interface consumed by BrokerCore.
unlock(password) authenticate + establish session (raises
UNLOCK_FAILED on bad password, VAULT_BACKEND_ERROR
otherwise)
lock() invalidate session + drop in-memory material
list_metadata() items with secret fields stripped (ref index)
get_item(item_id) full normalized item, fetched on demand
"""
name = "abstract"
def __init__(self, config):
self.config = config
def configured(self) -> bool:
raise NotImplementedError
def unlock(self, password: str) -> None:
raise NotImplementedError
def lock(self) -> None:
raise NotImplementedError
def logout(self) -> None:
"""End the vault session AND the stored account login. Default
equals lock() for backends without a persistent login."""
self.lock()
def list_metadata(self) -> list[dict]:
raise NotImplementedError
def get_item(self, item_id: str) -> dict:
raise NotImplementedError
def make_backend(config) -> VaultBackend:
name = config.vault_backend
if name == "bitwarden-cli":
from .bwcli import BitwardenCliBackend
return BitwardenCliBackend(config)
if name == "openbao":
from .openbao import OpenBaoBackend
return OpenBaoBackend(config)
raise BrokerError(
"UNCONFIGURED",
f"unknown vault_backend {name!r} "
"(supported: 'bitwarden-cli', 'openbao')",
)