GONK is an edge-native API gateway written in Go for industrial, IoT, robotics, and air-gapped environments.
It is designed for teams that need secure service exposure near devices without running a heavy control plane, a database dependency, or a full cloud gateway stack.
Status: community preview. The core gateway, auth, routing, load balancing, observability, operator checks, and manual release tooling are in place; production hardening and benchmark baselines continue to evolve.
Try It In 2 Minutes
git clone https://github.com/JustVugg/gonk
cd gonk
make demo-upOpen another terminal and call the public route:
curl http://localhost:8080/public/ping
Generate a JWT and call the protected route:
make demo-token
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/pingFor ready-to-run binaries, download the latest Linux, Windows, or macOS archive from GitHub Releases. See docs/INSTALL.md for step-by-step install commands.
Why GONK
- Single Go binary plus YAML configuration.
- Security primitives close to the edge: JWT, API keys, mTLS, RBAC, scopes, and certificate-to-role mapping.
- Works in constrained or disconnected networks where Kubernetes, SaaS control planes, and central databases are not always available.
- Built for operational workflows: templates, validation, hot reload, health endpoints, Prometheus metrics, and a companion CLI.
- Operator guardrails: protected admin endpoints, audit logging, production secret checks, route introspection, and cache/status views.
See docs/INSTALL.md for installation, docs/SECURITY.md for the security model, docs/THREAT_MODEL.md for trust boundaries, docs/OPERATIONS.md for day-two operations, docs/DEPLOYMENT.md for production deployment, docs/BENCHMARKS.md for local performance checks, and docs/RELEASE.md for manual releases.
Best-Fit Use Cases
- Industrial gateways exposing PLC, sensor, historian, or HMI services.
- Robotics and field-device deployments with limited compute and intermittent connectivity.
- Air-gapped environments that need local auth, routing, and traffic controls.
- Edge microservice stacks that need gateway features without a large platform footprint.
For product positioning and startup strategy, see docs/STARTUP_BRIEF.md.
What's New in v1.2
Release and Deployment
- Ready-to-download Linux, Windows, and macOS release archives
- GitHub Container Registry image availability
- Production Docker Compose template
- systemd unit and production configuration template
What's New in v1.1
Authorization System
- Role-Based Access Control (RBAC)
- JWT scope validation
- Permission matrix combining roles and HTTP methods
- Support for different identity types (devices vs users)
mTLS Support
- Client certificate authentication
- Certificate-to-role mapping with wildcard support
- Dual authentication modes (mTLS + JWT)
Load Balancing
- Multiple upstreams per route
- Four strategies: round-robin, weighted, least-connections, ip-hash
- Active health checking with automatic failover
CLI Tool Complete command-line interface for configuration, JWT/certificate generation, and monitoring.
Installation
Download ready-to-run binaries from GitHub Releases:
- Linux:
gonk_<version>_linux_amd64.tar.gzorgonk_<version>_linux_arm64.tar.gz - Windows:
gonk_<version>_windows_amd64.ziporgonk_<version>_windows_arm64.zip - macOS:
gonk_<version>_darwin_amd64.tar.gzorgonk_<version>_darwin_arm64.tar.gz
# Clone and build git clone https://github.com/JustVugg/gonk cd gonk make build # Binaries will be in bin/ ./bin/gonk --version ./bin/gonk-cli --version
Or run the published container image:
docker run --rm -p 8080:8080 \
-v "$PWD/configs/gonk.production.yaml:/etc/gonk/gonk.yaml:ro" \
--env-file .env \
ghcr.io/justvugg/gonk:latestDetailed install commands are in docs/INSTALL.md.
Quick Start
Run the full Docker demo:
make demo-up make demo-token
Then call the protected route with the generated token:
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/pingSee examples/quickstart for the full demo with two upstream services and Prometheus.
For a more realistic protected edge API, see examples/secure-edge-api.
Run the quickstart smoke test locally:
Generate a basic configuration:
./bin/gonk-cli init --template basic --output gonk.yaml
Start the gateway:
./bin/gonk -config gonk.yaml
Generate a JWT token:
export JWT_SECRET=change-me ./bin/gonk-cli auth jwt generate --role admin --scopes "read:api,write:api" --user-id alice --expiry 24h
Test with the token:
curl -H "Authorization: Bearer <token>" http://localhost:8080/api/getConfiguration Examples
Authorization with Permission Matrix
auth: jwt: enabled: true secret_key: "change-me-in-production" validate_roles: true validate_scopes: true routes: - name: "sensor-api" path: "/api/sensors/*" upstreams: - url: "http://backend:3000" auth: type: "jwt" required: true allowed_roles: ["technician", "engineer", "admin"] required_scopes: ["read:sensors"] permissions: - role: "technician" methods: ["GET"] - role: "engineer" methods: ["GET", "POST"] - role: "admin" methods: ["GET", "POST", "DELETE"]
This setup gives technicians read-only access, engineers can read and calibrate, and admins have full control.
mTLS for Device Authentication
server: tls: enabled: true cert_file: "/certs/server.crt" key_file: "/certs/server.key" client_ca: "/certs/ca.crt" client_auth: "require" routes: - name: "device-data" path: "/api/devices/*" upstreams: - url: "http://iot-backend:3000" auth: require_client_cert: true cert_to_role_mapping: "CN=PLC-001": "device" "CN=Sensor-*": "sensor" "CN=Admin-*": "admin" permissions: - identity_type: "device" methods: ["POST"] - role: "admin" methods: ["GET", "DELETE"]
Devices can only write data, while admins can read and delete.
Load Balancing with Health Checks
routes: - name: "api" path: "/api/*" upstreams: - url: "http://backend-1:3000" weight: 70 health_check: "/health" - url: "http://backend-2:3000" weight: 30 health_check: "/health" load_balancing: strategy: "weighted" health_check_interval: 10s health_check_timeout: 5s
Traffic is distributed 70/30 between backends. Health checks run every 10 seconds and failed upstreams are automatically removed from rotation.
Protecting Admin Endpoints
GONK exposes operational endpoints under /_gonk/* and, when enabled, /metrics. Protect them with an admin token and optional CIDR allowlist:
admin: require_auth: true header: "X-Gonk-Admin-Token" token: "${GONK_ADMIN_TOKEN}" allowed_cidrs: ["127.0.0.1/32", "10.0.0.0/8"]
CLI commands that call admin endpoints automatically send GONK_ADMIN_TOKEN when it is set:
export GONK_ADMIN_TOKEN="change-me" gonk-cli --url http://localhost:8080 status gonk-cli --url http://localhost:8080 routes list gonk-cli --url http://localhost:8080 cache stats
Production Secret Guardrails
Set production mode to reject demo secrets such as change-me and change-me-admin-token:
runtime: environment: production
For intentionally demo-only production-shaped examples, set runtime.allow_demo_secrets: true.
Audit Logging
Audit logs include route, method, path, status, duration, client IP, identity type, identity, roles, and scopes.
CLI Reference
Server Operations
gonk -config gonk.yaml # Start server gonk-cli validate -c gonk.yaml # Validate configuration gonk-cli doctor -c gonk.yaml # Static operational checks gonk-cli doctor -c gonk.yaml --check-admin --check-upstreams gonk-cli status # Check if server is running gonk-cli health # Server health check gonk-cli --url http://localhost:8080 routes list gonk-cli --url http://localhost:8080 routes describe api gonk-cli --url http://localhost:8080 cache stats
JWT Management
# Generate token gonk-cli auth jwt generate --role admin --scopes "read:*,write:*" --user-id alice --expiry 24h # Validate token gonk-cli auth jwt validate <token> # Decode token (no validation) gonk-cli auth jwt decode <token>
API Keys
# Generate API key gonk-cli auth apikey generate --client-id mobile-app --roles user --scopes "read:sensors" # List configured keys gonk-cli auth apikey list -c gonk.yaml
Certificate Management
# Generate CA gonk-cli certs generate --cn "GONK CA" --type ca --output ./certs # Generate server cert gonk-cli certs generate --cn "localhost" --type server --output ./certs --ca-cert ./certs/ca.crt --ca-key ./certs/ca.key # Generate client cert gonk-cli certs generate --cn "Device-001" --type client --output ./certs --ca-cert ./certs/ca.crt --ca-key ./certs/ca.key # Validate cert against CA gonk-cli certs validate --cert ./certs/client.crt --ca ./certs/ca.crt # Show cert details gonk-cli certs info --cert ./certs/client.crt
Monitoring
gonk-cli metrics # Show Prometheus metrics gonk-cli metrics --route api-v1 # Filter by route gonk-cli cache stats # Cache statistics with entries, bytes, hits, misses gonk-cli cache clear # Clear cache
mTLS Demo
Run a complete certificate-chain demo with Docker Compose:
See examples/mtls for details.
Airgapped PKI
For disconnected environments, GONK supports bring-your-own CA files and local offline certificate generation:
gonk-cli certs bootstrap --cn edge-gateway.local --client Device-001 --output ./certs gonk-cli certs doctor -c gonk.yaml --client-cert ./certs/client.crt --server-name edge-gateway.local
See docs/AIRGAP_PKI.md and examples/airgap-pki for the full workflow.
Configuration Templates
# Basic template gonk-cli init --template basic --output gonk.yaml # Industrial IoT template gonk-cli init --template industrial --output gonk.yaml # Microservices template gonk-cli init --template microservices --output gonk.yaml
Configuration Schema
Use docs/gonk.schema.json with editors that support JSON Schema for YAML:
# yaml-language-server: $schema=./docs/gonk.schema.jsonIndustrial IoT Example
This configuration handles a typical industrial setup with PLCs writing sensor data and engineers monitoring/controlling the system.
server: listen: ":8443" tls: enabled: true cert_file: "/certs/server.crt" key_file: "/certs/server.key" client_ca: "/certs/device-ca.crt" client_auth: "request" auth: jwt: enabled: true secret_key: "${JWT_SECRET}" validate_roles: true validate_scopes: true api_key: enabled: true header: "X-API-Key" keys: - key: "${DEVICE_KEY}" client_id: "plc-001" roles: ["device"] routes: # Devices write sensor data using mTLS or API key - name: "sensor-ingestion" path: "/api/sensors/*" methods: ["POST"] upstreams: - url: "http://timeseries-db:8086" auth: require_either: ["client_cert", "api_key"] permissions: - identity_type: "device" methods: ["POST"] # Users read sensor data with JWT - name: "sensor-read" path: "/api/sensors/*" methods: ["GET"] upstreams: - url: "http://timeseries-db:8086" auth: type: "jwt" required: true permissions: - role: "technician" methods: ["GET"] - role: "engineer" methods: ["GET"] cache: enabled: true ttl: 30s # Only engineers can control actuators - name: "actuator-control" path: "/api/actuators/*" methods: ["POST", "PUT"] upstreams: - url: "http://plc-gateway:502" auth: type: "jwt" required: true allowed_roles: ["engineer", "admin"] required_scopes: ["write:actuators"] rate_limit: requests_per_second: 10
Design Tradeoffs
| Need | GONK fit |
|---|---|
| Run a secure gateway on an edge node with minimal dependencies | Strong fit |
| Combine JWT, API keys, mTLS, RBAC, scopes, and local policy in one config | Strong fit |
| Operate in disconnected or air-gapped environments | Strong fit |
| Manage a large multi-region cloud API platform with a hosted control plane | Not the current target |
| Require mature enterprise analytics, monetization, and developer portal features today | Not the current target |
The product wedge is intentionally narrow: secure, lightweight gateway infrastructure for edge networks where generic cloud API gateways are too heavy or operationally awkward.
Building
Prerequisites: Go 1.21+ and Make. Docker is optional for image builds. Docker Compose v2 is required for the quickstart demo.
# Both server and CLI make build # Just the server make build-server # Just the CLI make build-cli # All platforms (for releases) make build-all # Clean make clean # Run tests make test # Full Docker Compose demo make demo-up make demo-token make demo-down # Quickstart smoke test make demo-smoke # Full mTLS demo make mtls-demo # Local benchmark suite make bench # Manual pre-release verification, no GitHub Actions make release-check
Testing
GONK includes package-level Go tests for configuration loading, repository examples, JWT/API key/mTLS auth, cache behavior, rate limiting, request/response transforms, health endpoints, circuit breaker state transitions, load balancing, and HTTP proxy routing.
make test
make test-coverage
make test-raceBefore publishing a release, run coverage, the race detector, benchmarks, binary builds, and the Docker image build locally. See docs/TESTING.md for the current coverage focus, docs/BENCHMARKS.md for performance checks, and docs/RELEASE.md for the manual release process.
On Windows without make, use Go directly:
go build -o bin\gonk.exe .\cmd\gonk go build -o bin\gonk-cli.exe .\cmd\gonk-cli
Project Structure
gonk/
├── cmd/
│ ├── gonk/ # Server binary
│ └── gonk-cli/ # CLI tool
├── internal/
│ ├── auth/ # Authorization (RBAC, scopes, mTLS)
│ ├── loadbalancer/ # Load balancing strategies
│ ├── config/ # Configuration loading
│ ├── server/ # HTTP server
│ ├── proxy/ # Proxy handlers (HTTP/WS/gRPC)
│ ├── cache/ # Response caching
│ ├── metrics/ # Prometheus metrics
│ └── middleware/ # Rate limiting, logging, etc
├── configs/ # Example configuration
├── docs/ # Product and strategy docs
└── Makefile
License
Apache License 2.0
Acknowledgments
This version was driven by feedback from industrial IoT users who needed lightweight authorization capabilities. Thanks to the Go ecosystem libraries that make this possible: Gorilla Mux, JWT-Go, Prometheus client, and others.
