> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Egress IP Routing & VPN

> Route API requests through dedicated static IPs for whitelisting. Use managed KnoxCall egress servers or connect your own VPN infrastructure.

# Egress IP Routing & VPN

Many APIs require whitelisting specific IP addresses. KnoxCall supports routing requests through dedicated egress servers with static IPs—either managed by KnoxCall or through your own VPN infrastructure.

## The Problem

**Dynamic IPs:**

```text theme={"dark"}
Your server: 198.51.100.50
   ↓
KnoxCall proxy: 203.0.113.100 (changes)
   ↓
Partner API: ❌ Rejects (IP not whitelisted)
```

**APIs requiring IP whitelisting:**

* Banking and financial APIs (Open Banking, Plaid)
* Government services (tax, compliance)
* Enterprise B2B integrations
* Payment processors (some configurations)
* Internal corporate APIs

## The Solution

**Static egress IP:**

```text theme={"dark"}
Your server: 198.51.100.50 (any IP)
   ↓
KnoxCall proxy → Data plane node: 203.0.113.200 (fixed)
   ↓
Partner API: ✅ Accepts (203.0.113.200 is whitelisted)
```

**Benefits:**

* ✅ Single static IP to whitelist
* ✅ Works from any source (dev, staging, prod)
* ✅ Automatic failover if egress server down
* ✅ Choose geographic region
* ✅ Multiple egress IPs per tenant (if needed)

## Types of Egress Routing

KnoxCall supports two deployment models:

### 1. Managed Egress Servers (Recommended)

**What it is:**

* KnoxCall provisions and manages egress servers for you
* Static IP provisioned in your chosen region
* Automatic health monitoring and failover
* No infrastructure management required

**When to use:**

* You need a quick, turnkey solution
* You want KnoxCall to handle operations
* You don't have existing VPN infrastructure

**Regions available** (DigitalOcean region slugs):

* 🇺🇸 `nyc3` — New York, USA
* 🇺🇸 `sfo3` — San Francisco, USA
* 🇬🇧 `lon1` — London, UK
* 🇩🇪 `fra1` — Frankfurt, Germany
* 🇳🇱 `ams3` — Amsterdam, Netherlands
* 🇦🇺 `syd1` — Sydney, Australia
* 🇸🇬 `sgp1` — Singapore

**Pricing:**

* Included in Pro and Enterprise plans
* \$29/month per additional egress server (if you need multiple regions)

### 2. Self-Hosted VPN Integration

**What it is:**

* Connect KnoxCall to your existing VPN infrastructure
* Routes traffic through your VPN gateway
* You manage the VPN server, KnoxCall just uses it

**When to use:**

* You have existing VPN infrastructure
* Compliance requires self-hosted networking
* You need specific routing or firewall rules
* You want full control over egress traffic

**Supported VPN types:**

* WireGuard
* OpenVPN
* Custom proxy servers (SOCKS5, HTTP forward proxy)

**Pricing:**

* Included in Enterprise plan
* Contact sales for availability on lower tiers

## Setting Up Managed Egress

### Step 1: Request Egress Server

1. Navigate to **Proxy** → **Static IPs** (cloud-hosted KnoxCall only — this page is hidden on self-hosted deployments)
2. Click **Request Static IP**
3. Configure:

```yaml theme={"dark"}
Type: shared        # or "dedicated" (Enterprise only)
Region: nyc3        # DigitalOcean region slug — New York
```

4. Click **Request**

### Step 2: Wait for Provisioning

KnoxCall automatically:

* Creates a DigitalOcean Droplet in your region
* Configures forward proxy software
* Assigns a static IP (reserved IP)
* Sets up health checks
* Registers in data plane registry

**Typical provisioning time:** 2-3 minutes

### Step 3: Note Your Static IP

After provisioning completes:

```text theme={"dark"}
Egress Server: US East Egress
├─ Status: ✅ Active
├─ Region: nyc3 (New York, USA)
├─ Egress IP: 203.0.113.200
├─ Last seen: 12 seconds ago
└─ Routes using: 0
```

**Share this IP** with your API provider for whitelisting.

### Step 4: Assign to Routes

Configure which routes use the egress server:

**Option A: Per-environment (recommended)**

1. Go to route detail page
2. Select environment (e.g., "production")
3. Scroll to **Advanced** → **Egress Routing**
4. Select egress server: "US East Egress"
5. Save

**Option B: Via API**

```http theme={"dark"}
PUT /admin/routes/{route_id}/egress

{
  "egress_server_id": "<egress-server-uuid>"
}
```

Pass `egress_server_id: null` to remove the egress assignment and revert the route to direct routing.

### Step 5: Test & Verify

Make a test request through your route:

```bash theme={"dark"}
curl https://yourapp.com/api/v1/proxy/your-route \
  -H "Authorization: Bearer your-token"
```

