Metadata-Version: 2.5
Name: antcrew-proxy
Version: 2.0.0
Summary: Self-hosted LLM key proxy for antcrew-platform — BYOK without exposing provider keys
Project-URL: Homepage, https://github.com/iagop03/antcrew-proxy
Project-URL: Repository, https://github.com/iagop03/antcrew-proxy
Author-email: Iago Pueyo <iago.pueyo99@gmail.com>
License: MIT
Keywords: ai,anthropic,byok,fastapi,llm,openai,proxy
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: Proxy Servers
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.115
Requires-Dist: httpx>=0.28
Requires-Dist: uvicorn[standard]>=0.32
Provides-Extra: dev
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-anyio; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# antcrew-proxy

A lightweight reverse proxy that lets you use antcrew-platform without ever giving the platform your LLM API keys.

**How it works:**

```
antcrew-platform  →  antcrew-proxy (yours)  →  api.anthropic.com
       ↑                    ↑                    api.openai.com
  sends UUID token     holds your real            api.groq.com
  (never sees keys)    provider keys              …
```

The platform generates a UUID token and sends it on every LLM request — one token covers all providers. Your proxy validates the token, substitutes the real API key for the target provider, and forwards the request. The platform never touches your keys.

**Provider routing by URL path:**

| Path prefix | Upstream |
|---|---|
| `/anthropic/…` | `https://api.anthropic.com` |
| `/openai/…` | `https://api.openai.com` |
| `/groq/…` | `https://api.groq.com/openai` |
| `/gemini/…` | `https://generativelanguage.googleapis.com/v1beta/openai` |
| `/moonshot/…` | `https://api.moonshot.cn/v1` |
| `/deepseek/…` | `https://api.deepseek.com/v1` |
| `/mistral/…` | `https://api.mistral.ai/v1` |
| `/xai/…` | `https://api.x.ai/v1` |
| `/together/…` | `https://api.together.xyz/v1` |
| `/fireworks/…` | `https://api.fireworks.ai/inference/v1` |
| `/cerebras/…` | `https://api.cerebras.ai/v1` |
| `/ollama/…` | `http://localhost:11434` *(keyless)* |
| `/lmstudio/…` | `http://localhost:1234/v1` *(keyless)* |
| `/vllm/…` | `http://localhost:8000/v1` *(keyless)* |

---

## Setup (5 steps)

### Step 1 — Generate a token in the platform

Go to **Settings → LLM Mode**, select your workspace, and open the **Proxy** section.

Enter the public URL where you will host this proxy (e.g. `https://proxy.yourcompany.com`) and click **Generar token**.

Copy the token — it is only displayed once.

### Step 2 — Run antcrew-proxy

**With Docker (recommended):**

```bash
docker run -d \
  --name antcrew-proxy \
  -p 8080:8080 \
  -e PROXY_TOKEN=YOUR_UUID_TOKEN \
  -e ANTHROPIC_API_KEY=sk-ant-YOUR_KEY \
  -e OPENAI_API_KEY=sk-proj-YOUR_KEY \
  ghcr.io/iagop03/antcrew-proxy:latest
```

Configure only the provider keys you actually use — others can be omitted.

**With docker-compose** — copy `docker-compose.example.yml`, fill in your values:

```bash
docker compose -f docker-compose.example.yml up -d
```

**Without Docker:**

```bash
pip install -r requirements.txt
PROXY_TOKEN=your-token \
ANTHROPIC_API_KEY=sk-ant-... \
uvicorn main:app --host 0.0.0.0 --port 8080
```

### Step 3 — Verify the proxy is healthy

```bash
curl https://proxy.yourcompany.com/health
# → {"ok": true, "providers": ["anthropic", "openai"]}
```

The `providers` list shows which keys are configured and will accept requests.

Make sure port 8080 is reachable from the platform host. Run behind a TLS terminator (nginx, Caddy, Fly.io, Cloudflare Tunnel) in production — the platform will send LLM traffic over HTTPS.

### Step 4 — Activate proxy mode in the platform

Back in **Settings → LLM Mode**, click **Proxy ×0.7**. The workspace switches to proxy mode immediately.

