Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
"docs/features/bot-gateway",
"docs/features/bot-routing",
"docs/features/bot-pairing",
"docs/features/bot-unknown-user-pairing",
"docs/features/botos",
"docs/features/push-notifications"
]
Expand Down
81 changes: 70 additions & 11 deletions docs/best-practices/bot-security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -224,21 +224,78 @@ channels:
WhatsApp has the **strongest security defaults** and serves as the reference implementation for other channels.
</Tip>

## Gateway Pairing
## Owner-DM Pairing

For production deployments, use **gateway pairing** to authorize channels dynamically with the shipped pairing system:
The pairing system is now shipped and enables owner-approval for unknown users with inline Approve/Deny buttons sent directly to your DM.

For production deployments, use **owner-DM pairing** to authorize unknown users dynamically:

### 1. Set Callback Secret

```bash
export PRAISONAI_CALLBACK_SECRET="$(openssl rand -hex 32)"
```

<Warning>
Without `PRAISONAI_CALLBACK_SECRET`, inline-button callbacks will **not work across restarts**. Set this in production.
</Warning>

### 2. Configure Unknown User Policy

```python
from praisonaiagents import Agent
from praisonaiagents.bots import BotConfig

config = BotConfig(
token="your-bot-token",
unknown_user_policy="pair", # Enable owner-approval workflow
owner_user_id="123456789", # Your platform user ID
)

agent = Agent(
name="Support Bot",
instructions="Help users with their questions",
)
```

### 3. Owner Approval Workflow

When an unknown user messages your bot:

1. Bot generates a pairing code
2. **Owner receives DM with inline Approve/Deny buttons**
3. Owner clicks Approve → User is permanently approved
4. Owner clicks Deny → Request is rejected

**CLI Fallback:** If `owner_user_id` is not set, the bot replies:
```
Your pairing code: abc12345. Ask the owner to run: praisonai pairing approve telegram abc12345
```

### 1. Set Gateway Secret
### 4. Manual Approval (CLI)

Owners can approve pairing requests manually:

```bash
export PRAISONAI_GATEWAY_SECRET="your-secure-secret-key"
# Approve a specific pairing code
praisonai pairing approve telegram abc12345

# Approve for Discord
praisonai pairing approve discord def67890

# Approve for Slack
praisonai pairing approve slack ghi13579
```

## Gateway Pairing

For production deployments, use **gateway pairing** to authorize channels dynamically with the shipped pairing system:

<Note>
The gateway secret is optional - if unset, a per-install secret is auto-generated at `<store_dir>/.gateway_secret` with `0600` permissions and reused across restarts.
</Note>

### 2. Enable Pairing Policy
### Enable Pairing Policy

```python
from praisonaiagents.bots import BotConfig
Expand All @@ -251,7 +308,7 @@ config = BotConfig(
# Unknown users will automatically receive pairing codes when they DM the bot
```

### 3. Approve Pairing Requests
### Approve Pairing Requests

When unknown users DM your bot, they receive pairing codes. Approve them via CLI:

Expand All @@ -261,7 +318,7 @@ When unknown users DM your bot, they receive pairing codes. Approve them via CLI
praisonai pairing approve telegram ABCD1234 --label "alice"
```

### 4. Manage Pairings
### Manage Pairings

```bash
# List all paired channels
Expand All @@ -278,7 +335,7 @@ praisonai pairing clear --confirm
For detailed pairing documentation, see the [Bot Pairing](/docs/features/bot-pairing) guide.
</Tip>

### 5. List Pending Requests
### List Pending Requests

List all pending pairing codes waiting for approval:

Expand Down Expand Up @@ -312,7 +369,7 @@ telegram_only = store.list_pending(channel_type="telegram")
Canonical keys (`code`, `channel_type`, `channel_id`, `created_at`) are the stable contract. The `channel`, `user_id`, `user_name`, and `age_seconds` aliases are provided for UI consumers and should not be relied on for scripting — use the canonical keys.
</Note>

### 6. CLI Commands
### CLI Commands

Use the `praisonai pairing` commands to manage pairings from the command line:

Expand Down Expand Up @@ -442,8 +499,10 @@ Remediation: Consider allowlists for DM security and 'mention_only' group policy

<Accordion title="✅ Gateway Pairing Active" icon="link">
- [ ] `PRAISONAI_GATEWAY_SECRET` set
- [ ] Pairing codes generated and shared securely
- [ ] All production channels paired and verified
- [ ] `PRAISONAI_CALLBACK_SECRET` set (for inline buttons)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While adding the new PRAISONAI_CALLBACK_SECRET here, the accordion title (line 323) and the old PRAISONAI_GATEWAY_SECRET (line 324) should also be updated to match the new "Owner-DM Pairing" terminology used earlier in the document. This ensures consistency in the security checklist.

- [ ] `unknown_user_policy` configured (`deny`/`pair`/`allow`)
- [ ] `owner_user_id` set for inline approvals
- [ ] Pairing workflow tested and verified
- [ ] Revocation process documented
</Accordion>

Expand Down
Loading