Keycloakの認証・管理操作を漏れなく監査ログとして残し、外部のSIEMやWebhookへ確実に届ける。そのための正攻法がEvent Listener SPIです。トランザクション境界と失敗時の挙動を正しく設計しないと、監査ログに穴が空きます。実装の勘所を整理します。

01Keycloakの「イベント」は2系統ある

Keycloakは、認証基盤で起きた出来事を「イベント」として記録・配信する仕組みを標準で備えています。監査ログやSIEM連携を設計するうえで、まず押さえるべきは、イベントが2系統に分かれている点です。

両方とも、既定ではデータベースに保存され、Admin Consoleから閲覧できます。ログインイベントには保持期間(expiration)を設定でき、期限切れは自動削除されます。管理イベントには、変更内容そのもの(Representation)を含めるかどうかのフラグがあります。詳細はServer Administration Guideの監査(auditing)の章を確認してください。

現場のコツ:「イベントをDBに保存する」ことと「イベントを外部へ送る」ことは別レイヤーです。DB保存は運用画面での確認用、外部送信(SIEM/Webhook)は長期保全とアラート用。監査要件では、Keycloakの手が届かない外部ストレージに証跡を逃がしておくことが本質です。DB保存だけに頼ると、Keycloak自体の侵害時に証跡ごと消される恐れがあります。

02Event Listener SPIとは何か

DB保存とは別に、イベントが発生した瞬間に任意の処理を差し込むための拡張点がEvent Listener SPIです。標準ではjboss-loggingリスナー(サーバーログへ出力)が組み込まれており、これを有効化するだけでもログ基盤への一次連携はできます。ただしSIEM向けの構造化送信や、外部Webhook連携をやりたい場合は、独自リスナーを実装するのが正攻法です。

実装は次の2つのインターフェースと、1つのサービス登録ファイルで構成されます。

インターフェースの正確なシグネチャはEventListenerProviderのJavadocで確認できます。実装後は、Admin Consoleの Realm settings → Events → Event listeners で、getId() が返すIDを登録すると有効になります。

現場のコツ:現行はQuarkusベースのディストリビューションが標準です。旧WildFly版で使われた standalone/deployments/ へのホットデプロイは非推奨で、Quarkus版ではJARを providers/ に配置し kc.sh build を実行してから起動する手順が基本になります。ビルド時/実行時の設定分離はバージョンで挙動が変わるため、採用バージョンの公式手順で必ず裏取りしてください。

03トランザクション境界を外さない

ここがEvent Listener SPI最大の落とし穴です。onEvent は、そのイベントを生んだ実行中のトランザクションの内側で呼ばれます。つまりリスナーの中で重い外部I/O(HTTP送信やSIEMへの書き込み)を同期実行すると、そのレイテンシがユーザーのログイン処理そのものを遅延させます。さらに、外部送信が失敗して例外を投げれば、元のトランザクションごとロールバックされ、ログインが失敗しかねません。

Javadocはこの点を明確に述べています。イベント処理をJPAでDBに書くならトランザクション整合が取れて都合が良い一方、ログファイルへの書き込みや外部送信のようにロールバックできない副作用は、トランザクションのコミット完了後に回すべきだとしています。そのための仕組みが KeycloakTransactionManager.enlistAfterCompletion(...) です。イベントを一旦メモリ上に積み、元トランザクションが成功コミットした後にだけ実際の送信を行います。

Keycloakトランザクション 認証処理・DB更新 onEvent 呼び出し メモリに積むだけ commit コミット後 enlistAfterCompletion 送信タスクを登録 SIEM / Webhook 送信 スレッドプールで非同期 同期送信はレイテンシと巻き添えロールバックの原因。送信はコミット後・別スレッドへ逃がす 監査ログの完全性は「コミット後送信」で担保する
図:ログイン処理のトランザクションと、コミット後の非同期送信の分離

04非同期化と失敗時の扱い

