---
name: token-broker
description: Secure Gemini proxy for devs. Calls Gemini via your self-hosted Token Broker — X-API-Key (sk_...) → broker mints GCP access token from stored SA JSON and proxies to Vertex AI. No private_key leaves server.
version: 2.0.0
author: Token Broker
base_url: http://YOUR_SERVER:8001
auth: X-API-Key
---

# Token Broker Skill

Use this skill when you need to call Gemini models through the team's Token Broker. Do NOT call Google directly — always proxy through the broker.

## 1. Get your key
Ask admin for a project-scoped `sk_...` key. Admin creates it via Dashboard → Projects → Generate.

Store as env:
```
BROKER_URL=http://YOUR_SERVER:8001
BROKER_API_KEY=sk_...
```

## 2. Call Gemini — Generate Content

**Endpoint** `POST {BROKER_URL}/v1/gemini/{model}:generateContent`
Header: `X-API-Key: {BROKER_API_KEY}`

**Allowed models** (check `/v1/models` or admin → Models): `gemini-1.5-flash`, `gemini-1.5-pro`, `gemini-1.0-pro`, `gemini-2.0-flash`

### cURL
```bash
curl -X POST $BROKER_URL/v1/gemini/gemini-1.5-flash:generateContent \
  -H "X-API-Key: $BROKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}'
```

### Python
```python
import requests, os
BROKER_URL = os.getenv("BROKER_URL", "http://YOUR_SERVER:8001")
API_KEY = os.getenv("BROKER_API_KEY")

r = requests.post(
    f"{BROKER_URL}/v1/gemini/gemini-1.5-flash:generateContent",
    headers={"X-API-Key": API_KEY},
    json={"contents":[{"role":"user","parts":[{"text":"Summarize this: ..."}]}]},
    timeout=60
)
r.raise_for_status()
text = r.json()["candidates"][0]["content"]["parts"][0]["text"]
print(text)
```

### Node
```js
const res = await fetch(`${process.env.BROKER_URL}/v1/gemini/gemini-1.5-flash:generateContent`, {
  method: "POST",
  headers: {"X-API-Key": process.env.BROKER_API_KEY, "Content-Type":"application/json"},
  body: JSON.stringify({contents:[{role:"user", parts:[{text:"Hello"}]}]})
});
const j = await res.json();
console.log(j.candidates[0].content.parts[0].text);
```

### Request Body (Vertex AI shape)
```json
{
  "contents": [{"role":"user","parts":[{"text":"Your prompt"}]}],
  "generationConfig": {"temperature": 0.7, "maxOutputTokens": 1024},
  "_region": "us-central1"
}
```
`_region` is optional broker extension (default `us-central1`).

### Response 200
```json
{
  "candidates": [{"content":{"parts":[{"text":"Hello! How can I help?"}]}}],
  "usageMetadata": {"promptTokenCount": 3, "candidatesTokenCount": 8}
}
```

## 3. JSON File Server (recommended — lightweight, logged)
Use this when you just want the token JSON and will call Vertex yourself (no proxy). Logs which `model` was requested.

```bash
curl -X POST $BROKER_URL/v1/json \
  -H "X-API-Key: $BROKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-1.5-flash"}'
# also: POST $BROKER_URL/v1/json/gemini-1.5-flash
# -> {"json_type":"token","model":"gemini-1.5-flash","access_token":"ya29...","expires_in":3600, "project":"acme"}
```
Then call Vertex directly with that `ya29`:
```bash
curl https://us-central1-aiplatform.googleapis.com/v1/projects/$GCP_PROJECT/locations/us-central1/publishers/google/models/gemini-1.5-flash:generateContent \
  -H "Authorization: Bearer $TOKEN" -d '{"contents":[{"role":"user","parts":[{"text":"Hello"}]}]}'
```

## 4. Get raw GCP token (optional)
For BigQuery/GCS, not Gemini:
```bash
curl -X POST $BROKER_URL/v1/token \
  -H "X-API-Key: $BROKER_API_KEY" \
  -d '{"scopes":["https://www.googleapis.com/auth/cloud-platform"], "model":"gemini-1.5-flash"}'
# model field is optional but will be logged
# -> {"access_token":"ya29...","expires_in":3600}
```

## 4. List allowed models
```bash
curl $BROKER_URL/v1/models -H "X-API-Key: $BROKER_API_KEY"
```

## 5. Errors
- `401` missing X-API-Key
- `403` invalid key
- `400` model not allowed → check allowlist
- `502` Vertex AI failed → check SA permissions / Vertex AI API enabled
- `429` rate limited (30/min per key)

## 6. Notes for AI Agents
- Never ask user for SA JSON. Only use `X-API-Key: sk_...`.
- Timeout 60s. Use `gemini-1.5-flash` for speed, `gemini-1.5-pro` for quality.
- Keep prompts in `contents[].parts[].text`. System instructions: add first content with `role: "user"` containing system prompt.
- Broker logs every call (project, key, model, latency) → admin can audit in Logs.
