CloudWatch Logs に個人情報が出たら通知する方法 ── データ保護ポリシーと LogEventsWithFindings のアラーム

目次

概要

アプリケーションのログに、メールアドレスや患者番号のような個人情報・医療情報がうっかり出力されてしまうことがあります。ログはアプリケーションの開発者や運用担当者など多くの人が見るため、気づかないまま残しておくと、見せてはいけない人にまで情報が見えてしまいます。

Amazon CloudWatch Logs の データ保護ポリシー を使うと、ロググループに取り込まれるログから機密データを検出し、マスク(伏せ字)にできます。機密データが見つかると、CloudWatch に LogEventsWithFindings メトリクスが送られるので、これに CloudWatch アラームを付ければ、機密データがログに出たことを通知できます。

この記事では、データ保護ポリシーの仕組み、マネージドデータ識別子とカスタムデータ識別子の違い、マスクを外して見るための権限、Amazon Macie や Amazon GuardDuty との違いを整理します。実践では、ロググループにデータ保護ポリシーを設定し、メールアドレスと患者番号を含むログがマスクされることを確かめてから、LogEventsWithFindings にアラームを付けて、アラーム状態になるところまでを確認します。

取り込み時に機密データを検出・マスクし、LogEventsWithFindings のアラームで通知する
取り込み時に機密データを検出・マスクし、LogEventsWithFindings のアラームで通知する
クラウドおさる

猿山の当番日誌に、うっかりバナナ倉庫の合言葉を書いてしまう猿がいるのでござる。書かれた瞬間に墨で塗り、長老に知らせる仕組みを CloudWatch Logs で作るでござるよ。

この記事のメリット

  • CloudWatch Logs のデータ保護ポリシーで、ログの機密データがいつ・どう検出されマスクされるかを説明できるようになる
  • マネージドデータ識別子とカスタムデータ識別子を使い分けられるようになる
  • LogEventsWithFindings メトリクスにアラームを付けて、機密データの出力を通知できるようになる
  • Amazon Macie・Amazon GuardDuty・メトリクスフィルターとの違いを整理し、ログの機密データ対策に合う手段を選べるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

データ保護ポリシーとは

データ保護ポリシーは、CloudWatch Logs のロググループに取り込まれるログイベントから機密データを 監査(検出) し、マスク するための設定です。

項目内容
設定の範囲1 つのロググループ、またはアカウント全体(既存と今後作るロググループのすべて)
ロググループごとの数1 つ。1 つのポリシーで複数のデータ識別子を指定できる
対象のログクラス標準ログクラスと低頻度アクセスログクラスの両方
検出・マスクのタイミングロググループに取り込まれるとき。ポリシーを設定する前に取り込まれたログはマスクされない
マスクされる場所ログイベントの表示、CloudWatch Logs Insights、メトリクスフィルター、サブスクリプションフィルターなど、すべての出力先

アカウント全体のポリシーと、ロググループ単位のポリシーの両方があるときは、両方が適用されます。どちらかで指定したデータ識別子は、すべて検出・マスクされます。

クラウドおさる

墨で塗られるのは、ポリシーを掛けた後に書かれた日誌だけでござる。すでに書かれてしまった分は塗られぬので、気づいた時点で過去のログの扱いも別に考える必要があるのでござるぞ。

データ識別子

何を機密データとみなすかは、データ識別子 で指定します。

種類内容
マネージドデータ識別子AWS が用意したもの。認証情報(AWS シークレットアクセスキーなど)、財務情報(クレジットカード番号など)、個人を特定できる情報(PII。メールアドレス、運転免許証番号など)、保護対象保健情報(PHI。健康保険や医療の識別番号など)、デバイス識別子(IP アドレスなど)の 5 つのカテゴリがある
カスタムデータ識別子自分で名前と正規表現を指定する。社員番号や患者番号のような、組織固有の形式を検出できる。1 つのポリシーに 10 個まで、正規表現は 200 文字まで

