Secure unknown user onboarding with CLI-approved pairing codes
Bot platform adapters now ship in the praisonai-bot package. praisonai bot serve still works exactly as documented here; for a standalone install see praisonai-bot Migration.
Bot pairing lets unknown users self-request access to your bot with secure 8-character codes that you approve from the CLI.
from praisonaiagents import Agent, BotConfigagent = Agent(name="assistant", instructions="You are a helpful assistant.")config = BotConfig(unknown_user_policy="pair")agent.start("An unknown user wants access — generate a pairing code.")
The user DMs the bot for the first time; PraisonAI issues an 8-character code you approve from the CLI.
# Revoke specific channelpraisonai pairing revoke telegram 987654321# Clear all pairings (with confirmation)praisonai pairing clear# Are you sure you want to clear ALL paired channels? [y/N]: y# ✅ Cleared 3 paired channels# Clear without confirmation promptpraisonai pairing clear --confirm
All three routes are gated by an admin auth checker (auth_admin) wired in by create_pairing_routes(pairing_store, auth_admin). Non-admin sessions receive 403. Invalid codes return 404.
The code parameter on /approve is consumed atomically — replays return 404.
Subscribe to the pairing_approved event to run agent logic the moment a channel is approved — for example, send a welcome DM, log to your CRM, or warm a per-user memory store.
from praisonaiagents import Agentfrom praisonaiagents.bus import get_default_buswelcomer = Agent( name="Welcomer", instructions="Write a one-line friendly welcome message for a new user.",)def on_pairing_approved(event): channel = event.data["channel"] code = event.data["code"] welcome = welcomer.start(f"Welcome the new {channel} user with code {code}") print(welcome)get_default_bus().subscribe(on_pairing_approved, ["pairing_approved"])
Platform Implementation Status: PR #1504 ships the pairing system and CLI with full Telegram support. Other platform adapters need handler wiring to complete the integration.
# Option 1: Set explicit gateway secret (recommended for production)export PRAISONAI_GATEWAY_SECRET="your-secure-secret-key"# Option 2: Auto-generated per-install secret# Stored at <store_dir>/.gateway_secret with 0600 permissions# Persists across restarts, unique per installation
Secret Persistence: Without PRAISONAI_GATEWAY_SECRET, a per-install secret is auto-generated and stored at <store_dir>/.gateway_secret with mode 0600. This file is critical for code verification across restarts.
Set PRAISONAI_GATEWAY_SECRET explicitly in production environments to ensure consistent code verification across deployments.
# Generate secure secretopenssl rand -hex 32 > gateway_secret.txt# Set in productionexport PRAISONAI_GATEWAY_SECRET=$(cat gateway_secret.txt)
Monitor Rate Limits
Watch for rate limiting warnings in logs - they indicate potential pairing spam or legitimate users hitting limits.
# Look for these log patterns:# DEBUG: Rate limited channel 123456 (last code: 45.2s ago)# INFO: Generated pairing code for user123 on telegram: ABCD1234
Use Descriptive Labels
Add labels when approving pairings to identify channels later.
# Good - easy to identifypraisonai pairing approve telegram ABCD1234 --label "alice-work"praisonai pairing approve telegram EFGH5678 --label "bob-personal"# Less helpfulpraisonai pairing approve telegram ABCD1234
Regular Pairing Audits
Periodically review paired channels and revoke access for inactive users.
# Review all pairingspraisonai pairing list# Revoke specific channels praisonai pairing revoke telegram 987654321# Clear all if starting freshpraisonai pairing clear --confirm
Pair a user with a non-empty --label (the canonical id) and StoreBackedIdentityResolver automatically unifies their session across every channel paired under the same label. No separate praisonai identity link calls needed. See Cross-Platform Sessions › StoreBackedIdentityResolver.