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.
from praisonaiagents import Agent

agent = Agent(
    name="Local Agent",
    instructions="You are a helpful assistant.",
)
# Serve on loopback — no token required
# $ praisonai gateway start --host 127.0.0.1
agent.start("hello")
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)

from praisonaiagents import Agent

agent = Agent(
    name="Local Agent",
    instructions="You are a helpful assistant.",
)

# Serve via gateway on loopback — no token needed
# $ praisonai gateway start --host 127.0.0.1
agent.start("hello")
2

External deployment (strict — token required)

# Option A: Run onboarding (recommended)
praisonai onboard

# Option B: Set a token explicitly
export GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)
praisonai gateway start --host 0.0.0.0

How It Works

ModeMeaningTrigger
localPermissive — no token requiredLoopback bind (default)
tokenToken required (auto-generated if absent on loopback)External bind (default)
passwordUsername/password authChainlit UI
trusted-proxyAuth handled upstreamReverse proxy setups

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

Hostis_loopback()Resolved mode
127.0.0.1Truelocal
127.255.255.255Truelocal
localhostTruelocal
::1Truelocal
0.0.0.0Falsetoken
192.168.1.xFalsetoken
10.0.0.xFalsetoken
8.8.8.8 (public)Falsetoken

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

VariableScopeEffect
GATEWAY_AUTH_TOKENGatewayAuth token. Required on external bind. Auto-generated + saved to ~/.praisonai/.env (mode 0600) on loopback when unset.
CHAINLIT_HOSTUIHost the UI binds to (default 127.0.0.1). Drives UI auth mode resolution.
CHAINLIT_USERNAMEUIUsername (default admin).
CHAINLIT_PASSWORDUIPassword (default admin).
PRAISONAI_ALLOW_DEFAULT_CREDSUIEscape hatch. Set to 1/true/yes to allow admin/admin on external bind. Unsafe — demo only.
CHAINLIT_AUTH_SECRETUISession secret. Auto-generated if unset (ephemeral per-process).

Error Reference

GatewayStartupError — raised by assert_external_bind_safe() when binding externally without a token:
Cannot bind to 0.0.0.0 without an auth token.
Fix:  praisonai onboard         (30 seconds, 3 prompts)
Or:   export GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)
UIStartupError — raised by register_password_auth() when admin/admin used on external bind:
Cannot bind to 0.0.0.0 with default admin/admin credentials.
Fix:  export CHAINLIT_USERNAME=myuser CHAINLIT_PASSWORD=mypass
Lab:  export PRAISONAI_ALLOW_DEFAULT_CREDS=1  (demo only)

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

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