マネージドデータ識別子の検出には、パターンマッチングと機械学習モデルが使われます。種類によっては、データの近くに特定のキーワード(例: 健康保険請求番号なら hicn など)があることも検出の条件になります。PHI の識別子は米国・EU・英国・カナダなど特定の国や地域の番号を対象にしているので、国内の医療機関で使う患者番号のような独自の形式は、カスタムデータ識別子で検出します。

関係のないデータ識別子をたくさん選ぶと、誤検出が増える可能性があります。ログに出る可能性があるデータに絞って選ぶことが推奨されています。

クラウドおさる

世の中に広く通じる合言葉はマネージドデータ識別子、猿山だけの札番号はカスタムデータ識別子、と分けて考えるとよいのでござるな。

マスクを外して見るには

マスクされた元のデータを見られるのは、logs:Unmask の権限を持つユーザーだけです。AWS 管理ポリシー CloudWatchLogsFullAccess には logs:Unmask が含まれています。権限を持つユーザーは、ログストリームの表示で「表示」→「マスク解除」を選ぶか、CloudWatch Logs Insights のクエリで unmask(@message) を使うと、元の値を確認できます。ログを見る人の多くには logs:Unmask を渡さず、調査が必要な担当者だけに渡す、という分け方ができます。

検出を通知する

機密データが検出されると、AWS/Logs 名前空間に LogEventsWithFindings メトリクス(機密データに一致したログイベントの数。統計は Sum)が送られます。このメトリクスは無料で、CloudWatch アラーム・グラフ・ダッシュボードで使えます。アラームの条件を「合計が 1 以上」にして、アクションで SNS トピックに通知すれば、ログに機密データが出たことをすぐに知れます。

検出の詳細(どのデータ識別子に、どのログイベントが一致したか)が欲しい場合は、ポリシーの監査結果の送信先として、CloudWatch Logs のロググループ、Amazon Data Firehose、Amazon S3 を指定できます。送信先を指定しなくても、マスクとメトリクスの送信は行われます。

データ保護ポリシーの監査とマスクで、何が起きるか
データ保護ポリシーの監査とマスクで、何が起きるか

ほかのサービスとの違い

サービス・機能CloudWatch Logs の機密データ対策に使えるか
CloudWatch Logs のデータ保護ポリシー使える。取り込み時に検出・マスクし、LogEventsWithFindings でアラームを付けられる
Amazon MacieAmazon S3 に保存されたデータの機密データを検出するサービス。CloudWatch Logs のロググループは対象外
Amazon GuardDutyAWS アカウントやワークロードへの脅威(不審な API 呼び出しや通信など)を検出するサービス。ログの中身の機密データは探さない
メトリクスフィルターログのパターンに一致した件数をメトリクスにできるが、パターンは自分で書く必要があり、マスクはしない
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

実践

ハンズオンガイド8 ステップ画面 5 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

医療系アプリのログを想定したロググループ /soa/clinic-app に、メールアドレス(マネージドデータ識別子)と患者番号(カスタムデータ識別子)を検出・マスクするデータ保護ポリシーを設定します。CloudShell からテスト用のログを送ってマスクされることを確かめ、LogEventsWithFindings メトリクスに付けたアラームがアラーム状態になることを確認します。

前提条件

  • リージョン: ap-northeast-1(東京)
  • 以下のリソースが作成済みであること

まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。

リソース種別リソース名内容作り方の参考
CloudWatch Logs ロググループ/soa/clinic-app医療系アプリのログの出力先(標準ログクラス)─
SNS トピックsoa-sensitive-data-alertsアラームの通知先(標準トピック)Amazon SNS でトピックを作成しメッセージを配信する

※ この記事では、通知がトピックに届くところまでを扱います。メールなどで受け取るには、トピックにサブスクリプションを追加します。

作成するリソース一覧

リソース種別リソース名用途
データ保護ポリシー(/soa/clinic-app に設定)メールアドレスと患者番号の検出・マスク
カスタムデータ識別子PatientId患者番号(PT- に続く 8 桁の数字)を検出する
ログストリームtest-01テスト用のログの送り先
CloudWatch アラームsoa-sensitive-data-alarmLogEventsWithFindings が 1 以上になったら通知