コミット後に送信するとしても、送信処理自体をリクエストスレッドで同期的に待つと、やはりレスポンスが遅くなります。実務では、コミット後フックの中で送信タスクをスレッドプールへ投入し、即座にリターンする構成を採ります。実際、代表的なOSS実装であるp2-inc/keycloak-eventsも、送信タスクをスレッドプールでスケジュールし、Keycloakトランザクションのコミット後に実行する設計を採っています。

非同期化すると、次は「送信に失敗したイベントをどう扱うか」が論点になります。監査ログは欠損が許されないため、失敗時の戦略を必ず決めます。

現場のコツ:「監査ログを一件も落とさない」を厳密に満たしたい場合、Keycloakプロセス内の非同期送信だけに頼るのは危険です。プロセスが異常終了すればメモリ上の未送信イベントは消えます。堅牢さを優先するなら、リスナーはローカルの追記ログ(またはKafka等の耐久キュー)へ確実に書くまでを責務とし、そこからSIEMへの転送はFluent Bit等の外部エージェントに委ねる二段構えが安全です。

05SIEM / Webhook連携の設計パターン

送信先ごとに、現実的なパターンを整理します。

SIEMに渡す際は、イベントのフィールド設計が効いてきます。type(イベント種別)、realmIdclientIduserIdipAddresserror、そして相関のためのsessionIdを必ずマッピングします。管理イベントでは、operationType(CREATE/UPDATE/DELETE)とresourcePath、変更主体(authDetails)が監査の中核です。なおonEvent(AdminEvent, includeRepresentation) の第2引数を有効にすると変更後のRepresentationも取得できますが、パスワードや機密属性が乗る場合があるためマスキング方針を決めてから有効化します。

実案件でのKeycloak構築事例は導入事例もあわせてご覧ください。マルチアカウント環境での証跡集約はマルチアカウント統制とも接続する論点です。

06監査要件へのマッピング

監査要件(内部統制、PCI DSS、各種セキュリティ基準など)に照らすと、Event Listener SPIで担保すべき点は概ね次に集約されます。

なお、監査ログ(イベントの証跡)と、監視メトリクス(件数の傾向)は目的が異なります。ログインや失敗の件数の傾向監視には、Keycloak標準のイベントメトリクスが使えます。--metrics-enabled=true--event-metrics-user-enabled=true で有効化し、PrometheusエンドポイントへLOGIN/LOGIN_ERROR等のカウンタが出ます。既定はrealm単位で、event-metrics-user-tags でclientやIdP次元を追加できます(カーディナリティに注意)。詳細はMonitoring user activities with event metricsを参照してください。この機能はKeycloak 26.1で正式に取り込まれています。

現場のコツ:「アラートを出したい(傾向)」ならイベントメトリクス、「一件ずつ証跡を残したい(監査)」ならEvent Listener SPI。両者は排他ではなく併用します。メトリクスで異常の兆候を掴み、SIEMに送った個別イベントで原因を追う、という役割分担が現場では回しやすい構成です。

07まわりの拡張点との棲み分け

Event Listener SPIは「起きたことを記録・通知する」拡張点です。「起きる前に介入する」用途では別のSPIを使い分けます。認証フローそのものにステップを差し込むならCustom Authenticator SPI、認証フロー全体の設計は認証フロー(Authentication Flow)の記事が該当します。イベント連携と合わせて、認証の入口(検知・記録)と処理(制御)を両輪で設計すると、監査と防御が一枚岩になります。

また、監視・可観測性の全体像はKeycloakの可観測性もあわせてご覧ください。イベントメトリクス、ログ、トレースの三点で認証基盤の状態を捉える設計につながります。

まとめ

Event Listener SPIは、Keycloakの監査ログを「Keycloakの外」に確実に逃がすための正攻法です。実装はEventListenerProviderFactoryEventListenerProviderの2つとサービス登録だけとシンプルですが、勘所は実装量ではなく境界設計にあります。

ここを外すと、ログインが遅くなる・巻き添えでコケる・監査ログに穴が空く、のいずれかを踏みます。逆に押さえておけば、堅牢で説明可能な監査基盤になります。

参考(一次情報)

Keycloakの監査ログ設計やSIEM連携でお困りの際は、実構築の経験を踏まえてお問い合わせください。

相談する
← ブログ一覧へ戻る