Iket is a lightweight, extensible, pluggable API Gateway written in Go. It supports modern gateway features such as rate-limiting, JWT authentication, WebSockets, middleware chaining, hot-reloadable plugins, and secure remote administration via mTLS.
- High-Performance Proxy: Reverse proxy for HTTP and WebSocket APIs.
- Service-Based Configuration: Manage routes, backends, and policies by service.
- Secure Administration: Remote control via
iketusing mTLS and client certificates. - mTLS & TLS 1.3: Strong encryption and mutual authentication out of the box.
- Extensible Plugin System: Hot-reloadable middleware and lifecycle hooks.
- Authentication: Built-in support for Basic Auth, JWT, and Client Credentials.
- Observability: Prometheus metrics, structured logging, and health checks.
Get up and running in seconds with our ultimate installer:
Full Gateway Setup:
curl -fsSL https://raw.githubusercontent.com/bhangun/iket/main/scripts/install.sh | bashCLI Only (for remote administration):
curl -fsSL https://raw.githubusercontent.com/bhangun/iket/main/scripts/install.sh | bash -s -- --cli-onlyOptional Source Build:
curl -fsSL https://raw.githubusercontent.com/bhangun/iket/main/scripts/install.sh | bash -s -- --from-sourceBy default, the installer downloads prebuilt release binaries. --from-source is only needed if you explicitly want a local source build. In full mode it also generates mTLS certificates and sets up your initial configuration.
Safe Uninstall:
curl -fsSL https://raw.githubusercontent.com/bhangun/iket/main/scripts/uninstall.sh | bashBackup Then Full Remove:
curl -fsSL https://raw.githubusercontent.com/bhangun/iket/main/scripts/uninstall.sh | bash -s -- --backup --purge-stateFor detailed instructions and manual installation, see docs/INSTALL.md.
# Start with default config created by installer
iket-server --config ~/.iket/config.yaml
# Default storage is PostgreSQL with file mirroring
iket-server --config ./config/config.yaml --services ./config/service.yaml
# Use explicit PostgreSQL or legacy file-primary mode if needed
iket-server --storage postgres --postgres-url "postgres://iket:[email protected]:55432/iket?sslmode=disable" --config ./config/config.yaml --services ./config/service.yaml
iket-server --storage file --config ./config/config.yaml --services ./config/service.yamlIket provides a powerful CLI for remote administration. It supports multiple environment profiles (contexts) and secure mTLS communication.
# Guided setup to connect to a local or remote gateway
iket setup
# Trusted-host Docker bootstrap using the server CA or an existing client bundle
iket setup docker --url https://localhost:8443
# Verify the active context and certificate files
iket context test
# Create a short-lived enrollment token from an already-admin-capable context
iket enroll create-token --name laptop-admin --out ./enroll.json
# Redeem that token on another machine
iket enroll use --file ./enroll.json --name laptop-admin
# List all configured contexts (environments)
iket context list
# Switch between environments (e.g., local, docker, prod)
iket context use <context-name># Check gateway status of the active context
iket gateway status
# Simulate how Iket would match and rewrite a request without calling upstream
iket simulate /v1/auth/profile --method GET
# Short alias
iket test http://localhost/v1/auth/profile
# Simulate against local unpublished files instead of the active context
iket simulate /v1/auth/profile --method GET --config ./config/config.yaml --services ./config/service.yaml
...
# Certificate management
iket cert statusYou can override the active context using environment variables:
IKET_SERVER_URL=http://localhost:7100 iket gateway statusserver:
port: 8080
enableLogging: true
security:
tls:
enabled: true
port: 8443
certFile: "/path/to/server.crt"
keyFile: "/path/to/server.key"
clientCAFile: "/path/to/ca.crt"
clientAuthType: "RequireAndVerifyClientCert"
autoGenerate: true
generateSharedClient: falseserver.port stays available for plain HTTP traffic, while security.tls.port serves the mTLS admin endpoint. When autoGenerate: true, Iket creates ca.crt, ca.key, server.crt, and server.key automatically if they are missing. Shared admin client credentials are not generated by default; generateSharedClient: true is an explicit opt-in for compatibility-only environments.
In Docker deployments, those generated files land in the server deployment's mounted cert directory such as ./certs/, not automatically in the CLI-managed ~/.iket/certs. The usual first-admin bootstrap on the trusted server host is:
iket setup docker --cert-dir ./certs --url https://<server-ip>:8443If you explicitly enable generateSharedClient: true, Iket also generates client.crt and client.key in that same server-side cert directory, and you can then import them with:
iket cert import --name remote-prod --cert-dir ./certs --url https://<server-ip>:8443If Docker startup fails with open /app/certs/ca.key: permission denied, the host-mounted ./certs directory is not writable by the container user. Make sure IKET_UID / IKET_GID match the host owner, clear stale root-owned cert files if needed, and prefer running docker compose as the same user that owns the deployment folder.
security.tls.enrollmentPort exposes a narrow HTTPS bootstrap endpoint for one-time certificate enrollment without opening the full admin surface.
The direct enrollment flow works best when Iket is using its local managed CA. If you point clientCAFile at an external CA but do not keep the signing key on the server, Iket cannot mint new client certificates and enrollment will be rejected.
Iket also caps active enrollment tokens (security.tls.enrollmentMaxActive, default 10) and records token create/redeem/revoke events in the structured logs.
version: 1
services:
- name: "Identity Service"
host: "http://identity:8080/api"
base_path: "/{realm}/auth"
routes:
- path: /login
method: POST
requireAuth: true
stripPath: false
backend:
- url_pattern: /loginservice.base_path is the canonical way to mount a service on the public gateway path. Route paths are evaluated relative to that base, so the example above exposes POST /{realm}/auth/login and proxies it to /api/login upstream. If your host already includes a path prefix, Iket will join it with the rewritten route path without introducing double slashes.
Iket's plugin system allows you to extend the gateway with custom middleware.
type MyPlugin struct {}
func (p *MyPlugin) Name() string { return "myplugin" }
func (p *MyPlugin) Initialize(cfg map[string]interface{}) error { return nil }
func (p *MyPlugin) Middleware(next http.Handler) http.Handler { return next }# Generate a ready-to-run prebuilt Docker scaffold
iket server init --mode docker --output ./iket-docker --with-systemd
# Inspect the scaffold and local Docker runtime state
iket server doctor --mode docker --output ./iket-docker
# Or scaffold a host-native install instead
iket server init --mode host --output ./iket-host --with-systemd
iket server doctor --mode host --output ./iket-host
# Run the prebuilt image with your own compose file
docker compose up -d
# Or, if you have the repository checked out, use the bundled prebuilt compose file
docker compose -f docker/docker-compose.prebuilt.yaml up -dFor a full remote prebuilt Docker walkthrough, including config, auto-generated certs, and iket bootstrap, see docs/INSTALL.md.
iket-cli remains as a compatibility alias for the client binary, but iket is now the primary command. The gateway binary is iket-server.
The generated server scaffold now includes both config/config.yaml and config/service.yaml, and the host/Docker startup commands pass both files so file mirroring stays aligned with SQLite-backed storage.
- Implementation of new plugins
- Improving documentation
- Reporting bugs and security vulnerabilities
- Installation Guide
- CLI Command Reference
- API Key Management
- Plugin Quickstart
- Config Storage
- API Reference
This project is licensed under the MIT License - see the LICENSE file for details.