手順 1: データ保護ポリシーを作る

AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。上部の検索バーに CloudWatch と入力し、「CloudWatch」を選択します。

左側ナビゲーションの「ログ」→「ロググループ」を選択し、/soa/clinic-app を選択します。「アクション」→「データ保護ポリシーを作成」を選択します。「データ保護ロググループポリシー」の作成画面が開くので、以下を設定します。

  • マネージドデータ識別子: 「データ識別子を選択」を開き、EmailAddress で絞り込んで「EmailAddress」を選択
  • 「カスタムデータ識別子を追加」をクリックし、名前: PatientId、正規表現: PT-[0-9]{8} を入力
  • 監査結果の送信先: どれも選択しない
データ保護ポリシーの作成画面(マネージドデータ識別子 EmailAddress とカスタムデータ識別子 PatientId)
データ保護ポリシーの作成画面(マネージドデータ識別子 EmailAddress とカスタムデータ識別子 PatientId)

「データ保護をアクティブ化」をクリックします。ロググループの詳細の「データ保護」タブで、ポリシーが有効になり、2 つのデータ識別子が設定されていることを確認します。

手順 2: 機密データを含むログを送る

コンソール下部の「CloudShell」をクリックして CloudShell を開き、次のコマンドを実行します。ログストリーム test-01 を作り、患者番号とメールアドレスを含むログと、含まないログを 1 件ずつ送ります。

LG=/soa/clinic-app
aws logs create-log-stream --log-group-name "$LG" --log-stream-name test-01
now=$(date +%s%3N)
aws logs put-log-events --log-group-name "$LG" --log-stream-name test-01 --log-events \
  "[{\"timestamp\":$now,\"message\":\"reservation created patient=PT-20261021 contact=banana.taro@example.com\"},{\"timestamp\":$now,\"message\":\"reservation list loaded count=3\"}]"

コマンドが rejectedLogEventsInfo のエラーを返さずに終わることを確認します。

手順 3: ログがマスクされたことを確かめる

CloudWatch のコンソールに戻り、/soa/clinic-app の「ログストリーム」タブで test-01 を選択します。1 件目のログでは、患者番号とメールアドレスの部分が * で伏せられています。2 件目のログはそのまま表示されています。

ログストリーム test-01 で、患者番号とメールアドレスがマスクされたログイベント
ログストリーム test-01 で、患者番号とメールアドレスがマスクされたログイベント

画面右上の「表示」→「マスク解除」を選ぶと、元の値が表示されます。いまログインしているユーザーが logs:Unmask の権限を持っているためです。

クラウドおさる

同じログでも、logs:Unmask を持たぬ者には墨塗りしか見えないのでござる。日誌を読む猿と、墨を剥がせる猿を分けておけるのでござるな。

手順 4: LogEventsWithFindings メトリクスを確かめる

左側ナビゲーションの「メトリクス」→「クラシックメトリクス」を選択します。「参照」タブで「Logs」→「DataProtectionOperation, LogGroupName」を選択し、LogGroupName が /soa/clinic-app の LogEventsWithFindings の行にチェックを入れます。メトリクスはロググループごと(ディメンション LogGroupName)に出ます。ログを送ってから表示されるまで 2 分ほどかかります。

「グラフ化したメトリクス」タブで、統計を「合計」、期間を「1 分」に変更します。既定の「平均」「5 分」のままだと「データがありません」と表示されることがあります。手順 2 で送った時刻に、値が 1 のデータポイントが表示されます。送ったログは 2 件ですが、機密データを含むログイベントは 1 件なので、値は 1 です。

LogEventsWithFindings のグラフ(合計・1 分で値 1 のデータポイント)
LogEventsWithFindings のグラフ(合計・1 分で値 1 のデータポイント)

手順 5: アラームを作る

