Taronja Gateway is an API and application gateway.
It serves as an entry point for your API server and your frontend application, handling routing, authentication, sessions, and many more features, leaving your application code clean and focused on business logic.
- Features
- Installation
- Commands
- Configuration
- Middleware Architecture
- Building and Releasing
- Authentication on the APIs
- Getting the Current User from the Frontend
- Login and Logout Links from a Web Page
Features table, shows what is implemented and what is planned.
| Feature | Status | Since |
|---|---|---|
| API Gateway | ✅ | v0.0.1 |
| Application Gateway | ✅ | v0.0.1 |
| Management Dashboard | ✅ | v0.0.3 |
| Logging | ✅ | v0.0.1 |
| Analytics and Traffic metrics | ✅ | v0.0.4 |
| - User Geo-location | ✅ | v0.0.4 |
| - User fingerprint (JA4) | ✅ | v0.0.8 |
| - Traffic-over-time graphs (per minute/hour/day/week/month) | ✅ | v1.0.0 |
| Sessions (Persistent) | ✅ | v0.0.1 |
| User management | ✅ | v0.0.3 |
| Authentication | ✅ | v0.0.1 |
| Authentication: Basic | ✅ | v0.0.1 |
| Authentication: OAuth2 | ✅ | v0.0.1 |
| - OAuth2: GitHub | ✅ | v0.0.1 |
| - OAuth2: Google | ✅ | v0.0.1 |
| - OAuth2: Microsoft (Entra ID / Azure AD)¹ | 🚧 | |
| - OAuth2: Facebook¹ | 🚧 | |
| - OAuth2: Apple (Sign in with Apple)¹ | 🚧 | |
| Authentication: Token | ✅ | v0.0.9 |
| Authentication: JWT | 🚧 | |
| Authorization using RBAC | 🚧 | |
| HTTP Cache Control | ✅ | v0.0.12 |
| Response Compression (brotli/zstd/gzip/deflate) | ✅ | v1.0.0 |
| Distributed Tracing (OpenTelemetry) | ✅ | v1.0.0 |
| Notifications (in-app, email, Telegram) | ✅ | v1.0.0 |
| - Multi-recipient, per-user delivery channel, automatic retries | ✅ | v1.0.0 |
| - Sent/failed/pending status, per notification and per batch | ✅ | v1.0.0 |
| - Outbound webhook on user response | ✅ | v1.0.0 |
| Rate Limiter | ✅ | v0.0.22 |
| - Requests per minute per IP | ✅ | v0.0.22 |
| - Avoid scanners with number of 404 limit | ✅ | v0.0.22 |
| - Severe path with wildcard limit (e.g. /admin/*.php) | ✅ | v0.0.22 |
| - Persistent block-event history, with a per-country attacker map | ✅ | v1.0.0 |
| Feature Flags | 🚧 | |
| Circuit breaker | 🚧 | |
| Caching | 🚧 | |
| Load Balancing | ✅ | v1.0.0 |
- Round-robin across multiple to backends |
✅ | v1.0.0 |
| - Automatic failover on connection failure | ✅ | v1.0.0 |
| robots.txt | 🚧 | |
| more... | 🚧 |
¹ Implemented in v1.0.0 but untested; moved to the
wip/microsoft-apple-facebook-auth branch to come back to later.
curl -fsSL https://github.com/jmaister/taronja-gateway/raw/main/scripts/install.sh | bashThis script detects your OS and architecture, downloads the latest release, and installs it to your system path.
powershell -Command "Invoke-WebRequest -Uri 'https://github.com/jmaister/taronja-gateway/raw/main/scripts/install.bat' -OutFile 'install.bat'" && install.batThe Windows installer places the binary in %USERPROFILE%\bin. Add this directory to your PATH to use tg from anywhere.
Both installers take an optional version, e.g. to go back to an earlier release:
curl -fsSL https://github.com/jmaister/taronja-gateway/raw/main/scripts/install.sh | bash -s -- 0.0.24install.bat 0.0.24A config file must match the gateway's config version: keep a copy of your old config before migrating it.
Prefer to see it running before installing anything? examples/docker-demo is a docker compose up --build away from a full stack with one of each route type (static, authenticated static, reverse proxy), the admin dashboard, and Google/GitHub OAuth wired up to .env — see its README.
Every GitHub Release publishes ghcr.io/jmaister/taronja-gateway:<version> and :latest for linux/amd64 and linux/arm64 (Apple Silicon); pre-releases get only :<version> (see .github/workflows/docker-release.yml) — pull it directly instead of building the Dockerfile yourself:
docker run --rm -p 8080:8080 \
-v $(pwd)/config:/etc/taronja-gateway:ro \
-v gateway-db:/data \
ghcr.io/jmaister/taronja-gateway:latest \
run --config /etc/taronja-gateway/config.yamlUseful for deploying behind a platform that runs containers for you (a Docker Compose stack, Dokploy, Coolify, Kubernetes, ...): give it a config file with routes[].to pointing at your other services' addresses on that platform's network, and a volume at /data so the sqlite DB (admin user, sessions, traffic metrics) survives a redeploy. examples/docker-image is a runnable Compose version of exactly this — pulling the image rather than building examples/docker-demo's equivalent Dockerfile locally.
The Taronja Gateway CLI provides the following commands:
-
Run the Gateway:
./tg run --config ./sample/config.yaml
This command starts the Taronja API Gateway using the configuration file specified by the
--configflag. OnCtrl+Cor aSIGTERM(e.g. fromdocker stopor a Kubernetes pod eviction), it shuts down gracefully — draining in-flight requests for up to 15 seconds before exiting, instead of dropping them. -
Add a new user:
./tg adduser <username> <email> <password>
This command creates a new user in the database with the provided username, email, and password.
-
Show the current version:
./tg version
-
List the middleware chain for a config file:
./tg middleware list --config ./sample/config.yaml
Prints the middleware the config enables, in order, and every available middleware with its dependencies — without starting the server. See Middleware.
-
Migrate a config file to the current schema version:
./tg migrate --config ./sample/config.yaml > ./sample/config-v1.1.yamlPrints the migrated config to stdout — redirect it to save it; never modifies the original or writes a file itself.
tg runrefuses to start against an outdated (or too new) config file and tells you to run this (or upgrade the binary). See Config File Versioning. -
Validate a config file:
./tg validate --config ./sample/config.yaml
Loads and validates the config — schema version, routes, admin settings, and the global middleware chain's dependencies — without starting the server, opening a database connection, or making any network calls. Prints
'<path>' is valid (version X.Y): M route(s), management prefix "/_".on success, orFATAL: <error>(exit code 1) on the first problem found. Safe to run in CI or before deploying a config change.
Taronja Gateway uses a YAML configuration file to define server settings, routes, authentication providers, and other features. The configuration file can reference environment variables using the ${VARIABLE_NAME} syntax.
version: "1.0" # Config schema version — see "Config File Versioning" below
name: Example Gateway Configuration
server:
host: 0.0.0.0 # Bind to all interfaces, 127.0.0.1 for localhost only
port: 8080
url: http://localhost:8080
management:
session:
durationSeconds: 86400 # Session duration in seconds (24 hours)
admin:
enabled: true
username: admin
password: admin123 # Automatically hashed for security
middleware: # run top to bottom, see doc/middleware/
- name: ja4_fingerprint # the three analytics middleware feed the dashboard
- name: session_extraction
- name: traffic_metrics
- name: logging
routes:
- name: API Route
from: /api/v1/*
removeFromPath: "/api/v1/"
to: https://api.example.com
options:
cacheControlSeconds: 3600
authenticationProviders:
basic:
enabled: true
google:
clientId: ${GOOGLE_CLIENT_ID}
clientSecret: ${GOOGLE_CLIENT_SECRET}
github:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
branding:
logoUrl: /static/logo.png
geolocation:
iplocateApiKey: ${IPLOCATE_IO_API_KEY}
notification:
email:
enabled: true
host: smtp.example.com
port: 587
username: ${SMTP_USERNAME}
password: ${SMTP_PASSWORD}
from: ${SMTP_FROM}
fromName: ${SMTP_FROM_NAME}The config file declares a schema version in MAJOR.MINOR format (version: "1.0"). The gateway refuses to start when the file's version differs from the one it supports, in either direction. Run tg migrate to upgrade an older file. See doc/config-versioning.md for the version rules and migration steps.
Defines the gateway server settings.
host: The host address to bind to (default: 127.0.0.1)port: The port number to listen on (default: 8080).url: The full URL where the gateway is accessible
Controls the admin dashboard and user sessions. The gateway's own endpoints always live under /_ (login /_/login, dashboard /_/admin/, API /_/api/), so avoid using /_ in your routes.
session.durationSeconds: Session timeout in seconds (e.g., 86400 = 24 hours)admin.enabled: Enable the admin dashboardadmin.username: Username for dashboard accessadmin.password: Password for dashboard access (automatically hashed)
Global middleware runs on every request before it reaches a route:
compression, CORS, rate limiting, analytics, logging and tracing. It is
listed under the root middleware: key and runs in list order; each entry
has a name, an optional enabled: false and an optional config block
with that middleware's options. With no middleware: key, none runs.
middleware:
- name: compression
- name: rate_limiter
config:
requestsPerMinute: 300
maxErrors: 20
blockMinutes: 15
- name: ja4_fingerprint
- name: session_extraction
- name: traffic_metrics
config:
excludeStaticAssets: true
- name: logging| Middleware | What it does |
|---|---|
tracing |
OpenTelemetry span per request, exported over OTLP/HTTP |
compression |
brotli/zstd/gzip/deflate response compression |
cors |
CORS headers and preflights |
rate_limiter |
Per-IP request and error limits, scanner blocking |
ja4_fingerprint |
JA4H fingerprint per request |
session_extraction |
Attaches the caller's session to the request |
traffic_metrics |
Records requests for the statistics dashboard |
logging |
Logs each request |
See doc/middleware/ for every option, the dependencies between middleware and ordering advice.
Each route maps a from path pattern to a backend (to, a single URL or a list for load balancing), a single file (toFile), or a folder (toFolder). Common properties:
name: human-readable route identifierfrom: URL path pattern to match (supports*wildcards)to: backend URL, or a list of URLs to load balance acrosstoFile/toFolder: serve a file or a folder (a route sets exactly one ofto,toFile,toFolder)removeFromPath: prefix removed before forwarding (proxy routes, whole path segments only; a path intois prepended after)authenticated: true: require a logged-in useroptions.cacheControlSeconds: cache duration in seconds (0 = no-cache)
See doc/routes.md for examples and load balancing, and doc/CACHE_CONTROL.md for caching.
Basic (username/password) authentication and the Google and GitHub OAuth2 providers are configured under authenticationProviders. Each is independent and optional, and the login page shows a button for every enabled one.
authenticationProviders:
basic:
enabled: trueSee doc/authentication-providers.md for the OAuth2 setup and callback URLs.
Customize the login page and dashboard appearance.
branding:
logoUrl: /static/logo.pngConfigure IP geolocation services for analytics.
geolocation:
iplocateApiKey: ${IPLOCATE_IO_API_KEY}- With API key: Uses iplocate.io for accurate results
- Without API key: Falls back to freeipapi.com
The gateway can store and deliver notifications on behalf of the apps it sits in front of: in-app always, plus email and Telegram if configured. See doc/notifications.md for the data model, API, retry schedule, and delivery flows.
notification:
email:
enabled: true
host: smtp.example.com
port: 587
username: ${SMTP_USERNAME}
password: ${SMTP_PASSWORD}
from: noreply@example.com
fromName: Taronja Gateway
telegram:
enabled: true
botToken: ${TELEGRAM_BOT_TOKEN} # from @BotFatherUse environment variables to keep sensitive data out of your config file:
google:
clientId: ${GOOGLE_CLIENT_ID}
clientSecret: ${GOOGLE_CLIENT_SECRET}Set environment variables before running the gateway:
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
./tg run --config ./config.yamlSee the complete example configuration in sample/config.yaml.
Every middleware is one file in middleware/builtin/ holding its name, its
options type with validation, and a Definition;
middleware/builtin/global_chain.go turns the middleware: list into a
chain, checking names, options and dependencies. See
doc/middlewares.md for the design.
- Inspect what's active for a config file without starting the server:
./tg middleware list --config ./sample/config.yaml
- Monitor a running gateway (admin session required):
GET /_/api/middleware— status, dependencies, and health of every middlewareGET /_/api/middleware/{name}/metrics— request count, error count, and average duration for one middleware
- Add a built-in middleware — see
doc/middleware_development.md.
make build, make test, make cover and make dev cover day-to-day development. Releases are built and published with GoReleaser. See doc/building-and-releasing.md.
Proxied requests to routes with authenticated: true carry X-User-Id and X-User-Data headers, set only when a valid session (cookie) or bearer token exists. See doc/backend-integration.md for the header reference, the X-User-Data JSON structure, and a backend example.
A frontend served through the gateway can fetch the current user from the gateway's session API. See doc/backend-integration.md.
Plain links to the gateway's login and logout endpoints are enough. See doc/backend-integration.md.