### Step 5 — Run a pipeline

Trigger any run from the platform. LLM calls are routed through your proxy; your API keys never leave your network.

---

## Environment variables

| Variable | Required | Description |
|---|---|---|
| `PROXY_TOKEN` | **Yes** | UUID token generated by the platform |
| `ANTHROPIC_API_KEY` | No | Anthropic key (`sk-ant-…`) |
| `OPENAI_API_KEY` | No | OpenAI key (`sk-proj-…`) |
| `GROQ_API_KEY` | No | Groq key (`gsk_…`) |
| `GEMINI_API_KEY` | No | Gemini key (`AIza…`) |
| `MOONSHOT_API_KEY` | No | Moonshot AI key (`sk-…`) |
| `DEEPSEEK_API_KEY` | No | DeepSeek key |
| `MISTRAL_API_KEY` | No | Mistral AI key |
| `XAI_API_KEY` | No | xAI Grok key |
| `TOGETHER_API_KEY` | No | Together AI key |
| `FIREWORKS_API_KEY` | No | Fireworks AI key |
| `CEREBRAS_API_KEY` | No | Cerebras key |
| `ANTHROPIC_BASE_URL` | No | Override Anthropic endpoint |
| `OPENAI_BASE_URL` | No | Override OpenAI endpoint (e.g. Azure OpenAI) |
| `GROQ_BASE_URL` | No | Override Groq endpoint |
| `GEMINI_BASE_URL` | No | Override Gemini endpoint |
| `MOONSHOT_BASE_URL` | No | Override Moonshot endpoint |
| `DEEPSEEK_BASE_URL` | No | Override DeepSeek endpoint |
| `OLLAMA_BASE_URL` | No | Ollama server URL (default: `http://localhost:11434`) |
| `LMSTUDIO_BASE_URL` | No | LM Studio URL (default: `http://localhost:1234/v1`) |
| `VLLM_BASE_URL` | No | vLLM URL (default: `http://localhost:8000/v1`) |
| `HOST` | No | Bind host (default: `0.0.0.0`) |
| `PORT` | No | Bind port (default: `8080`) |

At least one provider key must be set (or a keyless local provider reachable), or all requests will return `503`.

---

## Adding a provider later

Stop the container, add the new key, and restart — no token rotation needed:

```bash
docker stop antcrew-proxy
docker run -d --name antcrew-proxy -p 8080:8080 \
  -e PROXY_TOKEN=SAME_TOKEN \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  -e OPENAI_API_KEY=sk-proj-...  \   # new
  ghcr.io/iagop03/antcrew-proxy:latest
```

---

## Rotating the token

If you suspect the token is compromised, go to **Settings → LLM Mode → Proxy → Rotar token**. The old token is invalidated immediately. Update `PROXY_TOKEN` on your proxy and restart:

```bash
docker stop antcrew-proxy && docker rm antcrew-proxy
docker run -d --name antcrew-proxy -p 8080:8080 \
  -e PROXY_TOKEN=NEW_TOKEN \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  ghcr.io/iagop03/antcrew-proxy:latest
```

---

## Revoking proxy mode

Click **Revocar** in the platform settings. The workspace reverts to managed mode and the token is deleted server-side. You can then stop the proxy container.

---

## Security

- Token is validated with `hmac.compare_digest` (constant-time) on every request.
- Your real API keys exist only in your container's environment; the platform stores only the encrypted UUID token.
- The proxy has no persistent state — it validates, rewrites the auth header, and forwards.
- Use HTTPS in production (TLS terminator in front of port 8080).

---

## Building locally

```bash
git clone https://github.com/iagop03/antcrew-proxy.git
cd antcrew-proxy
pip install -r requirements.txt
PROXY_TOKEN=test-token ANTHROPIC_API_KEY=sk-ant-... uvicorn main:app --reload
```

```bash
# Or build the Docker image
docker build -t antcrew-proxy .
docker run -p 8080:8080 -e PROXY_TOKEN=... -e ANTHROPIC_API_KEY=... antcrew-proxy
```
