SAFEVEIL
Safeveil documentation

Run your own route.Keep the gateway in your hands.

Deploy the Safeveil WireGuard gateway scaffold, provision client peers, add locations, and operate the control plane responsibly.

i
Know what you are deploying.

The public website is a presentation and control interface. A real VPN tunnel exists only after this repository is installed on a Linux VPS you control. This scaffold is not a completed security audit or a hosted consumer VPN service.

01 / Overview

Two parts, one private route.

Safeveil combines a static presentation and control interface in dist/ with a single-node WireGuard gateway and provisioning API in gateway/. WireGuard provides the encrypted tunnel. The Node.js control service creates and revokes peers while remaining bound to loopback behind an HTTPS reverse proxy.

Website and console

Static pages explain the concept, select a location, and administer a deployed gateway.

Gateway control plane

A minimal authenticated API manages WireGuard peer records and produces standard client configurations.

Your infrastructure

You supply the Linux VPS, public IPv4 address, DNS, monitoring, backups, and operational controls.

02 / Deployment

Deploy to a clean VPS.

Use Debian 12 or Ubuntu 22.04/24.04 with a public IPv4 address. Before installation, create a DNS A record pointing to the server and allow 80/tcp, 443/tcp, and 51820/udp.

Required environment

export UNTRACE_DOMAIN="vpn.example.com"
export UNTRACE_ADMIN_EMAIL="admin@example.com"
export UNTRACE_ADMIN_TOKEN="$(openssl rand -base64 48)"

sudo --preserve-env=UNTRACE_DOMAIN,UNTRACE_ADMIN_EMAIL,UNTRACE_ADMIN_TOKEN \
  bash gateway/bootstrap.sh

The installer configures WireGuard, the loopback control service, NGINX, TLS through Certbot, firewall-compatible ports, and the static website. Keep the generated administrator token in a password manager; never commit it or share it in screenshots or support messages.

03 / Client setup

Provision a WireGuard peer.

  1. Open https://vpn.example.com/console.html.
  2. Enter the gateway origin and the administrator token used during deployment.
  3. Create a uniquely named peer and download the generated .conf file.
  4. Import the configuration into an official WireGuard client for Windows, macOS, iOS, Android, or Linux.

The peer private key is returned once inside the downloaded configuration and is not stored in the peer database. If that file is lost, revoke the peer and create a replacement.

04 / Locations

Add country gateways.

Deploy one VPS per country or region. Give each deployment a unique location ID, display name, domain, and WireGuard endpoint. Then edit dist/locations.json, set that location’s available value to true, and point controlUrl to its HTTPS origin.

export UNTRACE_LOCATION_ID="de"
export UNTRACE_LOCATION_NAME="Germany · Frankfurt"
export UNTRACE_WG_ENDPOINT="vpn-de.example.com:51820"
export UNTRACE_SITE_ORIGIN="https://safeveil.example.com"
05 / API

Minimal control-plane API.

All responses use JSON. Administrative endpoints require Authorization: Bearer <token>. The public health endpoint does not require authorization.

MethodEndpointPurposeAuth
GET/api/healthService and configured-location healthPublic
GET/api/statusInterface, endpoint, location, and live peer stateBearer
GET/api/peersList stored peer recordsBearer
POST/api/peersCreate a peer and return its one-time client configurationBearer
DELETE/api/peers/:idRevoke and remove a peerBearer

Create a peer

curl -X POST "https://vpn.example.com/api/peers" \
  -H "Authorization: Bearer $UNTRACE_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Laptop","locationId":"de"}'
06 / Configuration

Gateway environment.

VariableDefaultMeaning
UNTRACE_BIND127.0.0.1Control API bind address
UNTRACE_PORT8787Loopback control API port
UNTRACE_ADMIN_TOKENRequiredAdministrator bearer token, minimum 32 characters
UNTRACE_WG_INTERFACEwg0Managed WireGuard interface
UNTRACE_WG_ENDPOINTRequiredPublic WireGuard host and port
UNTRACE_WG_SUBNET_PREFIX10.70.0Private IPv4 prefix for peers
UNTRACE_DNS1.1.1.1, 1.0.0.1DNS servers written to clients
UNTRACE_ALLOWED_ORIGINEmptyExact website origin allowed by CORS
UNTRACE_PEER_DB/var/lib/untrace/peers.jsonPersistent peer metadata path
UNTRACE_DRY_RUN0Use synthetic keys and avoid interface changes when set to 1
07 / Operations

Observe and maintain.

sudo systemctl status wg-quick@wg0
sudo systemctl status untrace-control
sudo wg show wg0
sudo journalctl -u untrace-control --since today

Revoking a peer removes its public key from the live WireGuard interface and persistent peer database. On reboot, the control service restores only peers still recorded in that database.

Dry-run testing

UNTRACE_ADMIN_TOKEN="development-token-with-at-least-32-chars" \
UNTRACE_WG_ENDPOINT="localhost:51820" \
UNTRACE_PEER_DB="./work/peers.json" \
UNTRACE_DRY_RUN=1 \
node gateway/bin/untrace-api.mjs

node --test gateway/tests/api.test.mjs
08 / Security

Production requires more.

This repository is a deployment scaffold, not a security audit. Before serving untrusted users, add an identity provider, per-user authorization, secret rotation, durable audit logs, monitoring, encrypted backups, abuse controls, and an independent security review.

Terminate the control plane only over valid HTTPS.
Keep the API bound to loopback.
Restrict inbound firewall rules.
Rotate administrator credentials.
Back up peer records and WireGuard state securely.
Monitor authentication failures and service restarts.
Patch the OS and dependencies promptly.
Never publish keys, tokens, or private infrastructure details.

IPv4 traffic is forwarded through the gateway. The client configuration routes ::/0 into the tunnel as a fail-closed IPv6 route; this scaffold does not provide routed IPv6 internet access.