Quickstart: Windows

Axemere Gateway sits between your applications and AI providers (OpenAI, Anthropic, etc.), enforcing policies, tracking attribution, and recording every request. This guide gets you running on Windows in about 15 minutes using WSL2 and Docker.

Choose Your Setup Method

Pick the method that best fits how you want to use the gateway:

MethodCode changesProviders coveredBest for
1. Base URLOne env var per SDKOne at a timeQuick test of a single provider
2. System ProxyNoneAll AI providersHome use -- centralize all your API keys
3. Explicit APINew HTTP callsAnyProduction, teams, full attribution

Jump to: Method 1 | Method 2 -- Recommended | Method 3


Table of Contents


Prerequisites

  • Windows 11 22H2 or later (Windows 10 21H2+ works but lacks automatic localhost port forwarding and systemd support)
  • Hardware virtualization enabled in BIOS/UEFI. If running Windows inside a VM (Parallels, VMware), the host hypervisor must support nested virtualization. Parallels on Apple Silicon does not support nested virtualization -- use Docker Desktop on macOS directly instead.
  • An OpenAI or Anthropic API key to store in the gateway. You can skip this and test with a policy denial instead.

Steps

Step 1: Set Up WSL2

Open PowerShell as Administrator and install WSL2 with Ubuntu:

wsl --install -d Ubuntu-24.04

After the install completes and Ubuntu launches, create your Linux user account.

Verify you are running WSL2 (not WSL1):

wsl --list --verbose

The VERSION column should show 2. If it shows 1, see the WSL1 Fallback section below.

Enable systemd inside the Ubuntu distro (required for the Debian package method):

sudo tee /etc/wsl.conf <<'EOF'
[boot]
systemd=true
EOF

Restart WSL from PowerShell:

wsl --shutdown

Then relaunch Ubuntu from the Start menu.


Step 2: Install Docker Desktop

Download and install Docker Desktop for Windows. During setup, enable the WSL2 backend. After installation, Docker commands work from both the Windows terminal and the WSL2 Ubuntu shell.

Verify Docker is working from the Ubuntu shell:

docker --version

Step 3: Download and Configure

Open the Ubuntu WSL2 terminal and download the Docker Compose file:

curl -fsSL https://github.com/Axemere-LLC/mvgc-releases/releases/latest/download/docker-compose.postgres.yaml \
  -o docker-compose.yaml
curl -fsSL https://github.com/Axemere-LLC/mvgc-releases/releases/latest/download/default.env.example \
  -o .env

Edit .env and set all values in one pass -- admin token and your AI provider API keys:

MVGC_ADMIN_TOKEN=<your-admin-token>   # use: openssl rand -hex 32
POSTGRES_PASSWORD=mvgcpassword        # change for production

# AI provider API keys -- add any providers you want to use
OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-ant-...
VariableValue
MVGC_ADMIN_TOKENAny strong random string -- use openssl rand -hex 32
POSTGRES_PASSWORDPassword for the bundled Postgres container (defaults to mvgcpassword; change for production)
OPENAI_API_KEYYour OpenAI API key (or whichever providers you use)

Step 4: Start the Gateway

docker compose up -d

This starts:

  • The Axemere Gateway on port 7080
  • A Postgres 16 instance (data stored in a Docker volume)

Wait a few seconds for the database to initialize. Verify the gateway is healthy:

curl -s http://localhost:7080/healthz | jq .

Expected response (after a few seconds; during the first 10s you may see {"status":"starting"}):

{"status":"ok", "version":"...", "node_id":"node-local-dev", ...}

On Windows 11, services on localhost inside WSL2 are automatically forwarded to localhost on the Windows host. You can verify from PowerShell:

curl.exe -s http://localhost:7080/healthz

HTTP :7080

proxied calls

WSL2 terminal
(curl)

Axemere Gateway
(Docker on WSL2)

Postgres 16
(Docker)

AI Provider
(OpenAI / Anthropic)


Step 5: Verify Credentials

