Trigger Rules & Security
This page covers the Channel system's trigger rule configuration and security pipeline mechanism in detail. Trigger rules determine when the Agent replies; the security pipeline determines whether a message can reach the Agent.
Trigger Rules
Trigger rules are configured via ChannelTriggerConfig. Each Channel instance can set these independently.
:::info Direct Messages Always Trigger Regardless of how trigger rules are configured, direct messages (DMs) always trigger an Agent reply. Trigger rules only affect messages in group chats. :::
all Mode — Reply to All Messages
The Agent generates a reply for every message in the group.
{
"mode": "all"
}
Best for:
- Personal bots
- Test environments
- Small groups with few participants
Note: Using this mode in an active, multi-person group causes a large number of API calls. It is recommended to use it with rate limiting.
mention Mode — Reply When @Mentioned
The Agent replies only when @mentioned in a message. Unmatched messages are cached as context (up to 50 messages) and sent to the Agent together with the triggering message so it understands the group conversation background.
{
"mode": "mention",
"mentionName": "Clawia"
}
Best for:
- Shared Discord/Slack servers
- Multi-person work groups
- When you don't want the bot to reply too frequently
mentionName field: Set this to the bot's username on the platform. The system checks whether the message content contains @Clawia (case-sensitive) to determine if a trigger fires.
keyword Mode — Keyword Matching
The Agent replies when the message contains a specified keyword. Keyword matching is case-insensitive.
{
"mode": "keyword",
"keywords": ["help", "assist", "Clawia"]
}
Best for:
- Customer service scenarios where users type "help" to trigger the bot
- Topic-specific channels
Matching rule: The trigger fires as long as the message content contains any one of the keywords. For example, the message Please help me look into this matches the keyword help.
dm_only Mode — Direct Messages Only
The Agent replies only to direct messages and completely ignores group messages (no caching, no reply).
{
"mode": "dm_only"
}
Best for:
- Deploying a bot on a public server but accepting only one-on-one conversations
- Privacy-sensitive scenarios
General Options
The following options can be combined with any trigger mode:
ignoreBot — Ignore Bot's Own Messages
{
"mode": "all",
"ignoreBot": true
}
When set to true, messages sent by the bot itself do not trigger a reply, preventing self-conversation loops.
allowFrom — Sender Allowlist
{
"mode": "all",
"allowFrom": ["123456789", "987654321"]
}
Restricts Agent replies to only users in the allowlist. allowFrom contains platform user IDs (e.g., Discord user IDs).
- An empty array or
["*"]means all users are allowed - ID matching is case-insensitive
- This check takes priority over the trigger mode: users not in the allowlist will not trigger a reply even if they @mention the bot
Message Caching Mechanism
In mention and keyword modes, unmatched messages are not discarded — they are cached in a sliding window:
- Each "Channel instance + chat session" maintains an independent message buffer
- The buffer stores a maximum of 50 recent messages (FIFO)
- When a trigger condition is met, all messages in the buffer are sent to the Agent together with the triggering message
- Group messages are wrapped in XML format, including sender, timestamp, and other context
This allows the Agent to understand the group conversation background when @mentioned, rather than seeing only a single message.
Security Pipeline
Every message from an external platform passes through 5 security layers in sequence before reaching the Agent. If any layer intercepts the message, subsequent layers do not execute.
Message enters
│
├── [1] RateLimiter ─── Rate exceeded? → Silently drop
│
├── [2] InputSanitizer ─── Contains control characters? → Strip and continue
│
├── [3] PromptGuardian ─── Injection attack detected? → Block + reply with deflection message
│
├── [4] UserPermissionService ─── User role forbidden? → Block
│
├── [5] ChannelPermissionGate ─── Is this a permission confirmation reply? → Consume the message
│
└── Trigger rule matching → Route to Agent
Layer 1: RateLimiter — Rate Limiting
A sliding-window rate limiter, implemented in memory with no need for persistence.
| Config | Default | Description |
|---|---|---|
enabled | false | Whether to enable rate limiting |
maxPerMinute | 20 | Max messages per user per minute |
maxPerHour | 200 | Max messages per user per hour |
globalMaxPerMinute | 60 | Max messages from all users combined per minute |
Behavior: Messages that exceed the limit are silently dropped (no reply, no notification to the sender).
Rate limit key: Tracked by channelId + senderId; messages from the same user in the same Channel instance share a quota.
Rate limiting is disabled by default. It is recommended to enable it for bots facing the public to prevent malicious spam from driving up API costs.
Layer 2: InputSanitizer — Input Sanitization
Strips invisible Unicode control characters from messages to prevent encoding exploits and obfuscation attacks.
| Config | Default | Description |
|---|---|---|
enabled | true | Whether to enable input sanitization |
stripControlChars | true | Whether to strip control characters |
Character types stripped:
- Null bytes (
\x00) - Zero-width spaces (
-) - Unicode bidirectional control characters (
-) - BOM marker (
) - Other C0/C1 control characters (common whitespace such as newlines and tabs are preserved)
Behavior: The sanitized message continues to the next layer. The count of characters stripped from the original message is logged. The message is not blocked.
Layer 3: PromptGuardian — Prompt Injection Detection
Uses an AI (LLM) to perform a semantic-level security review of messages, detecting prompt injection, jailbreaks, and adversarial manipulation.
| Config | Options | Description |
|---|---|---|
mode | off / monitor / block | Operating mode |
Mode descriptions:
| Mode | Behavior |
|---|---|
off | Completely disabled, zero overhead (default) |
monitor | Detects and logs, but does not block messages. Use to assess false-positive rates |
block | Blocks the message when injection is detected and replies to the sender with a humorous deflection message |
Design principles:
- Fail-open: if the LLM review times out (10 seconds) or errors, the message is automatically allowed through so that a security layer failure does not block normal communication
- Short messages (fewer than 10 characters) skip the review
- Safe message results are cached (SHA-256 hash key) to avoid redundant reviews
Layer 4: UserPermissionService — User Permissions
A role-based access control system. External users who send their first message are automatically registered with the guest role.
Role Hierarchy
Roles from highest to lowest:
| Role | Chat | Tool Execution | Requires Confirmation | Manage Users | Manage Settings |
|---|---|---|---|---|---|
| owner | Allowed | Allowed | No | Allowed | Allowed |
| admin | Allowed | Allowed | No | Allowed | No |
| trusted | Allowed | Allowed | No | No | No |
| member | Allowed | Allowed | Yes | No | No |
| guest | Allowed | No | — | No | No |
| blocked | No | No | — | No | No |
Field descriptions:
- Chat: whether the message is allowed to reach the Agent (
canChat) - Tool execution: whether the user can trigger tool calls such as file reads/writes and shell commands (
canUseTool) - Requires confirmation: whether sensitive tools (shell, file writes) require the sender to confirm in the Channel before execution (
requireConfirmation) - Manage users: whether the user can manage users with lower roles (
canManageUsers) - Manage settings: whether the user can modify Agent and security-related settings (
canManageSettings)
Default behavior:
- New users are automatically registered as
guest; they can chat but cannot trigger tools - Messages from
blockedusers are silently dropped, and the user receives a ban notification - Admins can change user roles through the Elftia interface
Layer 5: ChannelPermissionGate — Operation Confirmation
When a member-role user triggers a sensitive tool (shell commands, file writes, etc.), the system does not execute it directly — instead it sends a confirmation request in the Channel:
⚠️ Permission Required
Clawia wants to execute: **Shell Command**
> npm test
Reply: **y** (approve) / **n** (deny) / **always** (always allow this tool)
⏱ Auto-denied in 5 minutes. [confirm-xxx]
Confirmation reply options:
| Reply | Effect |
|---|---|
y / yes / ok / confirm | Approve this execution |
n / no / cancel / deny | Deny this execution |
always / always allow | Approve and remember this tool + argument combination; auto-approve subsequent calls |
Key details:
- Confirmation requests auto-deny after 5 minutes of no response
- A maximum of 5 pending confirmations per Channel + chat session
- The scope of
alwaysis precise to the tool + argument combination (e.g., "always allow Bash: npm test" does not auto-approve "Bash: rm -rf /") owner,admin, andtrustedroles never need confirmation; tools execute directlyguestrole cannot trigger tools at all and never reaches the confirmation step
Security Configuration Recommendations
Personal Use
{
"rateLimiter": { "enabled": false },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "off" }
}
Personal use does not require strict security. Keeping input sanitization enabled is sufficient.
Small Team
{
"rateLimiter": { "enabled": true, "maxPerMinute": 30, "maxPerHour": 300 },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "monitor" }
}
Enable rate limiting to prevent accidental flooding. Use PromptGuardian in monitor mode first to assess the false-positive rate.
Public-Facing
{
"rateLimiter": { "enabled": true, "maxPerMinute": 10, "maxPerHour": 100 },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "block" }
}
Enable the full security pipeline. Strict rate limiting + prompt injection blocking. Recommended to combine with an allowFrom allowlist or mention trigger mode.