「グラフ化したメトリクス」タブで、LogEventsWithFindings の行の「アクション」列にあるベルのアイコン(「アラームを作成」)をクリックします。「メトリクスと条件の指定」が、名前空間・ディメンションの入った状態で開きます。以下を設定します。

  • 統計: 合計
  • 期間: 1 分
  • 条件: しきい値の種類「静的」、「LogEventsWithFindings が」「以上」(既定では選ばれていません)、「…よりも」に 1
アラームの条件(合計・1 分・1 以上)
アラームの条件(合計・1 分・1 以上)

「次へ」をクリックし、「通知」で以下を設定します。

  • アラーム状態トリガー: 「アラーム状態」
  • SNS トピックの選択: 「既存の SNS トピックを選択」の入力欄に soa-sensitive-data-alerts と入力し、候補から選択

「次へ」をクリックし、アラーム名に soa-sensitive-data-alarm と入力します。「次へ」をクリックし、確認画面で「アラームの作成」をクリックします。

手順 6: アラーム状態になることを確かめる

CloudShell に戻り、もう一度機密データを含むログを送ります。

now=$(date +%s%3N)
aws logs put-log-events --log-group-name "$LG" --log-stream-name test-01 --log-events \
  "[{\"timestamp\":$now,\"message\":\"reservation updated patient=PT-20261022 contact=banana.jiro@example.com\"}]"

CloudWatch のコンソールで左側ナビゲーションの「アラーム」→「すべてのアラーム」を選択します。数分待つと、soa-sensitive-data-alarm の状態が「アラーム状態」に変わります。アラームを選択して「履歴」タブを開くと、状態の変化と、SNS トピックへのアクションが実行されたことを確認できます。この実践ではトピックにサブスクリプションを付けていないため、アラーム一覧の「アクション」列に警告が表示されますが、動作には影響しません。実際の運用では、トピックに通知先(メールやチャットなど)をサブスクライブしておきます。

soa-sensitive-data-alarm がアラーム状態になった画面
soa-sensitive-data-alarm がアラーム状態になった画面

まとめ

やりたいこと使う設定・サービス
ログの機密データを取り込み時に検出・マスクするCloudWatch Logs のデータ保護ポリシー
一般的な機密データ(メールアドレス、クレジットカード番号など)を検出するマネージドデータ識別子
組織固有の形式(患者番号、社員番号など)を検出するカスタムデータ識別子(正規表現)
機密データがログに出たら通知するLogEventsWithFindings メトリクスのアラーム → SNS
マスクされた元の値を見るlogs:Unmask の権限(「マスク解除」や unmask(@message))
S3 に保存されたデータの機密データを見つけるAmazon Macie
  • データ保護ポリシーはロググループ単位かアカウント全体に設定し、取り込み時に検出・マスクする。設定前のログはマスクされない
  • マスクは Logs Insights やメトリクスフィルター、サブスクリプションフィルターなど、すべての出力先に効く
  • LogEventsWithFindings は AWS/Logs 名前空間の無料のメトリクスで、アラームの元にできる
  • Macie は S3 のデータが対象、GuardDuty は脅威の検出で、どちらも CloudWatch Logs のログの機密データ検出には使わない
クラウドおさる

「CloudWatch Logs のログに個人情報や医療情報が出たら知らせたい」と聞いたら、データ保護ポリシーと LogEventsWithFindings のアラームでござる。S3 担当の Macie や、侵入者担当の GuardDuty と取り違えぬよう、見張る場所で覚えるでござるよ。

参照先

キャリア相談
クラウドおさる

独学の先に、AWS の仕事がある ── ジュニアおさるのキャリア相談

CLF には受かったけれど、次に何をすればいいのか分からない。独学で AWS を学ぶジュニアおさるの相談に、株式会社ジェニュイン代表の土肥が答えています。

  • ✓資格はゴールか、CLF の次に何から手を付けるか
  • ✓EC2 の次に作ってみる構成と、IaC・コスト管理
  • ✓実務経験ゼロでも、面接で話せる「これまで」の作り方
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次