Skip to main content
The gateway now ships in the praisonai-bot package. praisonai serve gateway still works exactly as documented here; for a standalone install see praisonai-bot Migration.
The gateway and chat UI change security behaviour based on the interface they bind to — permissive on loopback, strict on external. External binds also refuse a known-weak/placeholder auth_token — see Weak / placeholder secret guard.
The user opens the gateway UI or WebSocket client; bind-aware auth requires a token only when the server listens on a non-loopback host.

Quick Start

1

Local development (loopback — permissive)

2

External deployment (strict — token required)


How It Works


Token Source Precedence

When GatewayConfig(auth_token=...) is set, it is exported to GATEWAY_AUTH_TOKEN at gateway startup. Config wins over env. All auth paths — HTTP login, magic-link verification, WebSocket handshake — read the same secret. Implication: Rotating the token via GatewayConfig is sufficient; you don’t need to also unset GATEWAY_AUTH_TOKEN. Flow — “I rotated my gateway token but magic-link login still fails”: Prior to PR #1744, a stale GATEWAY_AUTH_TOKEN env var could shadow a fresh GatewayConfig.auth_token. Since PR #1744, config wins — restart the gateway and try again.

Interface Detection

The same is_loopback() predicate is now applied to the client host for auth-bypass decisions, not just the bind host — see Auth Bypass on Loopback.

Auth Bypass on Loopback

A loopback-bound gateway is permissive by default — local, non-proxied requests bypass auth without any environment variable. Semantic loopback client matching. The client host is checked with is_loopback(), not a fixed 3-string list. Local peers reported as 127.0.0.2, 127.255.255.255, or the expanded IPv6 form 0:0:0:0:0:0:0:1 bypass correctly instead of getting a spurious 401. Non-loopback clients (10.0.0.5, 2001:db8::1) never bypass on a loopback-bound gateway. Proxy-header guard. A request carrying x-forwarded-for, via, x-real-ip, or x-forwarded-host never inherits loopback trust — proxied requests always require auth. A missing client address also blocks the bypass.

Decision Table

Loopback requests to a loopback-bound gateway also receive all operator scopes by default. This is intended for local development — see Operator Scopes.

User Flows

Flow A — “I want a quick local demo”: Run on 127.0.0.1, no config needed. Token auto-generated, fingerprint logged (gw_****abcd), saved to ~/.praisonai/.env. Flow B — “I want to share on my LAN”: Run praisonai onboard (30s, 3 prompts) OR export GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)praisonai gateway start --host 0.0.0.0. Flow C — “I’m deploying to a VPS”: Same as B, but also set CHAINLIT_USERNAME / CHAINLIT_PASSWORD for the UI, and consider TLS. Flow D — “Lab/demo — I accept the risk of admin/admin on external”: export PRAISONAI_ALLOW_DEFAULT_CREDS=1.

Environment Variables


Error Reference

GatewayStartupError — raised by assert_external_bind_safe() when binding externally without a token:
UIStartupError — raised by register_password_auth() when admin/admin used on external bind:

Token Fingerprinting

Logs now show gw_****XXXX (last 4 chars), never the raw token. This is implemented by get_auth_token_fingerprint() for safe logging. Retrieve the full token from ~/.praisonai/.env if needed.

Which Option When


Rotating the token

When the operator changes auth_token and reloads, every session authenticated under the previous secret is force-closed with WebSocket close code 4001 and reason credentials_rotated. Clients should re-authenticate rather than backing off. Defaults on; opt out with gateway.revoke_on_secret_rotation: false.

Gateway Credential Rotation

Full rotation behaviour, the opt-out toggle, and client-side recovery

Weak / placeholder secret guard

A publicly-known placeholder like change-me is no protection at all — external binds refuse to start on a weak auth_token, and loopback prints a warning.

Behaviour matrix

The denylist

KNOWN_WEAK_SECRETS is a frozenset of well-known placeholder values. The lookup is whitespace-stripped and case-insensitive, so CHANGE-ME, change-me , and Change-Me all match. Empty and None also count as weak.
The last two entries — $(openssl rand -hex 16) and $(openssl rand -hex 32) — are in the denylist because pasting the fix command as a literal string (into YAML or an env value) instead of running it in a shell is the most common footgun. The literal is rejected exactly so this mistake fails loudly.

The refusal message

On an external bind with a weak token, the gateway raises WeakGatewaySecretError with this exact message:

Fix a weak token

1

Option A — run onboarding (recommended)

2

Option B — generate a strong token

Run this in a shell so $(...) is expanded to a random value. Do not paste the literal string $(openssl rand -hex 16) into gateway.yaml or an env value — that literal is itself in the denylist.
3

Option C — let doctor repair it (fastest if gateway.yaml is open)

--fix mints a strong token, persists it to ~/.praisonai/.env, and rewrites an explicit weak auth_token in gateway.yaml in place (${ENV} references are preserved). See Gateway CLI › Auto-repair.

Programmatic use

assert_gateway_secret_strong is not bind-aware itself — it raises on any weak value. The bind-aware policy (fail-closed external / warn loopback) is applied at the wrapper call sites.
praisonai gateway doctor surfaces the same verdict before start — see Weak-secret check.

Best Practices

Prefer praisonai onboard over manual token creation. It handles all the setup automatically and saves the token securely.
The auto-generated .env file contains sensitive tokens. Add it to your .gitignore and never commit it to version control.
Always set CHAINLIT_USERNAME and CHAINLIT_PASSWORD before binding to external interfaces. Never use admin/admin in production.
The PRAISONAI_ALLOW_DEFAULT_CREDS=1 escape hatch should only be used for ephemeral demos or testing. Never in production.

Operator Scopes

Least-privilege multi-operator access control

Gateway Documentation

Core gateway functionality and configuration

Onboarding

Quick setup with automatic token generation

Troubleshooting

Common gateway issues and solutions

Chat Interface

Chainlit UI security and configuration