Remote Access & Reverse Proxy
Remote access to Tabularis Web exposes database administration, stored credentials, tunnels, plugins and AI providers. It is therefore disabled until an authentication mode, a public HTTPS URL and an allowlist of origins are configured: binding to a non-loopback address without them fails at startup.
For the official image, Docker Compose and the Helm chart, see Docker & Helm. The rules on this page apply to containers too.
Deployment Boundary
Tabularis serves plain HTTP and does not terminate TLS itself. A remote deployment must:
- Put the Tabularis listener behind a trusted reverse proxy that terminates TLS.
- Keep the listener unreachable from client networks (firewall rules, a private network or a Kubernetes NetworkPolicy). A public HTTPS URL does not stop direct HTTP access to the listener.
- Preserve the public
Hostheader. - Proxy WebSocket upgrades.
Run the server under a dedicated account and restrict its data directory.
Choose an Authentication Mode
| Mode | Option | Secret | Use it when |
|---|---|---|---|
| Password | --auth password |
TABULARIS_WEB_PASSWORD, at least 12 characters |
A built-in login page is enough |
| Proxy | --auth proxy |
TABULARIS_WEB_PROXY_SECRET, at least 32 characters |
Your proxy already authenticates users (OIDC, SSO, basic auth) |
Pass secrets through the environment, never on the command line, where they show up in process listings.
Password Mode
export TABULARIS_WEB_PASSWORD='replace-with-a-long-unique-password'
tabularis web \
--host 127.0.0.1 \
--port 8080 \
--no-open \
--auth password \
--public-url https://tabularis.example.com \
--allowed-origin https://tabularis.example.com
The server shows a minimal /login page and exchanges a valid password for a Secure, HttpOnly, SameSite=Strict session cookie. It keeps only a hash of the password in memory.
Five failed attempts from one client within a minute lock that client out for five minutes (HTTP 429); other clients can still sign in. To identify clients behind your proxy, list the proxy's address with --trusted-proxy, for example --trusted-proxy 127.0.0.1/32, and have the proxy append X-Forwarded-For (Nginx $proxy_add_x_forwarded_for). Without it, forwarded headers are ignored. Trust only proxy addresses, never client networks.
Proxy Mode
export TABULARIS_WEB_PROXY_SECRET="$(openssl rand -base64 48)"
tabularis web \
--host 127.0.0.1 \
--port 8080 \
--no-open \
--auth proxy \
--public-url https://tabularis.example.com \
--allowed-origin https://tabularis.example.com
After authenticating the user, the proxy must replace (not append) two request headers:
X-Tabularis-User: the authenticated, non-empty user identifier;X-Tabularis-Proxy-Secret: the same secret asTABULARIS_WEB_PROXY_SECRET.
Tabularis removes both headers before handling the request and rejects requests where they are missing or wrong. Never expose the listener directly: a client that bypasses the proxy could send these headers itself.
Example Nginx location, after your own auth_request, OIDC or basic-auth configuration:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Tabularis-User $remote_user;
proxy_set_header X-Tabularis-Proxy-Secret "replace-with-the-environment-secret";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Keep the proxy secret in the proxy's protected secret store rather than in a world-readable configuration file.
Public URL and Allowed Origins
--public-url and every --allowed-origin must be an HTTPS origin with no path, query, fragment or credentials, and the public URL must also be in the allowlist. The only exception is a loopback host (localhost, 127.0.0.0/8, [::1]), which may use HTTP because the traffic never leaves the machine.
Requests with an unexpected Host or Origin get HTTP 403, and state-changing requests also need the session's CSRF token. Add further origins only if the same owner controls them:
--public-url https://tabularis.example.com \
--allowed-origin https://tabularis.example.com \
--allowed-origin https://admin.example.com
What Remote Sessions Can Do
Remote sessions are limited to database work by default: connections, metadata, queries, data editing and notebooks. Denied operations return HTTP 403.
- A remote session can edit a saved connection's metadata and credentials, but changing its driver, destination, or transport and authentication settings needs administrator rights. Stored credentials stay bound to the target an administrator approved.
- File-based drivers, including SQLite, need administrator rights, because SQL itself can open other files (for example with
ATTACH).
These groups stay denied unless you start the server with --allow-high-risk:
- SSH and Kubernetes tunnels;
- AI provider keys, generation, approvals and activity exports;
- credential import and export, backups, dumps and sensitive file operations;
- plugin installation and lifecycle;
- logs, task management, global settings and host filesystem actions.
MCP configuration stays unavailable to remote sessions even with that option.
Enable
--allow-high-riskonly for a deployment used by a single trusted administrator, never for a shared or weakly authenticated one.
Sessions and Audit Logs
- Sessions last eight hours, live in memory and end on logout. The server accepts at most 1,024 live sessions; beyond that, new logins get HTTP 503 while existing sessions keep working.
- Security events (sign-ins, denials, rate limiting, rejected hosts or origins, logouts and completed commands) are logged to stderr under the
tabularis::web_audittarget, with a request ID and an opaque session ID. They never include passwords, proxy secrets, access tokens, request bodies, SQL text or results.
systemd Example
Run the packaged binary as a dedicated account, behind the TLS reverse proxy. Create /etc/tabularis/web.env, owned by root:tabularis with mode 0640:
TABULARIS_WEB_PASSWORD=replace-with-a-long-unique-password
Then /etc/systemd/system/tabularis-web.service:
[Unit]
Description=Tabularis Web
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=tabularis
Group=tabularis
EnvironmentFile=/etc/tabularis/web.env
Environment=HOME=/var/lib/tabularis
StateDirectory=tabularis
UMask=0077
ExecStart=/usr/bin/tabularis web --host 127.0.0.1 --port 8080 --no-open --auth password --public-url https://tabularis.example.com --allowed-origin https://tabularis.example.com
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target
A headless service has no desktop keychain: give it a working keyring backend, or set TABULARIS_SECRET_STORE=file; see Security & Credentials.
Verification Checklist
- The upstream port is unreachable from a client network.
- HTTP redirects to HTTPS at the proxy, and the browser receives a
Securesession cookie. - An unlisted
Originand a wrongHostget HTTP 403. - Repeated invalid credentials end in HTTP 429.
- A default remote session gets HTTP 403 for an administrator-only action.
- Live progress and events reconnect through the proxy.
- Audit logs show request and session IDs but no secrets or SQL.