The gateway seeds credential records for all major providers automatically on first start (OpenAI, Anthropic, Gemini, Azure OpenAI, Cohere). Each credential maps a name like cred-openai to the env var you set in Step 3. No manual registration needed.

Configure the CLI and verify (run from the WSL2 shell):

mvgc config set-url http://localhost:7080
mvgc config set-token <your-admin-token>
mvgc credentials list

You should see cred-openai, cred-anthropic, and the other providers listed.

If you edit the credentials file inside the container to add a provider or change settings, reload without restarting:

mvgc credentials reload

Methods

Method 1: Base URL Replacement

Point your existing AI SDK at the gateway by overriding its base URL. The gateway forwards the request to the real provider using the API key you registered above.

Set the provider-specific base URL variable in the WSL2 shell before running your application:

# OpenAI
export OPENAI_BASE_URL=http://localhost:7080/proxy/openai
export OPENAI_API_KEY=unused   # gateway uses its stored key; value ignored

# Anthropic
export ANTHROPIC_BASE_URL=http://localhost:7080/proxy/anthropic
export ANTHROPIC_API_KEY=unused

# Gemini
export GOOGLE_API_BASE=http://localhost:7080/proxy/gemini

# Cohere
export CO_API_URL=http://localhost:7080/proxy/cohere

No .env or config change is needed. The gateway reads the /proxy/{provider}/ prefix to identify the upstream provider automatically. Supported path-prefix providers: openai, anthropic, gemini, cohere. Azure OpenAI requires the X-MVGC-Target-Host header instead (no fixed upstream hostname).

From PowerShell, set the variables before running Windows-native Python or Node.js:

$env:OPENAI_BASE_URL = "http://localhost:7080/proxy/openai"
$env:OPENAI_API_KEY  = "unused"
python my_openai_app.py

Tip: for transparent multi-provider coverage with no code changes, use Method 2.


Method 2: System Proxy

Self-hosted deployments only. SSL MITM transparent proxy is available for self-hosted gateways. It is not yet available for the Managed Gateway (Axemere-hosted); support is planned for a future release.

Configure Windows to route all AI provider traffic through the gateway automatically. No code changes required in any application -- including native Windows apps, browsers, and IDEs.

PAC → :7081
ambient traffic

AI domains only

everything else

Any Windows app
(browser, IDE, Python)

Axemere Gateway
:7080 developer
:7081 ambient

AI Providers

Internet
(DIRECT)

Step A: Enable MITM for HTTPS

Most AI APIs use HTTPS. To inspect and govern HTTPS traffic, enable MITM mode. Add to .env:

MVGC_PROXY_MITM_ENABLED=true
MVGC_MANAGED_DOMAINS=api.openai.com,api.anthropic.com,generativelanguage.googleapis.com,api.cohere.ai

Restart:

docker compose restart gateway

Step B: Install the CA Certificate (Windows)

Download the gateway's CA certificate and install it into the Windows certificate store so that all Windows applications trust the gateway's TLS interception:

# Download from the gateway
Invoke-WebRequest -Uri http://localhost:7080/v1/proxy/ca.crt -OutFile "$env:TEMP\mvgc-proxy-ca.crt"

