No description
  • TypeScript 99.1%
  • CSS 0.4%
  • Shell 0.2%
  • Dockerfile 0.1%
  • Makefile 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Robert Pławski 65c6331d56
Some checks failed
ci-cd / check (push) Successful in 1m10s
ci-cd / docker (push) Successful in 31s
ci-cd / deploy (push) Failing after 3s
feat: kiosk auto-login via kiosk.yaml auth.user + KIOSK.md reference
2026-10-27 01:07:08 +01:00
.forgejo/workflows feat: kiosk res/scale/quality GET params; ci-cd registry host fix 2026-10-27 00:52:20 +01:00
.github ci: use RELEASE_NOTES.md as release body when present 2026-10-20 12:14:30 +03:00
packages feat: kiosk auto-login via kiosk.yaml auth.user + KIOSK.md reference 2026-10-27 01:07:08 +01:00
scripts chore: update moonlight-web-stream to v3.0.0 2026-10-25 18:34:57 +02:00
.dockerignore fix: enable RDPEDISP resize, fix canvas clear, fix Docker cache, fix clipboard paste 2026-03-21 11:07:26 +02:00
.gitignore chore: ignore *.tsbuildinfo build artifacts 2026-04-14 11:08:53 +03:00
docker-compose.yml feat: kiosk RDP mode (?username=) and Forgejo ci-cd workflow 2026-10-27 00:09:23 +01:00
Dockerfile chore(docker): prune unused sql.js build variants (~22MB) 2026-09-16 10:09:14 +03:00
entrypoint.sh fix(moonlight): run moonlight-web-stream in-process with Gatwy chrome (#41) 2026-08-31 17:07:01 +03:00
kiosk.example.yaml feat: kiosk auto-login via kiosk.yaml auth.user + KIOSK.md reference 2026-10-27 01:07:08 +01:00
KIOSK.md feat: kiosk auto-login via kiosk.yaml auth.user + KIOSK.md reference 2026-10-27 01:07:08 +01:00
LICENSE chore: add MIT LICENSE file 2026-04-09 16:52:47 +03:00
Makefile fix: Makefile docker tag default (shell fallback, GATWY_IMAGE may be empty) 2026-10-27 00:54:43 +01:00
package-lock.json feat: kiosk RDP mode (?username=) and Forgejo ci-cd workflow 2026-10-27 00:09:23 +01:00
package.json chore: bump version to 1.2.2 2026-10-20 12:09:24 +03:00
README.md feat: kiosk auto-login via kiosk.yaml auth.user + KIOSK.md reference 2026-10-27 01:07:08 +01:00
THIRD_PARTY.md chore: update moonlight-web-stream to v3.0.0 2026-10-25 18:34:57 +02:00
tsconfig.base.json feat: initial pre-alpha release v0.0.1 2026-03-20 21:20:31 +02:00

Gatwy

alt text

Self-host your entire remote access stack in one Docker container — 10 protocols, one interface: RDP, SSH, VNC, Telnet, SMB, SFTP, FTP, MySQL & PostgreSQL (Optional - Moonlight).

License: MIT Image Size Latest Release Docker Image

No middleware. No Java. No server relay. WebAssembly-native RDP running directly in your browser — zero overhead across all protocols.

Website · Documentation · Gatwy vs Guacamole

Quick Start · Configuration


🚀 Why Gatwy?

Most browser-based remote access tools relay your display through a server-side engine, adding latency and complexity. Gatwy's RDP client runs entirely in your browser using WebAssembly — pixel-perfect, low-latency RDP with no middleware, no Java, and no extra containers.

One container. Zero dependencies. Open your browser and connect.


✨ Highlights

Feature What you get
10 protocols RDP (WebAssembly), SSH, VNC, Telnet, SMB, SFTP, FTP, PostgreSQL, MySQL — plus optional Moonlight
Split-pane workspace Unlimited sessions side by side with drag-and-drop tabs
Session recording & audit Encrypted RDP video, SSH asciinema, command-level audit log with auto-redacted passwords, file activity tracking
Credential library Reusable username/password and SSH key credentials; rotate a password once and every connection follows
Granular RBAC 30 fine-grained permissions, custom roles, per-connection sharing, protocol-level access control
Auth flexibility Local accounts, LDAP/AD, OpenID Connect (SSO), MFA (TOTP), IP access rules
Alerting SMTP, Telegram, Slack, Webhook channels with a no-code rule builder
Encrypted backup & restore Single-file .geb backup with AES-256 encryption

👉 Full feature list →


🐳 Quick Start

Docker Compose

# docker-compose.yml
services:
  gatwy:
    image: ghcr.io/kotoxie/gatwy:latest
    container_name: gatwy
    restart: unless-stopped
    ports:
      - '7443:7443'
    volumes:
      - ./data:/app/data
    environment:
      - GATWY_ENCRYPTION_KEY=your-64-char-hex-key  # openssl rand -hex 32
docker compose up -d

Docker Run

docker run -d \
  --name gatwy \
  --restart unless-stopped \
  -p 7443:7443 \
  -v ./data:/app/data \
  -e GATWY_ENCRYPTION_KEY=your-64-char-hex-key \
  ghcr.io/kotoxie/gatwy:latest

Then open https://<YOUR_IP>:7443 and create your admin account on first launch.

Note

The browser will warn about the self-signed certificate. Accept the exception to proceed, or bring your own cert.


⚙️ Configuration

Core

Variable Default Description
GATWY_ENCRYPTION_KEY (auto-generated file) 64-char hex AES-256 key. ⚠️ Set this in production. Generate with openssl rand -hex 32
PORT 7443 HTTPS port
DATA_DIR /app/data Database, certs, recordings, and logs
TLS_CERT_PATH / TLS_KEY_PATH (auto) Custom TLS certificate & key paths
BASE_PATH / (root) URL path prefix for serving behind a reverse proxy (e.g. /sys/ftp). Plain path segments only (A-Z a-z 0-9 . _ ~ -); leading/trailing slashes are normalized.

Authentication

Variable Default Description
OIDC_TOKEN_AUTH_METHOD client_secret_basic OIDC token endpoint client auth: client_secret_basic (or basic) or client_secret_post (or post).
GATWY_KIOSK_CONFIG <DATA_DIR>/kiosk.yaml Path to the kiosk RDP config file (see below).

Note: If no encryption key is set, Gatwy auto-generates one at /app/data/encryption.key and shows a warning banner. Fine for a home lab — not recommended for production.

Kiosk RDP (?username= param)

With data/kiosk.yaml in place (see kiosk.example.yaml), any logged-in user can open

https://<gatwy-host>:7443/?username=alice

and the entire UI is skipped: the app connects RDP-only to the single host from the YAML config, using alice as both the remote username and the password (password = username), sized to fit the window — nothing on screen but the RDP canvas. Useful for throwaway/virtual users on a fixed LAN host:

enabled: true
rdp:
  host: 192.168.1.125
  port: 3389
  verify_tls: false   # skip certificate validation on the target
auth:
  user: kiosk         # optional: auto-login visitors as this local account (no MFA)

With auth.user set, visitors who are not signed in to Gatwy are signed in automatically — they only ever see the remote desktop, never a login page. Without it, the normal Gatwy login is shown first (the ?username= param survives the redirect), then the kiosk session starts. The account's role still needs the RDP protocol permission.

Warning: password = username is intentionally weak — use only on trusted networks. See KIOSK.md for the full reference (URL params, config keys, auto-login flow, security notes).

Kiosk render params

Param Values Default Effect
res WxH (e.g. 1920x1080) (window size) Fixed desktop resolution sent to the host; the window no longer resizes the remote desktop
scale fit / stretch / 1 fit Display scaling: fit letterboxes preserving aspect ratio, stretch fills the window (may distort), 1 shows native pixels centered (may overflow)
quality 10–100 100 Renders the desktop at N% of the window size (fewer pixels = less bandwidth, upscaled on display). Ignored when res is set
https://<gatwy-host>:7443/?username=alice&res=1920x1080&scale=fit&quality=75

Warning

password = username is inherently weak — the kiosk mode is meant for isolated LAN segments or disposable accounts only.

👉 Full configuration reference →


🌙 Optional: Moonlight / Sunshine

Moonlight is off by default. The helper it uses, moonlight-web-stream, is GPL-3.0 and is not bundled — Gatwy itself stays MIT.

Tip

Enable it by setting ENABLE_MOONLIGHT to 1, true, or yes.

services:
  gatwy:
    environment:
      - ENABLE_MOONLIGHT=1

On start, the entrypoint downloads a pinned release into /opt/moonlight-web and Moonlight appears in the protocol picker. PIN pairing uses the Sunshine web UI.

When the variable is unset, Moonlight is hidden; stored Moonlight connections are kept and return if you enable it later.

See THIRD_PARTY.md for the license note and pinned release.


🔄 Updating

docker compose pull && docker compose up -d

🛠️ Building from Source

git clone https://github.com/kotoxie/gatwy && cd gatwy

# With Docker
docker compose up --build -d

# Without Docker (Node.js 20+)
npm install && npm run build && npm start

📄 License

MIT