Check the API provider's logs to confirm they see requests from `203.0.113.200`.

## Setting Up Self-Hosted VPN

### Prerequisites

* VPN server (WireGuard or OpenVPN)
* VPN configuration file or credentials
* Network access from KnoxCall servers

### Step 1: Prepare VPN Configuration

**WireGuard example:**

```ini theme={"dark"}
[Interface]
PrivateKey = <your-private-key>
Address = 10.0.0.2/24

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.yourcompany.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
```

**OpenVPN example:**

```text theme={"dark"}
client
dev tun
proto udp
remote vpn.yourcompany.com 1194
ca ca.crt
cert client.crt
key client.key
```

### Step 2: Register VPN in KnoxCall

1. Navigate to the **VPN** page and click **Create VPN Connection** → **My Own VPN**
2. Choose your VPN type (WireGuard, OpenVPN, or custom proxy)
3. Configure:

```yaml theme={"dark"}
Name: Corporate VPN
Type: wireguard
Configuration: (paste WireGuard config)
Egress IP: 203.0.113.200 (your VPN's egress IP)
Health Check URL: https://vpn-health.yourcompany.com/ping (optional)
```

4. Click **Save**

### Step 3: Test Connection

KnoxCall will:

* Establish VPN tunnel
* Perform health check (if configured)
* Report connectivity status

```text theme={"dark"}
VPN Node: Corporate VPN
├─ Status: ✅ Connected
├─ Type: WireGuard
├─ Egress IP: 203.0.113.200
├─ Last seen: 5 seconds ago
├─ Health: Healthy (200 OK)
└─ Routes using: 0
```

### Step 4: Assign to Routes

Assign the VPN node to a route from the route detail page under **Advanced** → **Egress Routing**.

## Advanced Configuration

### Multiple Egress Servers per Tenant

Use different egress IPs for different APIs:

```text theme={"dark"}
Egress Servers:
├─ US East Egress (203.0.113.200)
│    Routes: Stripe, Twilio
│
├─ EU West Egress (198.51.100.50)
│    Routes: European banking APIs
│
└─ Corporate VPN (192.0.2.100)
     Routes: Internal partner APIs
```

**Configuration:**

* Route A (Stripe) → uses US East Egress
* Route B (European bank) → uses EU West Egress
* Route C (partner) → uses Corporate VPN

### Failover & High Availability

**Managed egress servers:**

* Automatic health monitoring (every 30 seconds)
* If unhealthy, routes fall back to direct routing
* Email alerts on failover
* Auto-recovery when health restored

**Self-hosted VPN:**

* Manual health check URL (optional)
* No automatic failover unless configured
* You're responsible for VPN uptime

### Regional Routing

Route requests through the closest region to the destination API:

```text theme={"dark"}
Your app in US → Stripe API in US
  ↓ uses US East Egress (low latency)

Your app in US → European Bank API in EU
  ↓ uses EU West Egress (compliance + latency)
```

## Security Considerations

### Managed Egress Servers

**Isolation:**

* Dedicated Droplet per egress server (not shared)
* Firewall rules restrict traffic to your routes only
* No direct SSH access (managed via API)

**Authentication:**

* Requests authenticated with tenant-specific secret
* HMAC signature verification
* Replay attack prevention

**Monitoring:**

* All traffic logged
* Health checks every 30 seconds
* Alerts on anomalies

### Self-Hosted VPN

**Security checklist:**

* [ ] VPN credentials stored encrypted in KnoxCall
* [ ] Firewall allows only KnoxCall server IPs
* [ ] VPN configuration doesn't expose internal network
* [ ] Health check endpoint authenticated (if public)
* [ ] Egress traffic monitored on your side

**Network isolation:**

* Ensure VPN tunnel doesn't grant KnoxCall access to internal network
* Use split tunneling (only route API traffic through VPN)
* Configure firewall rules on VPN gateway

## Monitoring & Troubleshooting

### Health Status

**Managed egress servers** — run an on-demand health check:

```http theme={"dark"}
GET /admin/egress/{server_id}/health

Response:
{
  "server_id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
  "healthy": true,
  "checked_at": "2025-01-20T15:30:00Z"
}
```

**Self-hosted VPN nodes** — read the node's current status:

```http theme={"dark"}
GET /admin/data-plane-nodes/{id}

Response:
{
  "id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
  "status": "active",
  "last_seen_at": "2025-01-20T15:30:00Z",
  "health_check_url": "https://vpn-health.corp.com/ping",
  "egress_ip": "203.0.113.200",
  "region": "nyc3"
}
```

IDs are UUIDs. To actively test a self-hosted node's connectivity, call `POST /admin/data-plane-nodes/{id}/test`.

**Status values:**

