{"id":50867416,"url":"https://github.com/nlink-jp/ir-hub","last_synced_at":"2026-06-15T02:36:08.256Z","repository":{"id":364123071,"uuid":"1265038547","full_name":"nlink-jp/ir-hub","owner":"nlink-jp","description":"Incident-response lifecycle hub — Slack ChatOps bot for case channels, postmortems, and knowledge reuse","archived":false,"fork":false,"pushed_at":"2026-06-11T18:02:08.000Z","size":313,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T19:19:52.465Z","etag":null,"topics":["chatops","cybersecurity","golang","incident-response","llm","slack","socket-mode"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nlink-jp.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-10T12:07:43.000Z","updated_at":"2026-06-11T18:03:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nlink-jp/ir-hub","commit_stats":null,"previous_names":["nlink-jp/ir-hub"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/nlink-jp/ir-hub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fir-hub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fir-hub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fir-hub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fir-hub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nlink-jp","download_url":"https://codeload.github.com/nlink-jp/ir-hub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fir-hub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34345577,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chatops","cybersecurity","golang","incident-response","llm","slack","socket-mode"],"created_at":"2026-06-15T02:36:07.615Z","updated_at":"2026-06-15T02:36:08.234Z","avatar_url":"https://github.com/nlink-jp.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ir-hub\n\nインシデントレスポンス・ライフサイクルハブ — IR ライフサイクル全体を LLM で\n支援するワンパッケージの Slack ChatOps Bot。案件チャネル開設、対応中の支援、\nポストモーテム分析、知見の蓄積と再利用までを一気通貫でカバーします。\n\n[English README is here](README.md)\n\n\u003e **Status: 機能完成(Phase 1–3)。** 案件ライフサイクル管理、LLM\n\u003e ポストモーテム(クローズ時自動+再実行可)、LLM 状況サマリ、知見\n\u003e ドキュメント生成に加え、知見の再利用 — `@ir-hub` Q\u0026A、初動\n\u003e ブリーフィング、プラガブルなストレージ出力(local / GCS / S3)。\n\u003e 承認済み設計は [RFP](docs/ja/ir-hub-rfp.ja.md) を参照。\n\n## コンセプト\n\n```\n/ir-hub new ──→ 案件チャネル ──→ 対応活動 ──→ /ir-hub close\n     │             (状況サマリ / Q\u0026A 支援)         │\n     │                                            ▼\n     └── 初動ブリーフィング ◀── 知見ストア ◀── ポストモーテム\n         (過去案件から)        (JSON + Markdown,   (自動+再実行可)\n                                local / GCS / S3)\n```\n\n- **Slack 上の案件ライフサイクル** — `/ir-hub new` で案件ごとの専用チャネルを\n  開設、`/ir-hub close` でクローズしポストモーテムを自動実行\n- **LLM ポストモーテム(ai-ir2 理論を再構築)** — 5 段階分析(サマリ /\n  参加者アクティビティ / ロール推定 / タクティック抽出 / プロセス評価)を\n  Vertex AI Gemini で実行。ノンスタグによるプロンプトインジェクション防御と、\n  LLM 前後両方での IoC defang。分析は英語カノニカル、チャネル投稿は\n  設定言語へ翻訳\n- **知見ドキュメント** — 抽出タクティックごとに JSON + Markdown ペアを生成し、\n  ポストモーテム確定時に DB へインデックス(タグ / カテゴリ / 要約)登録。\n  再実行で当該案件の知見は置換\n- **知見の再利用** — `@ir-hub \u003c質問\u003e` で蓄積知見から回答(タクティック ID を\n  引用)、`/ir-hub new` 時に関連する過去タクティックをブリーフィング投稿、\n  知見を JSON + Markdown で local / GCS / S3 にエクスポート(`/ir-hub export`\n  およびポストモーテム後に自動)。IR チーム外も参照可能\n- **デュアルモードのスラッシュコマンド** — 引数ありで直接実行、引数なしの\n  `/ir-hub` はモーダルから操作を選択\n- **ACL 内蔵** — ユーザー ID 単位+Slack User Group 単位の Whitelist +\n  Blacklist。フェイルセーフ(Whitelist 未設定 = 全拒否)、拒否は silent で\n  監査ログに記録。数万メンバー規模のワークスペースを想定した設計\n- **継続取り込み** — オープン中の案件チャネルのメッセージを内蔵 SQLite に\n  リアルタイム保存。再接続後は履歴から自動 backfill\n- **Go 単一バイナリ** — Socket Mode 常駐 Bot。インバウンド公開不要、\n  ランタイム依存なし\n\n## コマンド\n\n| コマンド | 動作 |\n|---|---|\n| `/ir-hub` | モーダルで操作を選択(パラメータを覚える必要なし) |\n| `/ir-hub new \u003ctitle\u003e [--severity low\\|medium\\|high\\|critical] [--private\\|--public]` | 案件チャネル作成、起票者を招待、キックオフ投稿 |\n| `/ir-hub status` | 案件メタデータに続けて LLM 状況サマリ(現状 / 未解決事項 / 次アクション)を投稿 |\n| `/ir-hub close` | 案件をクローズし、ポストモーテムを自動実行(案件チャネル内で実行) |\n| `/ir-hub reopen` | クローズ済み案件を再オープン(メッセージ取り込みを再開) |\n| `/ir-hub pm` | ポストモーテムを手動(再)実行 — 当該案件の知見ドキュメントを置換 |\n| `/ir-hub export` | 全知見ドキュメントを設定済みストレージにエクスポート |\n| `@ir-hub \u003c質問\u003e` | 知見 Q\u0026A — 蓄積知見から回答(タクティック ID を引用) |\n\nポストモーテムはコンパクトな要約(重要度、プロセススコア、良かった点/\n改善点ダイジェスト、タクティック数)を投稿し、全文 Markdown レポートを\nスニペットとして添付します。\n\n## 前提条件\n\n- Go 1.26+(ビルド)\n- Socket Mode を有効化した Slack アプリ(下記)\n- Vertex AI API を有効化した GCP プロジェクトと Application Default\n  Credentials(`gcloud auth application-default login`)—\n  ポストモーテムと状況サマリは Gemini で実行されます\n- 知見エクスポート用: ローカルディレクトリ(既定)、または GCS バケット\n  (ADC)/ S3 バケット(AWS 既定認証チェーン)。クラウドクライアントが\n  初期化できない場合はエクスポートを無効化して Bot は稼働継続します\n\n## Slack アプリの設定\n\n\u003e 完全な手引き — スコープの正当性説明、管理者承認、トークンの取り扱い、\n\u003e 動作検証チェックリスト、トラブルシューティング — は\n\u003e [Slack アプリ構成ハンドブック](docs/ja/slack-app-setup.ja.md) を参照。\n\n以下のマニフェストからアプリを作成します(App settings → App Manifest):\n\n```yaml\ndisplay_information:\n  name: ir-hub\n  description: \u003e-\n    インシデント対応のライフサイクルハブ。案件チャネルの開設、対応支援、\n    ポストモーテム、知見の再利用を一気通貫で支援します。\n  long_description: |-\n    ir-hub はセキュリティインシデント対応チームのためのライフサイクル\n    ハブです。\n\n    ・/ir-hub new — 案件専用チャネルを開設し、起票者を招待して\n      キックオフを投稿\n    ・/ir-hub status — 案件の現在状況を要約\n    ・/ir-hub close — 対応を終了し、ポストモーテムを自動実行\n    ・対応から得られた知見を蓄積し、以降の案件で再利用\n\n    利用はアプリ内の許可リストにより IR チームに限定され、拒否は監査\n    ログに記録されます。メッセージの取り込みは ir-hub 自身が作成した\n    案件チャネルのみが対象です。\n\n    運用: \u003cyour IR team\u003e / 問い合わせ: #\u003cyour-contact-channel\u003e\nfeatures:\n  bot_user:\n    display_name: ir-hub\n    always_online: true\n  slash_commands:\n    - command: /ir-hub\n      description: Incident response lifecycle hub\n      usage_hint: \"new \u003ctitle\u003e | close | status\"\n      should_escape: false\noauth_config:\n  scopes:\n    bot:\n      - commands\n      - chat:write\n      - app_mentions:read\n      - users:read\n      - usergroups:read\n      - channels:manage\n      - channels:read\n      - channels:history\n      - channels:join\n      - groups:write\n      - groups:read\n      - groups:history\n      - files:write\n      - reactions:write\nsettings:\n  event_subscriptions:\n    bot_events:\n      - app_mention\n      - message.channels\n      - message.groups\n  interactivity:\n    is_enabled: true\n  socket_mode_enabled: true\n```\n\n続いて以下を発行します:\n\n1. **App-level トークン**(Basic Information → App-Level Tokens)に\n   `connections:write` スコープ → `IRHUB_SLACK_APP_TOKEN`\n2. **Bot トークン**(Install App)→ `IRHUB_SLACK_BOT_TOKEN`\n\n## インストール\n\n```sh\ngit clone https://github.com/nlink-jp/ir-hub.git\ncd ir-hub\nmake build          # → dist/ir-hub\n```\n\n## 設定\n\n[`config.example.toml`](config.example.toml) を\n`~/.config/ir-hub/config.toml` にコピーして編集します(または `--config`)。\n全フィールドは `IRHUB_*` 環境変数で上書き可能です\n(例: `IRHUB_ACL_ALLOW_GROUPS=ir-team,secops`)。設定ファイル内の未知の\nキーはエラーになるため、typo は即座に検出されます。\n\n`language = \"ja\"`(または `IRHUB_LANGUAGE=ja`)を設定すると、ユーザーに\n見えるすべてのメッセージ — モーダル、キックオフ/ステータス/クローズ投稿、\nエラー — が日本語になります。ログは英語のままです。\n\nSlack トークンは設定ファイルの `[slack]` セクションまたは環境変数で\n指定します(環境変数が優先):\n\n| 環境変数 | 説明 |\n|---|---|\n| `IRHUB_SLACK_APP_TOKEN` | App-level トークン(`xapp-…`、`connections:write`) |\n| `IRHUB_SLACK_BOT_TOKEN` | Bot トークン(`xoxb-…`) |\n\nトークンをファイルに書く場合は `chmod 600` で保護してください。\ngroup/other に読めるパーミッションの場合、ir-hub は起動時に警告を\n表示します。\n\n**ACL はデフォルト全拒否**です。`allow_users` / `allow_groups` が未設定の\n場合、すべてのコマンドとメンションは拒否され(監査ログに記録)、起動前に\n許可リストの設定が必要です:\n\n```toml\n[acl]\nallow_groups = [\"ir-team\"]      # User Group のハンドルまたは ID (\"S…\")\ndeny_users   = []               # deny が allow より優先\nnotify_denied = false           # true: 拒否をエフェメラルで通知\n```\n\n未知のグループハンドルは起動エラーになります(typo ガード)。\n\n## 起動\n\n```sh\nexport IRHUB_SLACK_APP_TOKEN=xapp-...   # pragma: allowlist secret\nexport IRHUB_SLACK_BOT_TOKEN=xoxb-...   # pragma: allowlist secret\nir-hub serve\n```\n\nBot は自動再接続し、再接続後は `conversations.history` から取りこぼしを\nbackfill します。\n\n\u003e **単一インスタンスを永続ストレージ上で動かす。** ir-hub は Socket\n\u003e Mode(単一 WebSocket — 2 つ起動すると全イベントが二重化)と、実\n\u003e ローカル FS の永続ディスクに置くべき内蔵 SQLite を使います。小さな\n\u003e 常時起動 VM が推奨ホストで、エフェメラル FS のコンテナ(Cloud Run)は\n\u003e DB を消去します。[デプロイガイド](docs/ja/deployment.ja.md)を参照。\n\n## 知見エクスポート\n\n`[storage]` でバックエンドを設定します。知見ドキュメントは\n`\u003cタクティック ID\u003e-\u003cslug\u003e.json` / `.md` のペア(local は `local_path`\n直下、S3 は `s3_prefix` 配下)として、手動(`/ir-hub export`)と\nポストモーテム後の自動の両方で書き出されます。\n\n```toml\n[storage]\nbackend    = \"local\"          # local | gcs | s3\nlocal_path = \"./knowledge\"\n# gcs_bucket = \"my-ir-knowledge\"        # backend = \"gcs\"(ADC 使用)\n# s3_bucket  = \"my-ir-knowledge\"        # backend = \"s3\"(AWS 既定チェーン)\n# s3_prefix  = \"ir-hub/\"\n```\n\nGCS は Application Default Credentials、S3 は AWS 既定認証チェーンを\n使用します。再エクスポートは決定的パスで上書きします。\n\n## 既知の制限\n\n- **メッセージの編集・削除は取り込まれません**(`message_changed` /\n  `message_deleted` はスキップ)。生イベント JSON を保存しているため、\n  後続フェーズで拡張可能です。\n- **案件の連番に欠番が生じることがあります**: チャネル作成に失敗した番号は\n  監査のため意図的に残します。\n- **private 案件チャネル**は後から public に変換できません。また取り込みの\n  継続には ir-hub がメンバーのままである必要があります。\n- **非常に長い案件は分析時に切り詰められます**: `analysis.max_input_tokens`\n  を超える場合、予算内の新しいメッセージを分析対象とし、レポートに\n  その旨を明記します。\n- **知見検索はタグ/キーワード(LIKE)絞り込み**でベクトル検索ではありません。\n  数百件規模に適しており、それ以上の規模では FTS や embedding が望ましく\n  なります。\n- **再エクスポートしたオブジェクトが孤立し得ます**: ポストモーテム再実行で\n  タクティック ID が新しくなるため、前回エクスポート分が手動削除まで\n  ストレージに残る場合があります。\n\n## ビルド\n\n```sh\nmake build          # 現在のプラットフォーム → dist/ir-hub\nmake build-all      # 5 プラットフォーム(CGO 不使用)\nmake test           # または go test ./...\nmake package        # リリース zip; darwin は署名+notarize\n```\n\n\u003e macOS リリースは **Developer ID 署名+Apple notarize 済み**です。\n\u003e Windows / Linux バイナリは未署名です。\n\n## ドキュメント\n\n- [デプロイガイド](docs/ja/deployment.ja.md) /\n  [English](docs/en/deployment.md)\n- [Slack アプリ構成ハンドブック](docs/ja/slack-app-setup.ja.md) /\n  [English](docs/en/slack-app-setup.md)\n- [RFP(承認済み設計)](docs/ja/ir-hub-rfp.ja.md) /\n  [English](docs/en/ir-hub-rfp.md)\n\n## ライセンス\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fir-hub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnlink-jp%2Fir-hub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fir-hub/lists"}