Quick Start
1
Default-Deny Allowlist
Permit only specific targets — everything else is blocked.The agent can only send to
origin (the conversation it came from) or the ops-alerts alias. Any other target returns a clean denial string instead of delivering.2
Default-Allow with Denylist
Allow everything except specific channels you want to protect.The agent can send to any target except the protected executive channels.
3
YAML Configuration
Set the policy in
gateway.yaml without writing Python:How It Works
Denial is model-readable. A well-instructed agent reads the failure string and recovers gracefully — for example, routing to an allowed channel or asking the user to confirm before proceeding.
The check sits in core (
praisonaiagents), so every messenger implementation is constrained — not just one adapter. Absent a policy, all sends are allowed (backwards compatible).
Configuration Options
SendPolicy
Import: from praisonaiagents.gateway.protocols import SendPolicy
Matching uses exact string comparison against the symbolic target token (e.g.
"origin", "slack:#ops", a friendly alias). Passing any value other than "allow" or "deny" for default raises ValueError at construction time.
SendDecision
Import: from praisonaiagents.gateway.protocols import SendDecision
SendDecision is a frozen dataclass — immutable once created.
SendPolicyProtocol
Import: from praisonaiagents.gateway.protocols import SendPolicyProtocol
SessionContext.
Common Patterns
Default-Deny Allowlist (Production)
Safest posture: only explicitly listed targets can receive messages.Default-Allow with Denylist
Lighter-weight for trusted environments where you only want to protect a few channels.Custom Protocol — Time-Window Restriction
SendPolicy:
Custom Protocol — Per-Agent RBAC
Threat Model
Concretely:- Prompt injection in a retrieved document instructs the agent to
send_message("slack:#exec", "<sensitive data>"). - Without a send policy, the message is delivered.
- With
SendPolicy(default="deny", allow=["origin"]), the call fails with a clean denial string. The agent reads it, cannot comply, and the data stays contained.
Best Practices
Prefer default='deny' for production deployments
Prefer default='deny' for production deployments
Start with the most restrictive posture and explicitly list every channel the agent legitimately needs. This gives you a clear audit trail and prevents unexpected delivery as new channels are added.
Always include 'origin' in the allowlist
Always include 'origin' in the allowlist
Unless you specifically want to prevent the agent from replying to the conversation it came from, include
"origin" in the allow list. Without it, default="deny" will block even simple replies.Keep policies in version control alongside gateway.yaml
Keep policies in version control alongside gateway.yaml
Whether you use Python or YAML config, commit your send policy alongside the rest of your gateway configuration. This ensures policy changes go through code review and are tracked in history.
Use SendPolicyProtocol for dynamic rules
Use SendPolicyProtocol for dynamic rules
If your rules depend on runtime state (user roles, time of day, session metadata), implement
SendPolicyProtocol rather than rebuilding a SendPolicy instance per request. The agent_id, session_id, and origin kwargs give you the context you need.Behaviour Reference
Related
Send Message Tool
Let agents proactively deliver messages to users mid-task.
Messaging Bots
Deploy AI agents to Telegram, Discord, Slack, and WhatsApp.
Bot Rate Limiting
Throttle how often agents can respond per user or channel.
Guardrails
Add input and output safety checks to your agents.

