トリガールールとセキュリティ
このページでは、Channel システムのトリガールール設定とセキュリティパイプラインの仕組みについて詳しく説明します。トリガールールは Agent がいつ返信するかを決定し、セキュリティパイプラインはメッセージが Agent に到達できるかどうかを決定します。
トリガールール
トリガールールは ChannelTriggerConfig で設定します。各 Channel インスタンスはこれらを個別に設定できます。
:::info ダイレクトメッセージは常にトリガーします トリガールールの設定に関係なく、ダイレクトメッセージ (DM) は常に Agent の返信をトリガーします。トリガールールが影響するのはグループチャット内のメッセージのみです。 :::
all モード — すべてのメッセージに返信
Agent はグループ内のすべてのメッセージに対して返信を生成します。
{
"mode": "all"
}
適している用途:
- 個人用ボット
- テスト環境
- 参加者が少ない小規模グループ
注: アクティブな複数人グループでこのモードを使用すると、多数の API 呼び出しが発生します。レート制限と併用することを推奨します。
mention モード — @メンション時に返信
Agent はメッセージ内で @メンションされた場合のみ返信します。一致しなかったメッセージはコンテキストとしてキャッシュされ(最大 50 件)、トリガーしたメッセージと一緒に Agent へ送信されるため、Agent はグループ会話の背景を理解できます。
{
"mode": "mention",
"mentionName": "Clawia"
}
適している用途:
- 共有の Discord/Slack サーバー
- 複数人の作業グループ
- ボットに頻繁に返信させたくない場合
mentionName フィールド: プラットフォーム上のボットのユーザー名を設定します。システムはメッセージ内容に @Clawia(大文字と小文字を区別)が含まれているかどうかを確認し、トリガーを発火するか判定します。
keyword モード — キーワードマッチング
Agent はメッセージに指定したキーワードが含まれている場合に返信します。キーワードマッチングは大文字と小文字を区別しません。
{
"mode": "keyword",
"keywords": ["help", "assist", "Clawia"]
}
適している用途:
- ユーザーが「help」と入力してボットをトリガーするカスタマーサービスのシナリオ
- 特定トピック向けのチャンネル
マッチングルール: メッセージ内容にいずれかのキーワードが含まれていれば、トリガーが発火します。たとえば、メッセージ Please help me look into this はキーワード help に一致します。
dm_only モード — ダイレクトメッセージのみ
Agent はダイレクトメッセージにのみ返信し、グループメッセージは完全に無視します(キャッシュなし、返信なし)。
{
"mode": "dm_only"
}
適している用途:
- パブリックサーバーにボットをデプロイしつつ、一対一の会話のみ受け付けたい場合
- プライバシーに配慮が必要なシナリオ
共通オプション
以下のオプションは、任意のトリガーモードと組み合わせて使用できます。
ignoreBot — ボット自身のメッセージを無視
{
"mode": "all",
"ignoreBot": true
}
true に設定すると、ボット自身が送信したメッセージは返信をトリガーしなくなり、自己対話ループを防ぎます。
allowFrom — 送信者の許可リスト
{
"mode": "all",
"allowFrom": ["123456789", "987654321"]
}
Agent の返信を、許可リスト内のユーザーからのメッセージのみに制限します。allowFrom にはプラットフォームのユーザー ID(例: Discord ユーザー ID)を指定します。
- 空の配列または
["*"]は、すべてのユーザーが許可されることを意味します - ID のマッチングでは大文字と小文字を区別しません
- このチェックはトリガーモードより優先されます: 許可リストに含まれないユーザーは、ボットを @メンションしても返信をトリガーしません
メッセージキャッシュの仕組み
mention モードと keyword モードでは、一致しなかったメッセージは破棄されず、スライディングウィンドウにキャッシュされます。
- 各「Channel インスタンス + チャットセッション」は、独立したメッセージバッファを維持します
- バッファには最新メッセージが最大 50 件保存されます(FIFO)
- トリガー条件が満たされると、バッファ内のすべてのメッセージがトリガーしたメッセージと一緒に Agent へ送信されます
- グループメッセージは XML 形式でラップされ、送信者、タイムスタンプ、その他のコンテキストが含まれます
これにより、Agent は @メンションされた際に単一のメッセージだけを見るのではなく、グループ会話の背景を理解できます。
セキュリティパイプライン
外部プラットフォームからのすべてのメッセージは、Agent に到達する前に 5 つのセキュリティレイヤーを順番に通過します。いずれかのレイヤーがメッセージをインターセプトした場合、後続のレイヤーは実行されません。
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
レイヤー 1: RateLimiter — レート制限
スライディングウィンドウ方式のレートリミッターで、永続化は不要なメモリ内実装です。
| 設定 | デフォルト | 説明 |
|---|---|---|
enabled | false | レート制限を有効にするかどうか |
maxPerMinute | 20 | ユーザーごとの 1 分あたりの最大メッセージ数 |
maxPerHour | 200 | ユーザーごとの 1 時間あたりの最大メッセージ数 |
globalMaxPerMinute | 60 | 全ユーザー合計の 1 分あたりの最大メッセージ数 |
動作: 制限を超えたメッセージは静かにドロップされます(返信なし、送信者への通知なし)。
レート制限キー: channelId + senderId で追跡されます。同じ Channel インスタンス内の同じユーザーからのメッセージは、同じクォータを共有します。
レート制限はデフォルトで無効です。悪意のあるスパムによって API コストが増加するのを防ぐため、公開向けのボットでは有効化することを推奨します。
レイヤー 2: InputSanitizer — 入力サニタイズ
メッセージから不可視の Unicode 制御文字を除去し、エンコーディングの悪用や難読化攻撃を防ぎます。
| 設定 | デフォルト | 説明 |
|---|---|---|
enabled | true | 入力サニタイズを有効にするかどうか |
stripControlChars | true | 制御文字を除去するかどうか |
除去される文字種:
- 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)
動作: サニタイズされたメッセージは次のレイヤーへ進みます。元のメッセージから除去された文字数がログに記録されます。メッセージはブロックされません。
レイヤー 3: PromptGuardian — プロンプトインジェクション検出
AI(LLM)を使用してメッセージをセマンティックレベルでセキュリティレビューし、プロンプトインジェクション、ジェイルブレイク、敵対的な操作を検出します。
| 設定 | オプション | 説明 |
|---|---|---|
mode | off / monitor / block | 動作モード |
モードの説明:
| モード | 動作 |
|---|---|
off | 完全に無効で、オーバーヘッドはありません(デフォルト) |
monitor | 検出してログに記録しますが、メッセージはブロックしません。誤検知率の評価に使用します |
block | インジェクションが検出された場合にメッセージをブロックし、送信者にユーモラスな受け流しメッセージを返信します |
設計原則:
- フェイルオープン: LLM レビューがタイムアウト(10 秒)またはエラーになった場合、セキュリティレイヤーの障害によって通常の通信がブロックされないよう、メッセージは自動的に通過を許可されます
- 短いメッセージ(10 文字未満)はレビューをスキップします
- 安全なメッセージの結果はキャッシュされ(SHA-256 ハッシュキー)、重複レビューを避けます
レイヤー 4: UserPermissionService — ユーザー権限
ロールベースのアクセス制御システムです。最初のメッセージを送信した外部ユーザーは、自動的に guest ロールで登録されます。
ロール階層
ロールは高い順に次のとおりです。
| ロール | チャット | ツール実行 | 確認が必要 | ユーザー管理 | 設定管理 |
|---|---|---|---|---|---|
| owner | 許可 | 許可 | いいえ | 許可 | 許可 |
| admin | 許可 | 許可 | いいえ | 許可 | いいえ |
| trusted | 許可 | 許可 | いいえ | いいえ | いいえ |
| member | 許可 | 許可 | はい | いいえ | いいえ |
| guest | 許可 | いいえ | — | いいえ | いいえ |
| blocked | いいえ | いいえ | — | いいえ | いいえ |
フィールドの説明:
- チャット: メッセージが Agent に到達することを許可されているかどうか(
canChat) - ツール実行: ファイルの読み書きやシェルコマンドなどのツール呼び出しをユーザーがトリガーできるかどうか(
canUseTool) - 確認が必要: 機密性の高いツール(シェル、ファイル書き込み)について、実行前に送信者が Channel 内で確認する必要があるかどうか(
requireConfirmation) - ユーザー管理: 自分より低いロールのユーザーを管理できるかどうか(
canManageUsers) - 設定管理: Agent およびセキュリティ関連の設定を変更できるかどうか(
canManageSettings)
デフォルトの動作:
- 新規ユーザーは自動的に
guestとして登録されます。チャットはできますが、ツールはトリガーできません blockedユーザーからのメッセージは静かにドロップされ、そのユーザーには禁止通知が送信されます- 管理者は Elftia インターフェースからユーザーのロールを変更できます
レイヤー 5: ChannelPermissionGate — 操作確認
member ロールのユーザーが機密性の高いツール(シェルコマンド、ファイル書き込みなど)をトリガーすると、システムはそれを直接実行せず、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]
確認返信のオプション:
| 返信 | 効果 |
|---|---|
y / yes / ok / confirm | この実行を承認する |
n / no / cancel / deny | この実行を拒否する |
always / always allow | 承認し、このツール + 引数の組み合わせを記憶します。以降の呼び出しは自動承認されます |
重要な詳細:
- 確認リクエストは、応答がないまま 5 分 経過すると自動拒否されます
- Channel + チャットセッションごとに、保留中の確認は最大 5 件 です
alwaysのスコープは、ツール + 引数の組み合わせに正確に限定されます(例: 「Bash: npm test を常に許可」は「Bash: rm -rf /」を自動承認しません)owner、admin、trustedロールでは確認は不要で、ツールは直接実行されますguestロールはツールをまったくトリガーできないため、確認ステップには到達しません
セキュリティ設定の推奨事項
個人利用
{
"rateLimiter": { "enabled": false },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "off" }
}
個人利用では厳格なセキュリティは不要です。入力サニタイズを有効にしておくだけで十分です。
小規模チーム
{
"rateLimiter": { "enabled": true, "maxPerMinute": 30, "maxPerHour": 300 },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "monitor" }
}
偶発的な大量投稿を防ぐため、レート制限を有効化します。まず PromptGuardian を monitor モードで使用し、誤検知率を評価してください。
公開向け
{
"rateLimiter": { "enabled": true, "maxPerMinute": 10, "maxPerHour": 100 },
"sanitizer": { "enabled": true },
"promptGuardian": { "mode": "block" }
}
セキュリティパイプラインをすべて有効化します。厳格なレート制限とプロンプトインジェクションのブロックを使用します。allowFrom 許可リストまたは mention トリガーモードと組み合わせることを推奨します。