Skip to main content

Airgap Deployment

Airgap Deployment lets you run SureStage in completely offline or air-gapped environments with no internet connectivity. Use a single self-contained binary with an embedded SQLite database for secure, isolated API mocking.

What is Airgap Deployment?

Airgap Deployment packages the core SureStage mock engine and protocol server into a single executable that:

  • Runs completely offline (no external dependencies)
  • Uses SQLite instead of PostgreSQL (no separate database server required)
  • Has no authentication layer (designed for secure network perimeters)
  • Includes all necessary components in one binary

This is ideal for:

  • Secure government or defense environments
  • Regulated industries (healthcare, finance) with strict data isolation
  • Development in offline or restricted networks
  • Edge computing scenarios

Architecture Differences

FeatureCloud/StandardAirgap
DatabasePostgreSQLSQLite
AuthenticationJWT + OAuthNone (NoopAuthGuard)
Multi-TenancyFull isolationSingle Tenant mode
Rate Limiting1000 req/min120 req/min
External ServicesOptionalNone
UpdatesAutomaticManual

Installation

Download Binary

Download the latest airgap binary for your platform:

# Linux
curl -L https://releases.surestage.com/airgap/latest/surestage-airgap-linux-amd64 -o surestage-airgap
chmod +x surestage-airgap

# macOS
curl -L https://releases.surestage.com/airgap/latest/surestage-airgap-darwin-amd64 -o surestage-airgap
chmod +x surestage-airgap

# Windows
curl -L https://releases.surestage.com/airgap/latest/surestage-airgap-windows-amd64.exe -o surestage-airgap.exe

Verify Checksum

# Download checksum file
curl -L https://releases.surestage.com/airgap/latest/checksums.txt -o checksums.txt

# Verify (Linux/macOS)
sha256sum -c checksums.txt

# Verify (Windows)
CertUtil -hashfile surestage-airgap.exe SHA256

Configuration

Configure the airgap deployment using environment variables.

Required Configuration

# Database file path
export AIRGAP_DB_PATH=/var/lib/surestage/airgap.db

# Server port (default: 3000)
export AIRGAP_PORT=3000

# Host to bind to (default: 0.0.0.0)
export AIRGAP_HOST=127.0.0.1

Optional Configuration

# Rate limit (requests per minute, default: 120)
export AIRGAP_RATE_LIMIT=200

# Log level (debug, info, warn, error, default: info)
export AIRGAP_LOG_LEVEL=info

# Enable request logging (default: false)
export AIRGAP_LOG_REQUESTS=true

# Max database size in MB (default: 1000)
export AIRGAP_DB_MAX_SIZE=2000

Running the Server

Start the Server

./surestage-airgap

Output

[INFO] SureStage Airgap v1.0.0
[INFO] Database: /var/lib/surestage/airgap.db
[INFO] Server listening on http://127.0.0.1:3000
[INFO] Rate limit: 120 requests/minute
[INFO] Authentication: Disabled (NoopAuthGuard)
[INFO] Ready to serve requests

Run as Background Service

Linux (systemd)

Create a systemd service file:

sudo nano /etc/systemd/system/surestage-airgap.service

Service Configuration

[Unit]
Description=SureStage Airgap Mock Server
After=network.target

[Service]
Type=simple
User=surestage
Group=surestage
WorkingDirectory=/opt/surestage
Environment="AIRGAP_DB_PATH=/var/lib/surestage/airgap.db"
Environment="AIRGAP_PORT=3000"
ExecStart=/opt/surestage/surestage-airgap
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Start Service

sudo systemctl daemon-reload
sudo systemctl enable surestage-airgap
sudo systemctl start surestage-airgap
sudo systemctl status surestage-airgap

macOS (launchd)

Create a launch agent:

nano ~/Library/LaunchAgents/com.surestage.airgap.plist

Launch Agent Configuration

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.surestage.airgap</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/surestage-airgap</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>AIRGAP_DB_PATH</key>
<string>/var/lib/surestage/airgap.db</string>
<key>AIRGAP_PORT</key>
<string>3000</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>

Load Service

launchctl load ~/Library/LaunchAgents/com.surestage.airgap.plist
launchctl start com.surestage.airgap

Windows (Service)

Use NSSM (Non-Sucking Service Manager):

# Install NSSM
choco install nssm

# Install service
nssm install SureStageAirgap "C:\Program Files\SureStage\surestage-airgap.exe"
nssm set SureStageAirgap AppEnvironmentExtra AIRGAP_DB_PATH=C:\ProgramData\SureStage\airgap.db
nssm set SureStageAirgap AppEnvironmentExtra AIRGAP_PORT=3000

