Quickstart: macOS
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 macOS in about 10 minutes using Homebrew.
Choose Your Setup Method
Pick the method that best fits how you want to use the gateway:
| Method | Code changes | Providers covered | Best for |
|---|---|---|---|
| 1. Base URL | One env var per SDK | One at a time | Quick test of a single provider |
| 2. System Proxy | None | All AI providers | Home use -- centralize all your API keys |
| 3. Explicit API | New HTTP calls | Any | Production, teams, full attribution |
Jump to: Method 1 | Method 2 -- Recommended | Method 3
Table of Contents
- Prerequisites
- Steps
- Methods
- View Records and Metrics
- Load a Custom Policy
- Using the Managed Gateway
- Next Steps
- Cleanup
Prerequisites
- Apple Silicon Mac (M1 / M2 / M3 / M4). Intel Mac users should use the Docker method on Linux or Docker Desktop instead.
- Homebrew installed. If you do not have it:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - A GitHub personal access token (classic,
reposcope) with read access toAxemere-LLC/homebrew-tapandAxemere-LLC/mvgc-releases. The tap is currently private; this requirement will be removed when the product goes public. - 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: Install PostgreSQL
The gateway requires PostgreSQL 15+. Install it locally with Homebrew:
brew install postgresql@16 brew services start postgresql@16
Add the PostgreSQL binaries to your PATH:
export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"
Wait for Postgres to be ready, then create the database:
pg_isready -q && createuser -s mvgc_gateway && createdb -O mvgc_gateway mvgc_gateway
Step 2: Install the Gateway
Set your GitHub token so Homebrew can access the private tap:
export HOMEBREW_GITHUB_API_TOKEN=<your-github-pat>
Install the gateway:
brew tap Axemere-LLC/tap brew install mvgc-gateway
Step 3: Configure and Start
Generate a strong admin token first:
openssl rand -hex 32
Edit the config file:
nano $(brew --prefix)/etc/mvgc/mvgc.yaml
Set all fields in one pass: database, admin token, and your AI provider API keys:
database: # Format: postgres://<user>[:<password>]@<host>[:<port>]/<database>?sslmode=<disable|require> url: "postgres://mvgc_gateway@localhost:5432/mvgc_gateway?sslmode=disable" gateway: admin_token: "<your-secret-admin-token>" # AI provider API keys -- add any providers you want to use env: OPENAI_API_KEY: "sk-..." # ANTHROPIC_API_KEY: "sk-ant-..."
Start the gateway:
brew services start mvgc-gateway
Verify it 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", ...}
Step 4: 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:
mvgc config set-url http://localhost:7080 mvgc config set-token <your-secret-admin-token> mvgc credentials list
You should see cred-openai, cred-anthropic, and the other providers listed.
If you edit $(brew --prefix)/var/mvgc/configs/credentials/credentials.yaml to add a
provider or change settings, reload without restarting:
mvgc credentials reload
Step 5: Install the Console Dashboard (optional)
The console provides a browser-based dashboard for monitoring requests, managing policies, credentials, and provider integrations.
brew install mvgc-console CONSOLE_GATEWAY_URL=http://localhost:7080 brew services start mvgc-console open http://localhost:7091
To set a password (default is no auth):
brew services stop mvgc-console CONSOLE_GATEWAY_URL=http://localhost:7080 CONSOLE_PASSWORD=<your-password> brew services start mvgc-console
See macOS IT Setup: Console for upgrade, log paths, and stop instructions.
Methods
Method 1: Base URL Replacement
Point your existing AI SDK at the gateway by overriding its base URL. The gateway resolves
the provider from the /proxy/{provider}/ path prefix and forwards the request using the
API key you registered in Step 4.
Set the provider-specific base URL variable before running your application:
# Anthropic export ANTHROPIC_BASE_URL=http://localhost:7080/proxy/anthropic export ANTHROPIC_API_KEY=unused # gateway uses its stored key; value ignored # OpenAI export OPENAI_BASE_URL=http://localhost:7080/proxy/openai export OPENAI_API_KEY=unused # Gemini export GOOGLE_API_BASE=http://localhost:7080/proxy/gemini # Cohere export CO_API_URL=http://localhost:7080/proxy/cohere
The gateway reads the /proxy/{provider}/ prefix to identify the upstream provider. No
gateway config change is needed. Supported path-prefix providers: openai, anthropic,
gemini, cohere. Azure OpenAI requires the X-MVGC-Target-Host header instead (no fixed
upstream hostname).
Then run your application as normal. The gateway intercepts the call, applies policy, and forwards it to the correct provider with the stored credential.
Tip: for transparent multi-provider coverage with no code changes at all, 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 macOS to route all AI provider traffic through the gateway automatically. No code changes required in any application.
Step A: Enable MITM for HTTPS
Most AI APIs use HTTPS. To inspect and govern HTTPS traffic, enable MITM mode and set your managed domains in the config:
# $(brew --prefix)/etc/mvgc/mvgc.yaml gateway: proxy_mitm_enabled: true managed_domains: "api.openai.com,api.anthropic.com,generativelanguage.googleapis.com,api.cohere.ai"
Restart the gateway:
brew services restart mvgc-gateway
Step B: Install the CA Certificate
Download and install the gateway's CA certificate so macOS trusts its TLS interception:
# Download the certificate curl -o /tmp/mvgc-proxy-ca.crt http://localhost:7080/v1/proxy/ca.crt # Add to macOS Keychain and mark as trusted sudo security add-trusted-cert -d -r trustRoot \ -k /Library/Keychains/System.keychain /tmp/mvgc-proxy-ca.crt
Step C: Configure the System Proxy
Use the PAC (Proxy Auto-Configuration) file served by the gateway. This routes only AI provider domains through the proxy -- everything else goes directly to the internet.
Option A: via System Settings (GUI)
- Open System Settings (Apple menu)
- Go to Network -- select your Wi-Fi or Ethernet -- click Details
- Click the Proxies tab
- Enable Automatic Proxy Configuration
- Enter the URL:
http://localhost:7080/v1/proxy/proxy.pac - Click OK
Option B: via Terminal
# Replace "Wi-Fi" with your active network interface name networksetup -setautoproxyurl "Wi-Fi" "http://localhost:7080/v1/proxy/proxy.pac" networksetup -setautoproxystate "Wi-Fi" on
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 pac_proxy_addr to $(brew --prefix)/etc/mvgc/mvgc.yaml:
gateway: pac_proxy_addr: ":7081"
Restart the gateway:
brew services restart mvgc-gateway
Confirm port 7081 is listening:
curl -s http://localhost:7081/healthz | jq .status
Alternative:
mvgc-gateway installautomates Steps B–D: it installs the CA certificate, configures the system proxy, writespac_proxy_addr: ":7081"to the config, and restarts the gateway. Runmvgc-gateway verifyafterwards to confirm port 7081 is bound.
Step E: Verify
Make an AI API call using your existing tooling. The gateway intercepts it, applies policy, and forwards it with the stored credential:
# curl uses the system proxy automatically curl -s https://api.openai.com/v1/models \ -H "Authorization: Bearer unused"
Check gateway metrics to confirm traffic is flowing through:
curl -s http://localhost:7080/metrics | grep mvgc_requests_total
App Coverage Notes
Most AI desktop apps and CLI tools respect macOS system proxy settings and are captured automatically once the PAC file is configured. There is one known exception:
ChatGPT Desktop (macOS) is not captured by the ambient proxy. The app uses a custom
networking stack that bypasses macOS system proxy settings, including PAC files and
HTTPS_PROXY environment variables. This is a limitation of the app, not the gateway.
Full coverage of ChatGPT Desktop requires a macOS Network Extension (planned for a future
release).
ChatGPT via web browser (chatgpt.com) is captured normally. Browsers respect system proxy settings, so any browser-based AI session routes through the gateway as expected.
Disabling the System Proxy
networksetup -setautoproxystate "Wi-Fi" off
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 first:
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-secret-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 .
A successful response returns HTTP 200 with the AI provider's response wrapped in the Axemere Gateway execution envelope.
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
Using the Managed Gateway
If your organization uses Axemere's managed gateway service, you do not need to install or configure anything locally. Requests are sent directly to the managed endpoint.
Prerequisites:
- An API key from your organization admin (created via
OrgService.CreateAPIKey)
Endpoint: https://us.gw.axemere.ai
Authentication: Include your API key as a Bearer token in every request.
Example:
curl -s -X POST https://us.gw.axemere.ai/v1/actions:execute \ -H "Authorization: Bearer mvgc_k_<your-api-key>" \ -H "Content-Type: application/json" \ -d '{ "schema": "mvgc.action_request.v2", "workload_id": "my-app", "action": { "type": "ai.infer", "method": "POST", "target_host": "api.openai.com", "params": {"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hello"}]} } }'
TLS is provided by the managed endpoint -- no client certificates needed. The org_id is
derived from your API key automatically.
See the Managed Gateway Guide for the full reference including policy overlays, metering, and troubleshooting.
Next Steps
| Task | Where to look |
|---|---|
| Configure credentials and policies for production | Configuration Reference |
| Manage policies, approvals, and monitoring | Network Operations Guide |
| Integrate your application | Developer Integration Guide |
| Deploy to Kubernetes or the cloud | IT Setup Guide |
| Use the managed gateway service | Managed Gateway Guide |
| Understand all terms and fields | Glossary |
Cleanup
Stop the gateway and PostgreSQL:
brew services stop mvgc-gateway brew services stop postgresql@16
Remove the system proxy setting:
networksetup -setautoproxystate "Wi-Fi" off
Remove the CA certificate from the system keychain (if installed):
sudo security delete-certificate -c "Axemere Gateway Proxy CA" /Library/Keychains/System.keychain
To uninstall completely:
brew uninstall mvgc-gateway brew uninstall postgresql@16 dropdb mvgc_gateway 2>/dev/null dropuser mvgc_gateway 2>/dev/null