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:
commit
be87900794
35 files changed
+5003
No files matched your search
@@ -0,0 +1,70 @@
|
||||
"""agent-browser ``credential.read`` plugin (agent-browser.plugin.v1).
|
||||
|
||||
agent-browser writes ONE JSON envelope on stdin::
|
||||
|
||||
{"protocol": "agent-browser.plugin.v1",
|
||||
"type": "credential.resolve",
|
||||
"capability": "credential.read",
|
||||
"request": {"profileName": "...", "itemRef": "...", "url": "..."}}
|
||||
|
||||
and expects one JSON object on stdout::
|
||||
|
||||
{"protocol": "agent-browser.plugin.v1", "success": true,
|
||||
"credential": {"username": ..., "password": ..., "url": ...,
|
||||
"usernameSelector": ..., "passwordSelector": ...,
|
||||
"submitSelector": ...}}
|
||||
|
||||
The plugin is a thin proxy: it forwards (itemRef, url) to the broker over
|
||||
the unix socket and relays the credential. The broker enforces the
|
||||
item's adapter policy and origin validation before releasing anything.
|
||||
Secret values go agent-browser-stdin -> plugin -> agent-browser; the
|
||||
agent model never sees them.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
from .errors import BrokerError
|
||||
from .server import call
|
||||
|
||||
PROTOCOL = "agent-browser.plugin.v1"
|
||||
|
||||
|
||||
def _fail(message):
|
||||
sys.stdout.write(json.dumps({
|
||||
"protocol": PROTOCOL, "success": False, "error": str(message)[:300],
|
||||
}) + "\n")
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
raw = sys.stdin.read(64 * 1024)
|
||||
envelope = json.loads(raw)
|
||||
except Exception:
|
||||
_fail("bad plugin envelope")
|
||||
return 1
|
||||
if (envelope.get("protocol") != PROTOCOL
|
||||
or envelope.get("type") != "credential.resolve"):
|
||||
_fail("unsupported plugin request")
|
||||
return 1
|
||||
req = envelope.get("request") or {}
|
||||
item_ref = req.get("itemRef")
|
||||
url = req.get("url")
|
||||
if not item_ref:
|
||||
_fail("missing itemRef")
|
||||
return 1
|
||||
try:
|
||||
cred = call("resolve", {"ref": item_ref, "url": url})
|
||||
except BrokerError as e:
|
||||
_fail(f"{e.code}: {e.message}")
|
||||
return 0 # a clean denial is still a protocol-level response
|
||||
sys.stdout.write(json.dumps({
|
||||
"protocol": PROTOCOL, "success": True, "credential": cred,
|
||||
}) + "\n")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user