@agentics/gated
v0.1.2
Published
A password gate for any HTTP server. Use as a wrapper that spawns your app and proxies the port, or as drop-in middleware.
Downloads
355
Maintainers
Readme
Gated Serve
Branded password gate for any HTTP server. Wraps your app and proxies the port, or drops in as middleware for Express, Connect, Koa, Fastify, and Hono.
- HMAC-signed cookie sessions, no external store
- Auto-detects the port from your script source and spawns it on a private internal port
- Reverse proxy with WebSocket / HTTP upgrade support
- Themed login page, configurable title, subtitle, and accent colour
- One binary, four aliases:
gated,gated,agenticsGate,agentics-gate
Public source: https://gitlab.com/agentics-ai/gated
Install
agpk add gatedOr globally for the CLI:
agpk add -g gatedFrom the GitLab source directly:
agpk add gitlab:agentics-ai/gatedCLI — wrapper mode
Point it at your server script and a password. It reads the port out of the source, spawns the script on a private port, and exposes the gate on the original port.
gated ./server.js --pass hunter2Override the port explicitly:
gated ./server.js 3000 --user admin --pass hunter2Supported script types out of the box: .js, .mjs, .cjs, .ts (via tsx), .py, .rb, .php, .go (via go run), .sh, .bun.
CLI — proxy-only mode
Already running the upstream yourself? Skip the spawn.
gated --proxy-only --port 3000 --listenPort 8080 --pass hunter2CLI — environment variables
Every flag has an env equivalent.
AGENTICS_GATE_PASS=hunter2 gated ./server.js| Env | Flag |
|---|---|
| AGENTICS_GATE_USER | --user |
| AGENTICS_GATE_PASS | --pass |
| AGENTICS_GATE_SECRET | --secret |
| AGENTICS_GATE_LISTEN_PORT | --listenPort |
| AGENTICS_GATE_TARGET_PORT | --port |
| AGENTICS_GATE_LISTEN_HOST | --listenHost |
| AGENTICS_GATE_TARGET_HOST | --targetHost |
| AGENTICS_GATE_TITLE | --title |
| AGENTICS_GATE_SUBTITLE | --subtitle |
| AGENTICS_GATE_ACCENT | --accent |
| AGENTICS_GATE_TTL | --ttl |
| AGENTICS_GATE_COOKIE | --cookie |
| AGENTICS_GATE_CHILD_PORT | --childPort |
CLI — config file
Drop a .agenticsGate.json (or .agentics-gate.json, agenticsGate.json, .agenticsGaterc, .agenticsGaterc.json) in the cwd:
{
"script": "./server.js",
"targetPort": 3000,
"username": "admin",
"password": "hunter2",
"title": "Internal Tools",
"subtitle": "Staff only",
"accentColor": "#67d0a8",
"ttl": 604800
}Precedence: CLI flags > env vars > config file > defaults.
CLI — full reference
gated <script> [port] [options] wrapper mode
gated --proxy-only --port <n> ... proxy-only
--port <n> App port (target)
--listenPort <n> Gate listen port (default: same as target)
--listenHost <h> Gate listen host (default: 0.0.0.0)
--targetHost <h> Upstream host (default: 127.0.0.1)
--user <u> Username (optional, password-only if absent)
--pass <p> Password (required)
--secret <s> HMAC secret (auto-generated if absent)
--ttl <s> Session TTL seconds (default: 604800)
--title <t> Login page title
--subtitle <t> Login page subtitle
--accent <hex> Accent colour (default: #67d0a8)
--cookie <name> Cookie name (default: agenticsGateToken)
--childPort <n> Pin child internal port (default: random free)
--proxy-only Skip spawn, just gate an existing target
-h, --help Show help
-v, --version Show versionMiddleware
Express
import express from 'express';
import { agenticsGate } from 'gated/express';
const app = express();
app.use(agenticsGate({ password: process.env.GATE_PASS }));
app.get('/', (_, res) => res.send('protected'));
app.listen(3000);Connect
import connect from 'connect';
import { agenticsGate } from 'gated/connect';
const app = connect();
app.use(agenticsGate({ password: process.env.GATE_PASS }));
app.listen(3000);Koa
import Koa from 'koa';
import { agenticsGate } from 'gated/koa';
const app = new Koa();
app.use(agenticsGate({ password: process.env.GATE_PASS }));
app.listen(3000);Fastify
import Fastify from 'fastify';
import { agenticsGate } from 'gated/fastify';
const app = Fastify();
await app.register(agenticsGate, { password: process.env.GATE_PASS });
await app.listen({ port: 3000 });Hono
import { Hono } from 'hono';
import { agenticsGate } from 'gated/hono';
const app = new Hono();
app.use('*', agenticsGate({ password: process.env.GATE_PASS }));
app.get('/', (c) => c.text('protected'));
export default app;Programmatic — standalone gate
For when you want the raw HTTP server without the CLI.
import { createGate } from 'gated';
const { server } = createGate({
target: 'http://127.0.0.1:4000',
username: 'admin',
password: 'hunter2',
title: 'Dashboard',
accentColor: '#67d0a8',
});
server.listen(8080);Options reference
| Option | Default | Description |
|---|---|---|
| target | required (programmatic) | Upstream URL, e.g. http://127.0.0.1:4000 |
| username | '' | Optional. If empty, login is password-only |
| password | required | The password to gate behind |
| secret | random 32 bytes | HMAC secret used to sign session tokens |
| ttl | 604800 (7d) | Session lifetime in seconds |
| cookieName | agenticsGateToken | Session cookie name |
| title | Agentics Gate | Login page title |
| subtitle | Authorisation required | Login page subtitle |
| accentColor | #67d0a8 | Accent hex used in the login UI |
Routes the gate adds
| Path | Method | Purpose |
|---|---|---|
| /__gate/login | GET | Render login page |
| /__gate/login | POST | Submit credentials, set session cookie |
| /__gate/logout | GET | Clear session and redirect to login |
| /__gate/healthz | GET | Liveness probe, always returns ok |
JSON clients (Accept: application/json) get a 401 with { error, loginUrl } instead of an HTML redirect.
How the wrapper resolves ports
In wrapper mode gated reads the script source and matches against patterns for common server frameworks (Node .listen(), Bun.serve, Deno.serve, Flask, Uvicorn, Django runserver, Go http.ListenAndServe, etc.). The detected port becomes the gate's listen port; the child process is spawned on a random free port (or --childPort), and traffic is proxied through.
If detection fails, pass the port as the second positional argument or --port.
Other runtimes
Node is the reference implementation. Ports for other runtimes live under ports/:
- Go —
ports/go/agenticsGate.go - Python —
ports/python/agenticsGate/
Engines
- Node
>= 18
License
MIT — Connor Etherington <[email protected]>
