Quickstart

Get Harbangan running and make your first API call in under 5 minutes using Docker. Choose the mode that fits your needs:

  • Proxy-Only Mode — Single container, single API key, no database or web UI. Best for personal use or quick evaluation.
  • Full Deployment — Multi-user with Google SSO, per-user API keys, and web dashboard. Best for teams.
Table of contents
  1. Proxy-Only Mode (Fastest)
    1. 1. Clone and configure
    2. 2. Start the gateway
    3. 3. Make your first API call
  2. Full Deployment (Multi-User)
    1. 1. Clone and configure
    2. 2. Start with Docker Compose
    3. 3. Complete setup via Web UI
    4. 4. Verify it works
    5. 5. Make your first API call
      1. OpenAI format
      2. Anthropic format
  3. What’s next?

Proxy-Only Mode (Fastest)

A single container with no PostgreSQL or Google SSO. Authenticates via a single PROXY_API_KEY. Supports all providers (Kiro, Anthropic, OpenAI, Copilot, Custom) via environment variables.

1. Clone and configure

git clone https://github.com/if414013/harbangan.git
cd harbangan

Create .env.proxy (copy from .env.proxy.example):

GATEWAY_MODE=proxy
PROXY_API_KEY=your-secret-api-key

# Optional — defaults to us-east-1:
# KIRO_REGION=us-east-1

# For Identity Center (pro): set your SSO start URL
# KIRO_SSO_URL=https://your-org.awsapps.com/start
# KIRO_SSO_REGION=us-east-1

2. Start the gateway

docker compose -f docker-compose.gateway.yml --env-file .env.proxy up -d

On first boot, the container runs a device code flow — check the logs for a URL to open in your browser:

╔═══════════════════════════════════════════════════════════╗
║  Open this URL in your browser to authorize:             ║
║  https://device.sso.us-east-1.amazonaws.com/?user_code=… ║
╚═══════════════════════════════════════════════════════════╝

Credentials are cached in a Docker volume — you only need to authorize once. On subsequent restarts, the gateway reuses the cached tokens automatically.

3. Make your first API call

The gateway starts on port 8000 and authenticates requests with your PROXY_API_KEY:

curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer your-secret-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

That’s it — you’re running.


Full Deployment (Multi-User)

Multi-user mode with PostgreSQL, Google SSO, per-user API keys, and web dashboard.

1. Clone and configure

git clone https://github.com/if414013/harbangan.git
cd harbangan
cp .env.example .env

Edit .env:

POSTGRES_PASSWORD=change-me

# Optional: seed admin for password login (first-run only)
# INITIAL_ADMIN_EMAIL=admin@example.com
# INITIAL_ADMIN_PASSWORD=changeme

Google SSO is configured via the Admin UI after first login, not via env vars. Use the INITIAL_ADMIN_* vars above for password-based first login.

2. Start with Docker Compose

docker compose up -d --build

This starts three services: PostgreSQL, the Rust backend, and the frontend (nginx serving the React SPA). The first build takes a few minutes.

Watch the logs:

docker compose logs -f backend

Wait until you see:

Setup not complete — starting in setup-only mode
Server listening on http://0.0.0.0:9999

3. Complete setup via Web UI

Open http://localhost:5173/_ui/ in your browser (or https://your-domain.com/_ui/ in production).

  1. Sign in — the first user gets the Admin role (via Google SSO or password auth)
  2. Connect your Kiro credentials on the Profile page via AWS SSO device code flow
  3. Create a personal API key in the API Keys section

4. Verify it works

# Health check
curl https://your-domain.com/health
# → {"status":"ok"}

# List models
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://your-domain.com/v1/models

5. Make your first API call

OpenAI format

curl -X POST https://your-domain.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "messages": [
      {"role": "user", "content": "Write a haiku about coding"}
    ],
    "stream": true
  }'

Anthropic format

curl -X POST https://your-domain.com/v1/messages \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Write a haiku about coding"}
    ],
    "stream": true
  }'

You should see a streaming SSE response with the model’s reply.


What’s next?