# Start service
nssm start SureStageAirgap

Using the Airgap Server

Create a Sandbox

curl -X POST http://localhost:3000/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"name": "My Mock API",
"description": "Offline mock API"
}'

Response 201 Created

{
"id": "sim_local123",
"name": "My Mock API",
"baseUrl": "http://localhost:3000/mock/sim_local123",
"status": "active"
}

Create a Route

curl -X POST http://localhost:3000/v1/simulations/sim_local123/routes \
-H "Content-Type: application/json" \
-d '{
"method": "GET",
"path": "/users/:id",
"response": {
"status": 200,
"body": {
"id": "{{params.id}}",
"name": "John Doe"
}
}
}'

Test the Mock

curl http://localhost:3000/mock/sim_local123/users/123

Response 200 OK

{
"id": "123",
"name": "John Doe"
}

Database Management

Backup Database

# Stop server first
sudo systemctl stop surestage-airgap

# Copy database file
cp /var/lib/surestage/airgap.db /backup/airgap-$(date +%Y%m%d).db

# Restart server
sudo systemctl start surestage-airgap

Restore Database

# Stop server
sudo systemctl stop surestage-airgap

# Restore backup
cp /backup/airgap-20260321.db /var/lib/surestage/airgap.db

# Restart server
sudo systemctl start surestage-airgap

Export Mocks

Export mock definitions to YAML for migration or backup:

curl http://localhost:3000/v1/simulations/sim_local123/export > mocks.yaml

Import Mocks

Import mock definitions from YAML:

curl -X POST http://localhost:3000/v1/simulations/import \
-H "Content-Type: application/x-yaml" \
--data-binary @mocks.yaml

Limitations

No Authentication

The airgap server uses NoopAuthGuard, meaning all requests are unauthenticated. Deploy only in secure network perimeters where access is controlled by:

  • Network segmentation
  • Firewall rules
  • VPN access
  • Physical security

Never expose an airgap server to the public internet.

Lower Rate Limits

Default rate limit is 120 requests/minute (vs 1000 req/min for cloud):

# Increase if needed
export AIRGAP_RATE_LIMIT=500

Single Tenant Only

Airgap mode operates as a single Tenant. Multi-Tenancy features are disabled:

  • No Tenant isolation
  • No organization management
  • No user roles

No External Integrations

Features requiring external services are unavailable:

  • Git Sync
  • OAuth authentication
  • Webhook delivery
  • Email notifications
  • External schema registries

Security Considerations

Network Isolation

  • Deploy behind firewalls
  • Use VPN for remote access
  • Restrict to trusted internal networks
  • Monitor access logs

File Permissions

# Secure database file
chmod 600 /var/lib/surestage/airgap.db
chown surestage:surestage /var/lib/surestage/airgap.db

# Secure binary
chmod 755 /opt/surestage/surestage-airgap
chown root:root /opt/surestage/surestage-airgap

Logging

Enable request logging for security audits:

export AIRGAP_LOG_REQUESTS=true

Logs include:

  • Request timestamp
  • Source IP
  • HTTP method and path
  • Response status
  • Duration

Updates

Updates must be manual:

  1. Download new binary
  2. Stop service
  3. Replace binary
  4. Start service

Database migrations run automatically on startup.

Monitoring

Health Check

curl http://localhost:3000/health

Response 200 OK

{
"status": "healthy",
"version": "1.0.0",
"database": {
"type": "sqlite",
"size": "12.4 MB",
"routeCount": 156
},
"uptime": 86400,
"requestsServed": 45123
}

Metrics Endpoint

curl http://localhost:3000/metrics

Response 200 OK

# HELP surestage_requests_total Total requests served
# TYPE surestage_requests_total counter
surestage_requests_total{method="GET",status="200"} 32145
surestage_requests_total{method="POST",status="201"} 8567

# HELP surestage_request_duration_seconds Request duration
# TYPE surestage_request_duration_seconds histogram
surestage_request_duration_seconds_bucket{le="0.01"} 38542
surestage_request_duration_seconds_bucket{le="0.05"} 40123

Metrics are compatible with Prometheus.

Troubleshooting

Problem: Server won't start

Solution: Check database file permissions and disk space. Verify port 3000 is not in use.

Problem: Database file too large

Solution: Export mocks to YAML, delete old database, import mocks to fresh database.

Problem: Rate limit exceeded

Solution: Increase AIRGAP_RATE_LIMIT environment variable or spread requests over time.