* `active` - Healthy and routing traffic ✅
* `unhealthy` - Failed health check ⚠️
* `unreachable` - Cannot connect 🔴
* `unknown` - Status not yet determined 🔄

### Request Logs

View which requests used egress routing:

```http theme={"dark"}
GET /admin/logs

Response:
{
  "logs": [
    {
      "route_id": "3a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
      "data_plane_node_id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
      "egress_ip": "203.0.113.200",
      "target_url": "https://api.stripe.com/v1/charges",
      "status": 200,
      "timestamp": "2025-01-20T15:30:00Z"
    }
  ]
}
```

### Common Issues

**Problem: "Egress server unreachable"**

```text theme={"dark"}
Routes using this server fall back to direct routing
```

**Solutions:**

1. Check server status in dashboard
2. If managed: wait 2-3 min for auto-recovery
3. If self-hosted: verify VPN server is running
4. Check firewall allows KnoxCall IPs

**Problem: "API still rejecting IP"**

```text theme={"dark"}
API provider claims IP is not whitelisted
```

**Debug steps:**

1. Verify correct egress server assigned to route
2. Check route's environment is correct
3. Test with: `curl https://ifconfig.me/ip` through egress server
4. Confirm API provider whitelisted the right IP
5. Check for typos in IP address (common!)

**Problem: "Latency increased after enabling egress"**

```text theme={"dark"}
Requests now take 200ms longer
```

**Causes:**

* Egress server in wrong region (e.g., US egress for EU API)
* VPN has high latency

**Solutions:**

* Use egress server closest to destination API
* For self-hosted VPN: measure VPN latency
* Consider multiple regional egress servers

**Problem: "VPN connection keeps dropping"**

```text theme={"dark"}
Self-hosted VPN shows "unreachable" intermittently
```

**Solutions:**

1. Check VPN server logs for disconnections
2. Increase WireGuard PersistentKeepalive value
3. Configure health check to detect failures faster
4. Ensure firewall isn't blocking keep-alive packets

## Cost Optimization

### When to Use Egress Routing

**Use egress when:**

* ✅ API requires IP whitelisting
* ✅ You need consistent source IP for logging/audit
* ✅ Compliance mandates specific egress points
* ✅ API has regional restrictions

**Skip egress when:**

* ❌ API doesn't require IP whitelisting
* ❌ Added latency is critical (use direct routing)
* ❌ Route has very high traffic (cheaper to provision own server)

### Multi-Tenant Cost Sharing

For enterprise deployments with many routes:

```text theme={"dark"}
Option A: Separate egress per route
  → 10 routes = 10 egress servers = $290/month

Option B: Shared egress server
  → 10 routes = 1 egress server = $29/month
  → All use same egress IP
```

Most APIs accept multiple routes from same IP, so Option B is usually fine.

## API Reference

Managed egress servers have their own API surface under `/admin/egress`. The data-plane-node endpoints (`/admin/data-plane-nodes`) are for self-hosted VPN nodes. All of these endpoints are cloud-mode only.

#### Supporting endpoints

```http theme={"dark"}
GET /admin/egress/regions              # list available DigitalOcean regions
GET /admin/egress/pricing              # shared / dedicated monthly pricing
GET /admin/egress/availability/{region}  # is a shared server available now?
```

### Request a Managed Egress IP

```http theme={"dark"}
POST /admin/egress

{
  "type": "shared",   // "shared" or "dedicated" (dedicated = Enterprise)
  "region": "nyc3"    // DigitalOcean region slug (default: syd1)
}

Response:
{
  "ok": true,
  "message": "No shared server available in this region. Provisioning new server (2-3 minutes).",
  "is_provisioning": true,
  "egress_server": {
    "id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
    "ip_address": null,
    "region": "nyc3",
    "type": "shared",
    "status": "provisioning"
  }
}
```

Polling for completion:

```http theme={"dark"}
GET /admin/egress

Response (when ready):
{
  "egress_servers": [
    {
      "id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
      "status": "active",
      "reserved_ip": "203.0.113.200",
      "region": "nyc3"
    }
  ]
}
```

If provisioning fails, retry with `POST /admin/egress/{server_id}/retry`.

### Register Self-Hosted VPN

`region`, `kind`, and `display_name` are required. `kind` must be `managed` or `self_hosted`; `vpn_type` (when present) must be `wireguard`, `openvpn`, or `custom`. `vpn_config_json` is a free-form blob stored verbatim — its shape is not validated, so the keys below are just an example.

