Skip to content
このページは AI の支援により作成・翻訳されました。誤りがあれば、改善にご協力ください。 GitHub で編集

WSSトンネル

WSSトンネル(フェーズB)はOpenPR-WebhookからコントロールプレーンサーバーへのアクティブなWebSocket接続を提供します。インバウンドHTTP Webhookを待つ代わりに、トンネルによりコントロールプレーンが永続的な接続を通じてエージェントに直接タスクをプッシュできます。

これはWebhookサービスがNATやファイアウォールの背後で実行されており、インバウンドHTTPリクエストを受信できない場合に特に便利です。

動作の仕組み

コントロールプレーン (wss://...)
    ^         |
    |         | task.dispatch
    |         v
+-------------------+
| openpr-webhook    |
|   tunnel client   |
|                   |
| task.ack  ------->|
| heartbeat ------->|
| task.result ----->|
+-------------------+
    |
    v
  CLIエージェント (codex / claude-code / opencode)
  1. OpenPR-WebhookがコントロールプレーンのURLへのWebSocket接続を開く
  2. AuthorizationヘッダーのBearerトークンで認証する
  3. 接続を維持するために定期的なハートビートメッセージを送信する
  4. コントロールプレーンからtask.dispatchメッセージを受信する
  5. task.ackですぐに確認する
  6. CLIエージェントを通じて非同期でタスクを実行する
  7. 実行完了時にtask.resultを送り返す

トンネルの有効化

トンネルを有効にするには2つのことが必要です:

  1. フィーチャーフラグ:features.tunnel_enabled = true
  2. トンネルセクション:tunnel.enabled = true

両方の条件が真である必要があり、OPENPR_WEBHOOK_SAFE_MODEが設定されていてはなりません。

toml
[features]
tunnel_enabled = true
cli_enabled = true  # Usually needed for task execution

[tunnel]
enabled = true
url = "wss://control.example.com/ws/agent"
agent_id = "my-webhook-agent"
auth_token = "your-bearer-token"
reconnect_secs = 3
heartbeat_secs = 20

メッセージエンベロープフォーマット

すべてのトンネルメッセージは標準エンベロープを使用します:

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "heartbeat",
  "ts": 1711234567,
  "agent_id": "my-webhook-agent",
  "payload": { "alive": true },
  "sig": "sha256=abc123..."
}
フィールドタイプ説明
idString(UUID)一意のメッセージ識別子
typeStringメッセージタイプ(以下参照)
tsIntegerUnixタイムスタンプ(秒)
agent_idString送信エージェントのID
payloadObjectタイプ固有のペイロード
sigString(オプション)エンベロープのHMAC-SHA256署名

メッセージタイプ

アウトバウンド(エージェントからコントロールプレーンへ)

タイプタイミングペイロード
heartbeatN秒ごと{"alive": true}
task.ackタスク受信後すぐ{"run_id": "...", "issue_id": "...", "status": "accepted"}
task.resultタスク完了後{"run_id": "...", "issue_id": "...", "status": "success/failed", "summary": "..."}
errorプロトコルエラー時{"reason": "invalid_json/missing_signature/bad_signature", "msg_id": "..."}

インバウンド(コントロールプレーンからエージェントへ)

タイプ目的ペイロード
task.dispatchこのエージェントにタスクを割り当て{"run_id": "...", "issue_id": "...", "agent": "...", "body": {...}}

タスクディスパッチフロー

コントロールプレーン              openpr-webhook
    |                                 |
    |--- task.dispatch ------------->|
    |                                 |--- task.ack(即時)
    |<--- task.ack ------------------|
    |                                 |
    |                                 |--- CLIエージェント実行
    |                                 |    (非同期、タイムアウトまで)
    |                                 |
    |<--- task.result ---------------|--- task.result
    |                                 |

task.dispatchペイロードフィールド:

フィールドタイプ説明
run_idString一意のrun識別子(省略した場合は自動生成)
issue_idString作業対象のイシューID
agentString(オプション)ターゲットエージェントID(最初のcliエージェントにフォールバック)
bodyObjectディスパッチャーに渡す完全なWebhookペイロード

HMACエンベロープ署名

tunnel.hmac_secretが設定されている場合、すべてのアウトバウンドエンベロープが署名されます:

  1. エンベロープはsignullに設定してJSONにシリアライズされる
  2. HMAC-SHA256がシークレットを使用してJSONバイトで計算される
  3. 署名がsigフィールドにsha256={hex}として設定される

インバウンドメッセージについては、tunnel.require_inbound_sig = trueの場合、有効な署名のないメッセージはすべてerrorエンベロープで拒否されます。

toml
[tunnel]
hmac_secret = "shared-secret-with-control-plane"
require_inbound_sig = true

再接続の動作

トンネルクライアントは切断時に自動的に再接続します:

  • 初期リトライ遅延:reconnect_secs(デフォルト:3秒)
  • バックオフ:連続失敗ごとに2倍に増加
  • 最大バックオフ:runtime.tunnel_reconnect_backoff_max_secs(デフォルト:60秒)
  • 接続成功時にベース遅延にリセット

並行性制御

トンネルを通じたCLIタスク実行はruntime.cli_max_concurrencyで制限されます:

toml
[runtime]
cli_max_concurrency = 2  # Allow 2 concurrent CLI tasks (default: 1)

並行性制限を超えるタスクはセマフォの許可を待ちます。これにより、複数のタスクが連続してディスパッチされるときにマシンが過負荷になるのを防ぎます。

設定リファレンス

フィールドデフォルト説明
tunnel.enabledfalseトンネルを有効/無効にする
tunnel.url--WebSocket URL(wss://またはws://
tunnel.agent_idopenpr-webhookエージェント識別子
tunnel.auth_token--認証のBearerトークン
tunnel.reconnect_secs3ベース再接続間隔
tunnel.heartbeat_secs20ハートビート間隔(最小3秒)
tunnel.hmac_secret--HMAC-SHA256署名シークレット
tunnel.require_inbound_sigfalse署名なしのインバウンドメッセージを拒否

セキュリティ注意

  • プロダクションでは常にwss://を使用してください。ws://を使用するとサービスが警告をログに記録します。
  • auth_tokenはWebSocketアップグレード中にHTTPヘッダーとして送信されます。TLSが使用されていることを確認してください。
  • なりすましタスクディスパッチを防ぐためにhmac_secretと共にrequire_inbound_sigを有効にしてください。

Released under the Apache-2.0 License.