Gatway

Documentation

Get Gatway running

From an empty server to a developer shipping AI-assisted code with a full audit trail — usually under an hour.

Overview

Gatway has three parts:

PartWhat it does
GatewayFastAPI service. All AI traffic passes through it — routing, policy, security filtering, caching, audit.
DashboardReact console for admins: providers, budgets, users, agents, cost and change history.
VS Code extensionWhat developers use: chat, autocomplete, edit-apply, code review and agents.

The gateway exposes an OpenAI-compatible /v1/chat/completions endpoint, so existing tools and scripts can point at it without changes.

Deploy the gateway

Requirements: Ubuntu 22.04+, Python 3.11+, PostgreSQL 14+, Node 20 (to build the dashboard).

git clone <your-repo> /opt/gatway
cd /opt/gatway/ai-gateway
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt

Create the database:

sudo -u postgres psql
CREATE USER gateway WITH PASSWORD 'a-long-random-password';
CREATE DATABASE gateway OWNER gateway;

Generate your secrets:

# encrypts provider keys at rest
./.venv/bin/python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
openssl rand -hex 32   # ADMIN_KEY
openssl rand -hex 32   # SESSION_SECRET

Back up ENCRYPTION_KEY outside the server. It seals every provider key in the database. Lose it and those keys become permanently unreadable.

Write .env, then start it:

DATABASE_URL=postgresql+asyncpg://gateway:...@localhost:5432/gateway
ADMIN_KEY=...
ENCRYPTION_KEY=...
SESSION_SECRET=...
ANTHROPIC_API_KEY=sk-ant-...
NVIDIA_API_KEY=nvapi-...
./.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
curl localhost:8000/health   # {"status":"ok"}

Database tables are created automatically on first boot — there is no migration step. Build the dashboard with npm ci && npm run build in frontend/ and serve frontend/dist from nginx.

For the full production setup — Elastic IP, domain, nginx with SSE support, TLS and systemd — see DEPLOYMENT_AWS.md in the repository.

Connect providers

Gatway supports Anthropic, OpenAI, Gemini, NVIDIA and Ollama. Keys can come from .env (gateway-wide fallback) or be added per organization in the dashboard, where they're encrypted at rest.

Sign in to the dashboard → Providers & Models → add a key. Then set:

Local Ollama requests are exempt from the security filter — nothing leaves the machine.

Users & keys

Bootstrap the first organization and admin with your master ADMIN_KEY:

curl -X POST https://gatway.example.com/admin/orgs \
  -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Acme"}'

curl -X POST https://gatway.example.com/admin/users \
  -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
  -d '{"org_id":"<org-id>","email":"you@acme.com","role":"admin","password":"strong-password"}'

After that, everything happens in the dashboard. Roles:

RoleCan do
developerUse the extension and their own usage view
leadPlus read the change audit trail
fde / adminPlus manage users, keys, policy and agents

Issue each developer a key under Users & Keys — it starts with sk-gw- and is shown only once. Keys can be scoped to a project so cost is attributed correctly.

VS Code extension

Install the .vsix: Extensions → Install from VSIX, then reload. Point it at your server in settings:

"gatway.baseUrl": "https://gatway.example.com"

Open the Gatway sidebar and sign in with email/password or your sk-gw- key. You get:

Useful settings:

SettingDefaultPurpose
gatway.focusedContexttrueSend only the relevant code part instead of whole files
gatway.inlineCompletionstrueGhost-text suggestions
gatway.completionDelayMs300Idle time before requesting a suggestion
gatway.autoNewChatIdleMinutes20Start a fresh chat after idle, so old topics don't bleed in

Project setup

Two files make Gatway understand a repository. Commit both.

.aiconfig

Team rules and stack, applied to every request in this repo. Create it with Gatway: Create .aiconfig.

{
  "stack": ["python", "fastapi", "react"],
  "testing": "pytest",
  "rules": [
    "SQLAlchemy 2.0 style only",
    "Errors follow RFC 7807"
  ],
  "ignore_paths": ["migrations/", "*.lock"],
  "max_context_files": 5
}

PROJECT_STRUCTURE.md

A generated map of the repo, attached as context so the AI understands the layout. Run Gatway: Generate Project Structure once and commit the result.

Agents

Agents explore the codebase with tools and propose multi-file changes. They're declarative — adding one is configuration, not code — and they're layered:

  1. Built-in — Coder, Reviewer, Test writer
  2. Org-published — created in the dashboard, available to everyone
  3. Project — committed in .gatway/agents/*.md

A project agent overrides an org agent with the same id, unless the org marked it locked.

A project agent

---
name: DB Migrator
description: Writes schema migrations
tools: [read_file, search_code, propose_edit, create_file]
model: claude-sonnet-4-5
---
You migrate database schemas. Always include a rollback path
and never edit a migration that has already shipped.

Tools

ToolAccess
list_files, read_file, search_coderead-only
propose_edit, create_filestages a change for approval

Allowlists are enforced by the gateway, not the client. An agent published without write tools cannot modify code even if a modified client asks it to. Agents never write directly — every change goes through the diff preview and your Apply click.

Code review & CI

Run Gatway: Review Changes to review uncommitted work or a branch against your base. Findings come back with severity, file, line and a suggested fix.

The same endpoint works from CI — gate a merge on the result:

curl -X POST https://gatway.example.com/v1/review \
  -H "Authorization: Bearer $GATWAY_KEY" -H "Content-Type: application/json" \
  -d "$(jq -n --arg d "$(git diff origin/main...HEAD)" '{diff:$d}')"

The response includes approved, a summary, and a findings[] array.

Cost controls

Four mechanisms, all on by default:

Set hard limits in the dashboard: monthly budget per organization and per project, and a daily token limit per user. Track spend under Overview.

Audit trail

Every prompt is recorded, and every applied change is recorded with its full diff and the prompt that caused it. Leads and admins see it under Changes, filterable by developer, project and date.

Secrets are stripped before anything is stored; PII follows your organization's policy.

This covers AI-assisted changes. It complements git blame rather than replacing it — a developer can still edit by hand outside Gatway.

Config reference

VariableDefaultPurpose
DATABASE_URLsqlitePostgres connection string
ENCRYPTION_KEYFernet key sealing provider credentials
ADMIN_KEYMaster key for /admin
AUTO_SIMPLE_MODELgpt-4o-miniModel for simple prompts
AUTO_COMPLEX_MODELclaude-sonnet-4-5Model for complex prompts
ANALYSIS_MODELCheap model that optimizes prompts. Empty disables it
COMPLETION_MODELqwen2.5-coder, gpt-4o-miniAutocomplete chain
FALLBACK_MODELSFailover chain after the chosen model
RESPONSE_CACHEtrueSemantic response cache
OPTIMIZE_CONTEXTtrueDedupe and trim context
EMBEDDING_MODELnvidia/nv-embedqa-e5-v5Embeddings for cache and search

Troubleshooting

SymptomFix
Replies arrive all at once, not streamingAdd proxy_buffering off; to the nginx API block
Requests cut off around 60 secondsRaise proxy_read_timeout to 600s
No autocomplete suggestionsCOMPLETION_MODEL points at a model you have no key for
Answer unrelated to the questionStart a new chat — old turns were still in context
"Proposed edits (0 files)"The model's search text didn't match the file; the guard correctly refused to apply it
Provider keys unreadable after a rebuildENCRYPTION_KEY changed — restore the original