# Install into the Trusted Root Certification Authorities store (machine-wide)
# This requires an elevated PowerShell session
Import-Certificate -FilePath "$env:TEMP\mvgc-proxy-ca.crt" `
  -CertStoreLocation Cert:\LocalMachine\Root

If you are using Firefox, it uses its own certificate store and needs the certificate added separately: Settings -- Privacy & Security -- Certificates -- View Certificates -- Authorities -- Import.

Step C: Configure the System Proxy

Use the PAC (Proxy Auto-Configuration) file served by the gateway. Windows calls this a "setup script". It routes only AI provider domains through the proxy.

Option A: via Windows Settings (GUI)

  1. Open Settings (Win + I)
  2. Go to Network & Internet -- Proxy
  3. Under Automatic proxy setup, enable Use setup script
  4. Enter the script address: http://localhost:7080/v1/proxy/proxy.pac
  5. Click Save

Option B: via PowerShell

$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $regPath -Name AutoConfigURL -Value "http://localhost:7080/v1/proxy/proxy.pac"
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 0   # PAC overrides manual proxy

Step D: Enable Port 7081

The PAC file routes ambient traffic to port 7081, a dedicated listener that tags all PAC-routed requests as traffic_class: ambient. Port 7081 is not bound by default.

Add MVGC_PAC_PROXY_ADDR=:7081 to .env, then restart:

docker compose restart gateway

Confirm port 7081 is listening from WSL2:

curl -s http://localhost:7081/healthz | jq .status

Step E: Verify

Open a browser or PowerShell and make an AI API call. The gateway intercepts it automatically. Check gateway metrics from WSL2:

curl -s http://localhost:7080/metrics | grep mvgc_requests_total

Disabling the System Proxy

Settings:

  1. Go to Settings -- Network & Internet -- Proxy
  2. Disable Use setup script

PowerShell:

$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $regPath -Name AutoConfigURL -Value ""

Method 3: Explicit Gateway API

Call the gateway's native API directly. This gives you full control over attribution (project, customer, account labels) and unlocks all governance features.

Register a workload (run from the WSL2 shell):

CLI:

cat > wl-quickstart.yaml << 'EOF'
workload_id: wl-quickstart
org_id: org-quickstart
name: Quickstart Workload
default_attribution:
  project_id: proj-quickstart
allowed_connection_types:
  - direct_api
EOF

mvgc workloads create --file wl-quickstart.yaml

API:

export MVGC_ADMIN_TOKEN="<your-admin-token>"

curl -s -X PUT http://localhost:7080/v1/admin/workloads \
  -H "MVGC-Admin-Token: $MVGC_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workload_id": "wl-quickstart",
    "org_id": "org-quickstart",
    "name": "Quickstart Workload",
    "default_attribution": {
      "project_id": "proj-quickstart"
    },
    "allowed_connection_types": ["direct_api"]
  }' | jq .

Submit a request:

curl -s -X POST http://localhost:7080/v1/actions:execute \
  -H "Content-Type: application/json" \
  -d '{
    "schema": "mvgc.action_request.v2",
    "org_id": "org-quickstart",
    "workload_id": "wl-quickstart",
    "action": {
      "type": "ai.infer",
      "method": "POST",
      "target_host": "api.openai.com",
      "target_path": "/v1/chat/completions",
      "params": {
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "Say hello in one sentence."}],
        "max_tokens": 50
      }
    },
    "attribution": {
      "project_id": "proj-quickstart"
    }
  }' | jq .

Test a policy denial (no API key needed):

curl -s -X POST http://localhost:7080/v1/actions:execute \
  -H "Content-Type: application/json" \
  -d '{
    "schema": "mvgc.action_request.v2",
    "org_id": "org-quickstart",
    "workload_id": "wl-quickstart",
    "action": {
      "type": "ai.infer",
      "method": "POST",
      "target_host": "api.example-blocked.com",
      "params": {"model": "test"}
    },
    "attribution": {"project_id": "proj-quickstart"}
  }' | jq .

Expected response (HTTP 403):

{
  "decision": "deny",
  "reason": "...",
  "request_id": "..."
}

View Records and Metrics

Every request creates an execution record regardless of which method you use:

curl -s "http://localhost:7080/v1/reports/usage?project_id=proj-quickstart" | jq .
curl -s "http://localhost:7080/v1/reports/spend?project_id=proj-quickstart" | jq .
curl -s http://localhost:7080/metrics | grep mvgc_requests_total

Load a Custom Policy

Push a policy bundle that allows only api.openai.com:

curl -s -X PUT http://localhost:7080/v1/admin/policies \
  -H "MVGC-Admin-Token: $MVGC_ADMIN_TOKEN" \
  -H "Content-Type: application/yaml" \
  --data-binary @- << 'EOF'
schema: mvgc.policy_bundle.v1
bundle_id: bundle-quickstart
version: 1.0.0
defaults:
  decision: deny
evaluation:
  order: [identity, targets, credentials, budgets, risk]
  stop_on: [deny, require_approval]
  merge_strategy: first_match
inline_rules:
  identity:
    - id: identity.allow.proxy
      priority: 100
      when:
        field: context.connection_type
        in: [connect_proxy, sdk_redirect, direct_api]
      effect:
        decision: allow
  targets:
    - id: targets.allow.openai
      priority: 100
      when:
        field: context.action.target_host
        equals: "api.openai.com"
      effect:
        decision: allow
    - id: targets.deny.others
      priority: 50
      when:
        field: context.action.target_host
        exists: true
      effect:
        decision: deny
        reason: "target host not in allowlist"
EOF

Alternative: Debian Package in WSL2

If you prefer running the gateway as a native systemd service instead of Docker, install via APT inside the WSL2 Ubuntu shell:

# 1. Install PostgreSQL
sudo apt install -y postgresql
sudo systemctl enable --now postgresql

openssl rand -hex 16   # use as password below

sudo -u postgres psql <<'EOF'
CREATE USER mvgc_gateway WITH PASSWORD '<your-generated-password>';
CREATE DATABASE mvgc_gateway OWNER mvgc_gateway;
EOF

# 2. Add the Axemere APT repository
curl -fsSL https://raw.githubusercontent.com/Axemere-LLC/mvgc-apt/main/gpg.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/mvgc.gpg

echo "deb [signed-by=/etc/apt/keyrings/mvgc.gpg arch=$(dpkg --print-architecture)] \
  https://raw.githubusercontent.com/Axemere-LLC/mvgc-apt/main stable main" \
  | sudo tee /etc/apt/sources.list.d/mvgc.list

sudo apt update && sudo apt install mvgc-gateway

# 3. Configure
sudo nano /etc/mvgc/mvgc.yaml
# Set database.url and gateway.admin_token

# 4. Start
sudo systemctl enable --now mvgc-gateway

From here, continue with Step 5: Verify Credentials above.


Known Limitations

  • WSL2 systemd quirks. If systemctl returns errors after enabling systemd, run wsl --shutdown from PowerShell and relaunch the distro.
  • Use the Linux filesystem. Keep all Axemere config and data files under the Linux filesystem (e.g., /etc/mvgc/, /var/lib/mvgc/). Windows-mounted paths (/mnt/c/...) have poor I/O performance and may break the 0600 permission requirement on Ed25519 key files.
  • SSL MITM proxy. The MVGC_PROXY_MITM_ENABLED mode works inside WSL2, but the generated CA certificate must be installed in the Windows certificate store for Windows applications to trust it (see Step B above).
  • Windows 10 networking. On Windows 10, WSL2 localhost forwarding is not automatic. Find the WSL2 VM IP with hostname -I and substitute it for localhost in the PAC URL and proxy settings.
  • Native Windows is not supported. The gateway binary is Linux-only. Use WSL2 or Docker Desktop.

WSL1 Fallback

If wsl --list --verbose shows VERSION 1, you are on WSL1 (nested virtualization unavailable, e.g., Parallels on Apple Silicon).

On WSL1:

  • Docker Desktop is the recommended path. It integrates with WSL1 without requiring systemd.
  • Binary download also works. Download the linux/amd64 tarball and run the gateway directly (./mvgc-gateway).
  • systemctl commands will not work. The gateway must be started manually.

Next Steps

TaskWhere to look
Configure credentials and policies for productionConfiguration Reference
Manage policies, approvals, and monitoringNetwork Operations Guide
Integrate your applicationDeveloper Integration Guide
Deploy to Kubernetes or the cloudIT Setup Guide
Use the managed gateway serviceManaged Gateway Guide
Understand all terms and fieldsGlossary

Cleanup

Docker Compose:

docker compose down -v   # stops containers and removes the Postgres volume

Disable system proxy (PowerShell):

$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $regPath -Name AutoConfigURL -Value ""

Remove the CA certificate (elevated PowerShell):

Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*MVGC*" } | Remove-Item

Debian package in WSL2:

sudo systemctl stop mvgc-gateway
sudo apt remove mvgc-gateway