What you'll build
A local HTTP broker that stands between a host and the real credential.
By the end of this lab you will have a tiny broker process listening on
127.0.0.1. A host can send model requests to that local
address, and the broker decides whether the request is allowed, where it
should go upstream, and whether it should attach a bearer token.
The teaching version starts in dry_run mode, so you can see
the full request and response cycle without a real API key or a real
outbound call. Once that shape makes sense, the same broker can pull a
secret from an environment variable, 1Password, or Azure Key Vault.
Run it
cd ai_ecosystem_labs
python3 13-local-broker/broker.py --config 13-local-broker/broker_config.dry-run.json
Starting here? Quick setup
git clone https://github.com/BanditF/ai_ecosystem_labs
cd ai_ecosystem_labs
python3 13-local-broker/broker.py --config 13-local-broker/broker_config.dry-run.json
Requires Python 3.8+. No extra packages needed for this lab.
Time guide. Setup: 5–10 min. Working through it: 25–45 min, especially if you compare dry-run mode with the real secret-handling path.
Why this piece exists
The point is to move trust to a narrower place.
If the host holds the raw provider key, every config file, shell session,
or tool wrapper that talks to the model becomes part of the secret's blast
radius. A localhost broker changes that shape. The host only knows how to
call a local HTTP interface, and the broker is the only component that
needs to know how to fetch or attach the real credential.
That does not make localhost magically safe. It does give you a cleaner
trust boundary: allowlisted paths, optional caller authentication, request
size limits, and one place to swap secret backends without changing host
code. Real systems often do this with an internal gateway or backend
service. This lab is the smallest version of that idea.
Real-world analog: your editor, CLI, or agent host talks to a small local
gateway, and that gateway talks to OpenAI or another provider. The host is
holding a capability, not the root credential.
Expected output
What a successful dry run looks like.
Your file paths may appear as absolute paths depending on where you run the script — that's expected.
When the broker starts:
{
"ok": true,
"listen": "http://127.0.0.1:8791",
"mode": "dry_run",
"allowed_paths": [
"/v1/chat/completions",
"/v1/responses",
"/v1/embeddings"
]
}
Then a dry-run request to an allowed path returns a mock forward description instead of calling a provider:
{
"ok": true,
"mode": "dry_run",
"forward": {
"url": "https://api.openai.example/v1/responses",
"path": "/v1/responses",
"secret_source": "none",
"would_attach_bearer_token": false
},
"request": {
"prompt": "hello"
}
}
The broker also appends an event to labs/13-local-broker/events.jsonl so you can see that the request was accepted and logged:
{"time":"2025-01-01T00:00:00Z","kind":"request","path":"/v1/responses","ok":true,"status":200,"mode":"dry_run"}