```http theme={"dark"}
POST /admin/data-plane-nodes

{
  "kind": "self_hosted",
  "region": "nyc3",
  "display_name": "Corporate VPN",
  "vpn_type": "wireguard",
  "vpn_config_json": {
    "interface": {
      "private_key": "...",
      "address": "10.0.0.2/24"
    },
    "peer": {
      "public_key": "...",
      "endpoint": "vpn.corp.com:51820",
      "allowed_ips": "0.0.0.0/0"
    }
  },
  "egress_ip": "203.0.113.200",
  "health_check_url": "https://vpn-health.corp.com/ping"
}

Response:
{
  "id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
  "status": "unknown",
  ...
}
```

The response returns the full node row; `id` is a UUID.

### Update / Test a Self-Hosted Node

```http theme={"dark"}
PUT  /admin/data-plane-nodes/{id}        # update node fields (partial; fields are COALESCEd)
POST /admin/data-plane-nodes/{id}/test   # test VPN connectivity → { healthy, status, last_seen_at }
```

### Assign Egress Server to a Route

```http theme={"dark"}
PUT /admin/routes/{route_id}/egress

{
  "egress_server_id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b"
}
```

Send `"egress_server_id": null` to clear the assignment and revert to direct routing.

### List Managed Egress Servers

```http theme={"dark"}
GET /admin/egress

Response:
{
  "egress_servers": [
    {
      "id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
      "reserved_ip": "203.0.113.200",
      "region": "nyc3",
      "type": "shared",
      "status": "active"
    }
  ]
}
```

Self-hosted VPN nodes are listed separately via `GET /admin/data-plane-nodes` (returns `{ "nodes": [...] }`).

### Release a Managed Egress Server

```http theme={"dark"}
DELETE /admin/egress/{server_id}

Response:
{
  "ok": true,
  "message": "Egress IP allocation released"
}
```

A server cannot be released while any route still uses it (returns `400` with `routes_using`).

### Check Managed Egress Health

```http theme={"dark"}
GET /admin/egress/{server_id}/health

Response:
{
  "server_id": "9f1c0e2a-3b4d-5e6f-7a8b-9c0d1e2f3a4b",
  "healthy": true,
  "checked_at": "2025-01-20T15:30:00Z"
}
```

## Best Practices

### ✅ Do This

1. **Test with dummy route first**
   * Create test route, assign egress, verify IP
   * Don't configure production routes immediately

2. **Document which API requires which IP**
   * Keep spreadsheet of API → egress IP mappings
   * Share with team for future reference

3. **Set up alerts**
   * Email when egress server goes unhealthy
   * Monitor latency changes

4. **Use regional egress servers**
   * Match egress region to API region when possible
   * Reduces latency

5. **Keep egress credentials secure**
   * For self-hosted VPN, treat credentials as secrets
   * Rotate VPN keys quarterly

### ❌ Avoid This

1. **Don't use same egress for unrelated APIs**
   * If one API blocks your IP, all routes affected
   * Use separate egress servers for high-risk APIs

2. **Don't skip health checks for self-hosted VPN**
   * You'll only discover downtime when users complain
   * Set up health check URL

3. **Don't delete egress server while routes use it**
   * Routes will fall back to direct routing
   * May break IP whitelisting

4. **Don't expose internal network via VPN**
   * Use split tunneling
   * Firewall VPN gateway appropriately

## Migration Guide

### From Direct Routing to Egress

**Before:**

```text theme={"dark"}
Route → Direct → API
(source IP changes)
```

**After:**

```text theme={"dark"}
Route → Egress Server → API
(source IP: 203.0.113.200)
```

**Steps:**

1. Provision egress server
2. Get static IP
3. Contact API provider to whitelist IP
4. Wait for confirmation (don't skip!)
5. Assign egress to route (test environment first)
6. Test
7. Assign to production
8. Monitor

**Rollback plan:**

* Clear the egress assignment (`PUT /admin/routes/{route_id}/egress` with `"egress_server_id": null`)
* Traffic reverts to direct routing

## Next Steps

<CardGroup cols={2}>
  <Card title="Multi-Region Deployment" icon="globe" href="/infrastructure/multi-region">
    Deploy KnoxCall across regions
  </Card>

  <Card title="Route Configuration" icon="route" href="/essentials/routes/creating-routes">
    Learn about route setup
  </Card>

  <Card title="Monitoring" icon="chart-line" href="/monitoring/analytics">
    Monitor egress server health
  </Card>

  <Card title="Security" icon="shield" href="/security/securing-your-routes">
    Secure your routes
  </Card>
</CardGroup>

***

<CardGroup cols={2}>
  <Card title="📊 Guide Info" icon="info-circle">
    * **Level**: Intermediate to Advanced
    * **Time**: 15-30 minutes
    * **Prerequisites**: Understanding of IP whitelisting and networking
  </Card>

  <Card title="🏷️ Tags" icon="tags">
    `egress`, `vpn`, `networking`, `ip-whitelisting`, `infrastructure`
  </Card>
</CardGroup>
