You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PraisonAI PR #1517 (merged 2026-04-22) introduces bind-aware authentication posture for both the WebSocket Gateway and the Chainlit UI. Security defaults now change automatically based on the bind interface:
External (0.0.0.0, LAN IPs, public IPs) → strict mode (auth token required, admin/admin blocked)
This is a user-facing behaviour change that affects anyone running praisonai gateway start, praisonai chat, praisonai code, praisonai realtime, praisonai agents, or any Chainlit entry point. It also introduces new exceptions, new environment variables, and new helper functions that must be documented.
Note
A follow-up agent will create/update the docs based on this issue. Follow AGENTS.md rules strictly — new content goes in docs/features/, never docs/concepts/.
SDK Ground Truth (read these files first)
Per the AGENTS.md "SDK-First" cycle, read the actual source before writing docs:
frompraisonaiagentsimportAgentagent=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.1agent.start("hello")
# Option A: Run onboarding (recommended)
praisonai onboard
# Option B: Set a token explicitlyexport GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)
praisonai gateway start --host 0.0.0.0
How It Works — sequence diagram + table:
sequenceDiagram
participant User
participant Gateway
participant BindAwareAuth
participant WS as WebSocket Clients
User->>Gateway: praisonai gateway start --host <H>
Gateway->>BindAwareAuth: assert_external_bind_safe(config)
alt H is loopback (127.0.0.1, localhost, ::1)
BindAwareAuth-->>Gateway: OK (permissive, warn if no token)
else H is external (0.0.0.0, LAN, public)
alt auth_token set
BindAwareAuth-->>Gateway: OK (strict)
else no token
BindAwareAuth-->>Gateway: raise GatewayStartupError
Gateway-->>User: exit 1 + fix instructions
end
end
Gateway->>WS: accept connections
Loading
Auth Modes table (from AuthMode literal):
Mode
Meaning
Trigger
local
Permissive — no token required
Loopback bind (default)
token
Token required (auto-generated if absent on loopback)
User interaction flows (required by AGENTS.md §1.1 rule 10):
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 table (NEW in this PR):
Variable
Scope
Effect
GATEWAY_AUTH_TOKEN
Gateway
Auth token. Required on external bind. Auto-generated + saved to ~/.praisonai/.env (mode 0600) on loopback when unset.
CHAINLIT_HOST
UI
Host the UI binds to (default 127.0.0.1). Drives UI auth mode resolution.
CHAINLIT_USERNAME
UI
Username (default admin).
CHAINLIT_PASSWORD
UI
Password (default admin).
PRAISONAI_ALLOW_DEFAULT_CREDS
UI
Escape hatch. Set to 1/true/yes to allow admin/admin on external bind. Unsafe — demo only.
CHAINLIT_AUTH_SECRET
UI
Session secret. Auto-generated if unset (ephemeral per-process).
Error reference (NEW exceptions):
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 — explain that logs now show gw_****XXXX (last 4 chars), never the raw token. Cite get_auth_token_fingerprint().
Which option when — decision diagram (required by AGENTS.md §6.1):
graph TB
Q{Where will it run?}
Q -->|My laptop only| Local[127.0.0.1 — just run it]
Q -->|LAN for my team| LAN{Have a token?}
Q -->|Public internet| Public[0.0.0.0 + token + TLS + custom creds]
LAN -->|No| Onboard[praisonai onboard]
LAN -->|Yes| Export[export GATEWAY_AUTH_TOKEN=...]
classDef question fill:#F59E0B,stroke:#7C90A0,color:#fff
classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
classDef action fill:#189AB4,stroke:#7C90A0,color:#fff
classDef strict fill:#8B0000,stroke:#7C90A0,color:#fff
class Q,LAN question
class Local safe
class Onboard,Export action
class Public strict
Loading
Best Practices (AccordionGroup, 3–4 items):
Prefer praisonai onboard over manual token creation
Never commit ~/.praisonai/.env
Set custom CHAINLIT_USERNAME/CHAINLIT_PASSWORD before binding externally
Use PRAISONAI_ALLOW_DEFAULT_CREDS=1 only for ephemeral demos
Related (CardGroup cols={2}):
Link to docs/gateway.mdx
Link to docs/features/onboard.mdx
Link to docs/guides/troubleshoot-gateway.mdx
Link to docs/features/chat.mdx
Writing style reminders (AGENTS.md §6)
One-sentence section intros. No "In this section…", "As you can see…", "It's important to note…".
Agent-centric: start examples with from praisonaiagents import Agent.
Non-developer friendly: make the reader feel "is it this easy?"
Active voice, short, concise.
2. UPDATE — docs/gateway.mdx
Add a new "Authentication" section between "How It Works" and "Configuration Options":
One-sentence intro: "Authentication posture changes automatically based on the bind interface."
Related upcoming work (from PR body): Issues B (magic-link), C (Origin/CSRF), D (UI pairing banner), E (owner-DM pairing buttons) — this page will be the parent for those additions.
Follow AGENTS.md in this repo for structure, style, diagram colors, and placement rules.
Summary
PraisonAI PR #1517 (merged 2026-04-22) introduces bind-aware authentication posture for both the WebSocket Gateway and the Chainlit UI. Security defaults now change automatically based on the bind interface:
127.0.0.1,localhost,::1) → permissive mode (quickstart preserved)0.0.0.0, LAN IPs, public IPs) → strict mode (auth token required,admin/adminblocked)This is a user-facing behaviour change that affects anyone running
praisonai gateway start,praisonai chat,praisonai code,praisonai realtime,praisonai agents, or any Chainlit entry point. It also introduces new exceptions, new environment variables, and new helper functions that must be documented.Note
A follow-up agent will create/update the docs based on this issue. Follow
AGENTS.mdrules strictly — new content goes indocs/features/, neverdocs/concepts/.SDK Ground Truth (read these files first)
Per the AGENTS.md "SDK-First" cycle, read the actual source before writing docs:
Core protocols (Python)
src/praisonai-agents/praisonaiagents/gateway/protocols.pyAuthMode = Literal["local", "token", "password", "trusted-proxy"]is_loopback(host: str) -> boolresolve_auth_mode(bind_host: str, configured: Optional[AuthMode] = None) -> AuthModesrc/praisonai-agents/praisonaiagents/gateway/config.pyGatewayConfig:bind_host: Optional[str] = None(defaults tohostvia__post_init__)Gateway enforcement (wrapper)
src/praisonai/praisonai/gateway/auth.py(NEW FILE)class GatewayStartupError(Exception)assert_external_bind_safe(config: GatewayConfig) -> Noneget_auth_token_fingerprint(token: str) -> str→gw_****XXXXformatsave_auth_token_to_env(token: str, env_file: Optional[str] = None) -> None→ writes to~/.praisonai/.envwith mode0600src/praisonai/praisonai/gateway/server.pyassert_external_bind_safe(self.config)instart()~/.praisonai/.envUI enforcement (wrapper)
src/praisonai/praisonai/ui/_auth.py(NEW FILE)class UIStartupError(Exception)register_password_auth(app, *, bind_host: str) -> None— consolidated from 6 duplicated callbacksregister_password_auth):praisonai/ui/chat.pypraisonai/ui/bot.pypraisonai/ui/agents.pypraisonai/ui/realtime.pypraisonai/ui/code.pypraisonai/ui/colab_chainlit.pyTests (reference for behaviour)
src/praisonai/tests/unit/gateway/test_bind_aware_auth.pysrc/praisonai/tests/unit/ui/test_ui_bind_aware_creds.pysrc/praisonai/tests/integration/gateway/test_bind_aware_e2e.pyDecision: Create New + Update Existing
I checked the existing docs repo. Result:
docs/gateway.mdxdocs/features/bot-gateway.mdxdocs/guides/troubleshoot-gateway.mdxGatewayStartupErrorandUIStartupErrordocs/features/chat.mdxCHAINLIT_HOST,PRAISONAI_ALLOW_DEFAULT_CREDS, strict-mode behaviourdocs/features/onboard.mdxGATEWAY_AUTH_TOKEN~/.praisonai/.envwith mode0600docs/features/gateway-bind-aware-auth.mdxdocs.jsonImportant
Per
AGENTS.md§1.8: never place this indocs/concepts/. That folder is human-approved only. Place the new page indocs/features/.1. CREATE —
docs/features/gateway-bind-aware-auth.mdxFollow the AGENTS.md §2 "Page Structure Template" exactly. Agent-centric, non-developer friendly, progressive disclosure.
Frontmatter
Required content outline
One-sentence intro
Hero Mermaid diagram (use the standard color scheme from AGENTS.md §3.1):
graph LR subgraph "Bind-Aware Auth" Bind[🔌 Bind Host] --> Check{🔍 Loopback?} Check -->|Yes 127.0.0.1| Local[🟢 local mode<br/>no token required] Check -->|No 0.0.0.0| Token[🔒 token mode<br/>auth required] end classDef bind fill:#6366F1,stroke:#7C90A0,color:#fff classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff classDef permissive fill:#10B981,stroke:#7C90A0,color:#fff classDef strict fill:#8B0000,stroke:#7C90A0,color:#fff class Bind bind class Check decision class Local permissive class Token strictQuick Start (Steps component) — agent-centric, per AGENTS.md §1.1 rule 9:
Step 1: Local development (loopback — permissive)
Step 2: External deployment (strict — token required)
How It Works — sequence diagram + table:
sequenceDiagram participant User participant Gateway participant BindAwareAuth participant WS as WebSocket Clients User->>Gateway: praisonai gateway start --host <H> Gateway->>BindAwareAuth: assert_external_bind_safe(config) alt H is loopback (127.0.0.1, localhost, ::1) BindAwareAuth-->>Gateway: OK (permissive, warn if no token) else H is external (0.0.0.0, LAN, public) alt auth_token set BindAwareAuth-->>Gateway: OK (strict) else no token BindAwareAuth-->>Gateway: raise GatewayStartupError Gateway-->>User: exit 1 + fix instructions end end Gateway->>WS: accept connectionsAuth Modes table (from
AuthModeliteral):localtokenpasswordtrusted-proxyInterface detection table (from
is_loopback()tests):is_loopback()127.0.0.1Truelocal127.255.255.255TruelocallocalhostTruelocal::1Truelocal0.0.0.0Falsetoken192.168.1.xFalsetoken10.0.0.xFalsetoken8.8.8.8(public)FalsetokenUser interaction flows (required by AGENTS.md §1.1 rule 10):
127.0.0.1, no config needed. Token auto-generated, fingerprint logged (gw_****abcd), saved to~/.praisonai/.env.praisonai onboard(30s, 3 prompts) ORexport GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)→praisonai gateway start --host 0.0.0.0.CHAINLIT_USERNAME/CHAINLIT_PASSWORDfor the UI, and consider TLS.export PRAISONAI_ALLOW_DEFAULT_CREDS=1.Environment variables table (NEW in this PR):
GATEWAY_AUTH_TOKEN~/.praisonai/.env(mode0600) on loopback when unset.CHAINLIT_HOST127.0.0.1). Drives UI auth mode resolution.CHAINLIT_USERNAMEadmin).CHAINLIT_PASSWORDadmin).PRAISONAI_ALLOW_DEFAULT_CREDS1/true/yesto allowadmin/adminon external bind. Unsafe — demo only.CHAINLIT_AUTH_SECRETError reference (NEW exceptions):
GatewayStartupError— raised byassert_external_bind_safe()when binding externally without a token:UIStartupError— raised byregister_password_auth()whenadmin/adminused on external bind:Token fingerprinting — explain that logs now show
gw_****XXXX(last 4 chars), never the raw token. Citeget_auth_token_fingerprint().Which option when — decision diagram (required by AGENTS.md §6.1):
graph TB Q{Where will it run?} Q -->|My laptop only| Local[127.0.0.1 — just run it] Q -->|LAN for my team| LAN{Have a token?} Q -->|Public internet| Public[0.0.0.0 + token + TLS + custom creds] LAN -->|No| Onboard[praisonai onboard] LAN -->|Yes| Export[export GATEWAY_AUTH_TOKEN=...] classDef question fill:#F59E0B,stroke:#7C90A0,color:#fff classDef safe fill:#10B981,stroke:#7C90A0,color:#fff classDef action fill:#189AB4,stroke:#7C90A0,color:#fff classDef strict fill:#8B0000,stroke:#7C90A0,color:#fff class Q,LAN question class Local safe class Onboard,Export action class Public strictBest Practices (
AccordionGroup, 3–4 items):praisonai onboardover manual token creation~/.praisonai/.envCHAINLIT_USERNAME/CHAINLIT_PASSWORDbefore binding externallyPRAISONAI_ALLOW_DEFAULT_CREDS=1only for ephemeral demosRelated (
CardGroup cols={2}):docs/gateway.mdxdocs/features/onboard.mdxdocs/guides/troubleshoot-gateway.mdxdocs/features/chat.mdxWriting style reminders (AGENTS.md §6)
from praisonaiagents import Agent.2. UPDATE —
docs/gateway.mdxAdd a new "Authentication" section between "How It Works" and "Configuration Options":
docs/features/gateway-bind-aware-auth.mdxAlso add
bind_hostto theGatewayConfigsection if it isn't already.3. UPDATE —
docs/guides/troubleshoot-gateway.mdxAdd two new troubleshooting entries:
"GatewayStartupError: Cannot bind to 0.0.0.0 without an auth token"
GATEWAY_AUTH_TOKENpraisonai onboardorexport GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16)"UIStartupError: Cannot bind to 0.0.0.0 with default admin/admin credentials"
CHAINLIT_USERNAME/CHAINLIT_PASSWORD, or setPRAISONAI_ALLOW_DEFAULT_CREDS=1for demos"My gateway logs show
gw_****xxxxinstead of the full token"~/.praisonai/.env(GATEWAY_AUTH_TOKEN).4. UPDATE —
docs/features/chat.mdxAdd a "Security" or "Auth" subsection covering:
CHAINLIT_HOSTenvironment variable (default127.0.0.1)admin/adminis blocked on external bindPRAISONAI_ALLOW_DEFAULT_CREDS=1escape hatch (with a<Warning>callout)register_password_auth()(mention, don't deep-dive — user-focused)5. UPDATE —
docs/features/onboard.mdxSmall additions:
~/.praisonai/.envis written with mode0600.gw_****wxyz) consistent with new logging.<Note>linking to the new bind-aware auth page.6. UPDATE —
docs.jsonAdd the new page under the "Features" group (NOT "Concepts" — see AGENTS.md §1.8):
{ "group": "Features", "pages": [ // ...existing entries... "docs/features/gateway-bind-aware-auth" ] }Validate the JSON after editing (AGENTS.md §1.9 rule 8).
Acceptance Criteria
docs/features/gateway-bind-aware-auth.mdxexists and passes AGENTS.md §9 quality checklist<Steps>,<AccordionGroup>,<CardGroup>) per AGENTS.md §4.1GATEWAY_AUTH_TOKEN,CHAINLIT_HOST,CHAINLIT_USERNAME,CHAINLIT_PASSWORD,PRAISONAI_ALLOW_DEFAULT_CREDS,CHAINLIT_AUTH_SECRETGatewayStartupError,UIStartupErrorgw_****XXXX) mentioned~/.praisonai/.envmode0600persistence mentionedlocalhost, external examplesdocs/gateway.mdxhas a new Authentication section linking to the new pagedocs/guides/troubleshoot-gateway.mdxhas new entries for both new errors + fingerprint loggingdocs/features/chat.mdxdocumentsCHAINLIT_HOST+PRAISONAI_ALLOW_DEFAULT_CREDSdocs/features/onboard.mdxcross-links to the new page and notes0600permsdocs.jsonupdated under Features group (not Concepts), JSON validatesdocs/concepts/(AGENTS.md §1.8 forbids this)References
AGENTS.mdin this repo for structure, style, diagram colors, and placement rules.