1. はじめに
概要
マルチエージェント システムの構築では、分散型コース作成システムを構築しました。「雰囲気チェック」からデータドリブンなエージェント評価へでは、そのパフォーマンスを評価する方法を学習しました。
このラボでは、これらのセキュリティのギャップに対処してシステムを強化します。エージェント エンドポイントを公開すると、プロンプト インジェクションやサービス拒否などのエクスプロイトの対象になります。ユーザーとやり取りするエージェントは機密性の高い PII を処理するリスクがあり、ウェブをクロールするエージェントは有害なコンテンツを取り込んだり、間接的なプロンプト インジェクションの被害に遭ったりするリスクがあります。これらの脅威に対抗するために、Model Armor や Sensitive Data Protection などの Google Cloud セキュリティ ツールを使用して多層防御戦略を実装し、最小権限の IAM や認証済みネットワーク通信などのセキュリティのベスト プラクティスを適用します。
演習内容
- セキュリティ ポリシーを定義する: Sensitive Data Protection(SDP)テンプレートを作成して、個人情報(PII)を検出して秘匿化します。
- アプリケーションの安全性を統合する: エージェントに到達する前に Model Armor を使用してユーザー プロンプトをインターセプトしてサニタイズするようにバックエンドを変更します。
- 保護を確認する: 保護されたアプリケーションをデプロイし、レッドチーム シナリオを実行して、プロンプト インジェクションとセンシティブ データ漏洩がブロックされることを検証します。
- Policy as Code を実装する (省略可): Terraform を使用して Model Armor テンプレートと SDP テンプレートを管理し、環境全体で一貫したセキュリティ フィルタとガードレールを確保します。
学習内容
- Google Cloud Sensitive Data Protection(SDP)を構成して、センシティブ データを特定してマスクする方法。
- Terraform を使用して Model Armor テンプレートを作成してデプロイする方法。
- アプリケーション レイヤで GenAI エージェントを保護するための「多層防御」パターン。
- レッドチームの手法を使用してセキュリティ制御を監査して検証する方法。
2. セットアップ
構成
- ログインしていることを確認します。次のコマンドを実行して、現在の gcloud アカウントを取得します。
ログインしていない場合は、次のコマンドを実行します。gcloud config get-value accountgcloud auth login --update-adc - gcloud CLI のアクティブなプロジェクトを設定します。次のコマンドを実行して、現在の gcloud プロジェクトを取得します。
設定されていない場合は、次のコマンドを実行します。gcloud config get-value projectgcloud config set project YOUR_PROJECT_IDYOUR_PROJECT_IDはプロジェクトの ID に置き換えます。 - Cloud Run、Model Armor、Data Loss Prevention、Artifact Registry、Cloud Build、IAM Credentials の API を有効にします。
gcloud services enable --project $(gcloud config get-value project) \ aiplatform.googleapis.com \ modelarmor.googleapis.com \ dlp.googleapis.com \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ iamcredentials.googleapis.com - Cloud Run サービスがデプロイされるデフォルト リージョンを設定します。
Model Armor にアクセスして一貫した例を使用するには、gcloud config set run/region us-central1us-central1を使用してください。Model Armor を利用できるリージョンについては、こちらをご覧ください。
コードと依存関係
- スターター コードをクローンし、プロジェクトのルートにディレクトリを変更します。
Cloud Shell ワークスペースを起動するには、次のコマンドを実行します。git clone https://github.com/h3xar0n/prai-roadshow-lab-3-starter cd prai-roadshow-lab-3-starter [ターミナル] > [新しいターミナル] を使用して、新しいターミナルを開きます。cloudshell workspace . - ターミナルに次のコマンドを入力して、
.envファイルを作成します。 Cloud Shell エディタで、[表示] > [隠しファイルを切り替える] を使用して、echo "GOOGLE_GENAI_USE_VERTEXAI=true" > .env echo "GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project -q)" >> .env echo "GOOGLE_CLOUD_REGION=$(gcloud config get-value run/region -q)" >> .env echo "GOOGLE_CLOUD_LOCATION=global" >> .env.envなどの隠しファイルを表示します。 - ターミナルに次のコマンドを入力して、依存関係をインストールします。
uv sync
3. Sensitive Data Protection テンプレートを作成する
Model Armor の「Advanced」Sensitive Data Protection 機能は、Cloud DLP(Sensitive Data Protection)と統合して、コンテンツを検査して匿名化します。秘匿化に使用するには、まず、変換するセンシティブ データの種類と変換方法を指定する検査テンプレートと匿名化テンプレートを作成する必要があります。
検査テンプレートを作成する
Sensitive Data Protection は、infoType 検出機能を使用してさまざまな種類のセンシティブ データを検出します。150 を超える組み込みの検出器があり、パターン マッチング(正規表現)、辞書、コンテキスト ベースのシグナルなど、さまざまな検出方法を使用します。クレジット カード番号や政府機関発行の ID などの特定のタイプでは、チェックサムを検証して誤検出を減らすことで、単純なパターン マッチングを超えています。これらの検出器は、名前や住所などの個人情報(PII)だけでなく、API キーや認証トークンなどの認証情報も対象としています。これは、コードを操作または読み取るエージェントによる漏洩を防ぐ場合に特に便利です。
- Google Cloud コンソールで、[セキュリティ] > [Sensitive Data Protection] に移動します。
- ナビゲーション メニューで、[構成] > [テンプレート] を選択します。
- [テンプレートを作成] をクリックします。
- テンプレートを構成します。
- テンプレート タイプ:
Inspect - テンプレート ID:
sensitive-data-inspector - ロケーション タイプ:
Region - リージョン:
us-central1(Model Armor を使用するには必須です)。
- テンプレート タイプ:
- [続行] をクリックします。
- In [検出の設定] で、[infoType を管理] をクリックします。
- フィルタを使用して、次のinfoTypes を検索し、それぞれの横にあるチェックボックスをオンにします。
CREDIT_CARD_NUMBERGOVERNMENT_IDPERSON_NAMEEMAIL_ADDRESSSTREET_ADDRESSSECURITY_DATA
- 必要に応じて他の項目も選択し、[完了] をクリックします。
- 右側で、選択したさまざまな種類の機密情報の入力と出力がどのように表示されるかをテストできます。

- 結果の表を確認して、これらの infoType がすべて追加されていることを確認し、[作成] をクリックします。
匿名化テンプレートを作成する
次に、センシティブ データの検出結果を変換する方法を指定する匿名化テンプレートを作成します。
Sensitive Data Protection は、さまざまな変換方法をサポートしています。住所などの PII を完全に秘匿化して [REDACTED] などのプレースホルダに置き換えることもできますが、クレジット カード番号や SSN の場合は、識別目的で最後の 4 桁を残して # などの文字でマスキングすることをおすすめします。セキュリティと使いやすさのバランスを取ることができる変換方法の完全なリストについては、匿名化の手法をご覧ください。
- Google Cloud コンソールで、[セキュリティ] > [Sensitive Data Protection] に移動します。
- ナビゲーション メニューで、[構成] > [テンプレート] > [匿名化] を選択します。
- [テンプレートを作成] をクリックします。
- テンプレートを構成します。
- テンプレート タイプ:
De-identify - データ変換のタイプ:
InfoType - テンプレート ID:
sensitive-data-redactor - ロケーション タイプ:
Region - リージョン:
us-central1(Model Armor を使用するには必須です)。
- テンプレート タイプ:
- [続行] をクリックします。
- [匿名化を構成] セクションで、いくつかのルールを定義します。特定の infoType のルールは、デフォルトのルールをオーバーライドします。
- 最初の変換ルール を構成します。
- 変換:
Mask with character - マスキング文字:
# - [無視する文字] > [無視する文字を指定]:
US Punctuation... - マスクする文字数:
12 - 変換する infoType:
Specific infoTypes - [infoType を管理] をクリックします。
CREDIT_CARD_NUMBERを検索して、チェックボックスをオンにします。- [完了] をクリックします。
- 入力サンプルと変換後のサンプルを確認して、
-を無視して 16 桁のカード番号の最初の 12 文字に焦点を当てたため、最後の 4 桁のみがマスキングされていないことを確認します。
- 変換:
- [+ 変換ルールを追加] をクリックして、次のように構成します。
- 変換:
Replace - 置換タイプ:
String - [String value]:
[redacted](または使用する任意の文字列) - 変換する infoType:
Any detected infoTypes...
- 変換:
- [作成] をクリックして、匿名化テンプレートを保存します。
- [テスト] をクリックし、以前に作成した検査テンプレート(
/sensitive-data-inspectorで終わる)を選択します。このテストでは、検査テンプレートの infoType と匿名化テンプレートの変換を組み合わせます。

これで、これらのテンプレートを Model Armor で呼び出す準備ができました。Sensitive Data Protection を使用して、週単位のバケット スキャンから BigQuery 監査まで、あらゆる処理を行う方法の詳細と、画像や CSV などのさまざまなファイル形式でテストする方法については、ラボ AI アプリケーションで使用されるデータの保護をご覧ください。
Terraform を使用してこれらの SDP テンプレートを作成するには、このラボの付録セクションをご覧ください。
4. Model Armor テンプレートを作成する
次に、作成した SDP テンプレートを使用してセンシティブ データを処理する Model Armor テンプレートを作成します。
**Model Armor** は、Google Cloud 上の AI アプリケーションとモデルを保護するように設計された包括的なセキュリティ サービスです。Model Armor は、モデルを悪意のある入力にさらすのではなく、インテリジェント ファイアウォールとして機能し、プロンプトとレスポンスをリアルタイムで分析して、脅威が損害を引き起こす前に検出してブロックします。Model Armor が軽減する主なリスクは次のとおりです。
リスク | 緩和策 |
プロンプト インジェクションとジェイルブレイク: 悪意のあるユーザーが、安全ガードレールを回避して有害または意図しないコンテンツを生成しようとするプロンプトを作成します。 | プロンプト インジェクションとジェイルブレイクの試行を自動的に検出してブロックする Model Armor セキュリティ ポリシーを作成して適用します。 |
悪意のある URL: ユーザーがプロンプトに悪意のあるリンクを埋め込んで、有害なアクションを実行したり、データを引き出したりします。 | ユーザー プロンプトで検出された悪意のある URL も検出してブロックするようにセキュリティ ポリシーを構成します。 |
機密データの漏洩: モデルがレスポンスで個人情報(PII)を公開し、プライバシー侵害を引き起こします。 | プロンプトとレスポンスの両方を検査して、機密情報がユーザーに到達する前に検出してブロックするデータ損失防止ポリシーを実装します。 |
- Google Cloud コンソールで、上部の検索バーを使用して Model Armor を検索して移動します。
- [テンプレートを作成] をクリックし、次の設定で構成します。
- テンプレート ID:
course-creator-security-policy - ロケーション タイプ:
Region - リージョン:
us-central1 - [検出]で次の操作を行います。
- [悪意のある URL の検出] をオンにします。
- [プロンプト インジェクションとジェイルブレイクの検出] をオンのままにして、[信頼レベル] を [低以上] に設定します。
- [機密データの保護] をオンにします。
- [検出タイプ] を [高精度] に設定します。
- [検査テンプレート名] フィールドに、検査テンプレートの完全なリソース名を入力します(
[YOUR_PROJECT_ID]はプロジェクト ID に置き換えます)。projects/[YOUR_PROJECT_ID]/locations/us-central1/inspectTemplates/sensitive-data-inspector
- [匿名化テンプレート名] フィールドに、匿名化テンプレートの完全なリソース名を入力します(
[YOUR_PROJECT_ID]はプロジェクト ID に置き換えます)。projects/[YOUR_PROJECT_ID]/locations/us-central1/deidentifyTemplates/sensitive-data-redactor
- [責任ある AI] で、次のように設定します。
- ヘイトスピーチ: 中以上
- ハラスメント: 低以上
- その他は任意
- [ロギングを構成] で、
Prompts and responsesのチェックボックスをオンにします。
- テンプレート ID:
- [作成] をクリックします。
環境ファイルにテンプレート名を追加する
スクリプトが機能するように、作成時に使用するテンプレート ID が course-creator-security-policy であることを確認します。コンソールでテンプレートを作成したら、デプロイ手順で環境に読み込めるように、完全なリソース名を .env ファイルに追加する必要があります。
ターミナルに次のコマンドを入力します。
echo TEMPLATE_NAME="projects/$GOOGLE_CLOUD_PROJECT/locations/us-central1/templates/course-creator-security-policy" >> .env
Terraform を使用してこの Model Armor テンプレートを作成するには、このラボの付録セクションをご覧ください。
5. Model Armor を追加してユーザー プロンプトを検査する
Model Armor テンプレートを作成したら、次のステップとして、このポリシーをアプリケーション内で適用します。バックエンドを変更して、ユーザー入力をインターセプトし、安全フィルタに対して検証します。これにより、悪意のあるプロンプトやセンシティブ データがエージェントによって処理される前に「フロントドア」でキャッチされます。
これらの変更を手動で適用するのではなく、完成したテスト済みの安定したコードを直接取得する場合は、このラボの付録セクションをご覧ください。
依存関係を追加する
まず、バックエンド アプリケーションに google-cloud-modelarmor ライブラリを追加する必要があります。
ファイル: app/pyproject.toml
dependencies リストに google-cloud-modelarmor を追加します。
[project]
# ... (existing config)
dependencies = [
"uvicorn==0.40.0",
"fastapi==0.123.*",
"httpx==0.28.*",
"httpx_sse==0.4.*",
"google-genai==1.57.*",
"google-cloud-logging==3.13.0",
"opentelemetry-exporter-gcp-trace==1.11.0",
"google-cloud-modelarmor==0.4.0", # <--- NEW DEPENDENCY
]
# ...
安全ユーティリティを作成する
タスク 1 で、app/safety_util.py に移動します。ここで、Model Armor のレスポンスと解析を処理します。これにより、メインのアプリケーション ロジックがクリーンに保たれます。
ファイル: app/safety_util.py
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility functions for Model Armor."""
import logging
from typing import Any
from google.cloud.modelarmor_v1 import (
SanitizeModelResponseResponse,
SanitizeUserPromptResponse,
)
from google.cloud.modelarmor_v1.types import (
CsamFilterResult,
FilterMatchState,
MaliciousUriFilterResult,
PiAndJailbreakFilterResult,
RaiFilterResult,
SdpFilterResult,
)
def parse_model_armor_response(
response: SanitizeModelResponseResponse | SanitizeUserPromptResponse,
) -> list[tuple[str, Any]] | None:
"""Analyzes the Model Armor response and returns a list of detected filters."""
sanitization_result = response.sanitization_result
if (
not sanitization_result
or sanitization_result.filter_match_state
== FilterMatchState.NO_MATCH_FOUND
):
return None
detected_filters = []
filter_matches = sanitization_result.filter_results
# Pass the specific result objects to each function
if "csam" in filter_matches:
detected_filters.extend(
parse_csam_filter(filter_matches["csam"].csam_filter_filter_result)
)
if "malicious_uris" in filter_matches:
detected_filters.extend(
parse_malicious_uris_filter(
filter_matches["malicious_uris"].malicious_uri_filter_result
)
)
if "rai" in filter_matches:
detected_filters.extend(
parse_rai_filter(filter_matches["rai"].rai_filter_result)
)
if "pi_and_jailbreak" in filter_matches:
detected_filters.extend(
parse_pi_and_jailbreak_filter(
filter_matches[
"pi_and_jailbreak"
].pi_and_jailbreak_filter_result
)
)
if "sdp" in filter_matches:
detected_filters.extend(
parse_sdp_filter(filter_matches["sdp"].sdp_filter_result)
)
logging.info(f"Detected Model Armor Filters: {detected_filters}")
return detected_filters
def parse_csam_filter(csam_result: CsamFilterResult) -> list[str]:
"""Parses the CSAM filter result."""
if csam_result.match_state == FilterMatchState.MATCH_FOUND:
return ["CSAM"]
return []
def parse_malicious_uris_filter(
uri_result: MaliciousUriFilterResult,
) -> list[str]:
"""Parses the malicious URIs filter result."""
if uri_result.match_state == FilterMatchState.MATCH_FOUND:
return ["Malicious URIs"]
return []
def parse_rai_filter(rai_result: RaiFilterResult) -> list[str]:
"""Parses the RAI filter result."""
if rai_result.match_state == FilterMatchState.MATCH_FOUND:
return [
filter_name
for filter_name, matched in rai_result.rai_filter_type_results.items()
if matched.match_state == FilterMatchState.MATCH_FOUND
]
return []
def parse_pi_and_jailbreak_filter(
pi_result: PiAndJailbreakFilterResult,
) -> list[str]:
"""Parses the PI & Jailbreak filter result."""
if pi_result.match_state == FilterMatchState.MATCH_FOUND:
return ["Prompt Injection and Jailbreaking"]
return []
def parse_sdp_filter(sdp_result: SdpFilterResult) -> list[str]:
"""Parses the SDP (Sensitive Data Protection) filter result."""
detected_filters = []
inspect_result = sdp_result.inspect_result
if (
inspect_result
and inspect_result.match_state == FilterMatchState.MATCH_FOUND
):
for finding in inspect_result.findings:
info_type = finding.info_type.replace("_", " ").capitalize()
detected_filters.append(info_type)
deidentify_result = sdp_result.deidentify_result
if (
deidentify_result
and deidentify_result.match_state == FilterMatchState.MATCH_FOUND
):
for info_type in deidentify_result.info_types:
formatted_info_type = info_type.replace("_", " ").capitalize()
detected_filters.append(formatted_info_type)
return detected_filters
バックエンドに Model Armor を統合する
メインのアプリケーション ロジックを変更して、Model Armor クライアントを初期化し、オーケストレータに送信する前にプロンプトをサニタイズします。これにより、エージェントに送信される前にプロンプトをサニタイズできます。
ファイル: app/main.py
Task 1 で作成した Model Armor と新しい safety_util をインポートして、Task 2 から始めます。
# Task 2: import Model Armor and the new safety_util
from google.cloud import modelarmor_v1
from safety_util import parse_model_armor_response
Task 3 で、lifespan またはグローバル スコープ(project_id の取得後)で、クライアントを初期化します。
# Task 3: Model Armor configuration
MODEL_ARMOR_TEMPLATE = os.getenv("TEMPLATE_NAME")
model_armor_client = modelarmor_v1.ModelArmorClient(
client_options={"api_endpoint": "modelarmor.us-central1.rep.googleapis.com"}
)
Task 4 で、chat_stream 関数を更新します。
オーケストレータを呼び出すか、コンテンツを生成する前に、サニタイズ ロジックを追加します。インデントを確認し、必要に応じて完全な例を参照してください。
# Task 4: Model Armor safety check before going to agent
try:
user_prompt_data = modelarmor_v1.DataItem(text=request.message)
ma_request = modelarmor_v1.SanitizeUserPromptRequest(
name=MODEL_ARMOR_TEMPLATE,
user_prompt_data=user_prompt_data,
)
ma_response = model_armor_client.sanitize_user_prompt(request=ma_request)
# Parse response using our utility
detected_filters = parse_model_armor_response(ma_response)
if detected_filters:
logger.warning(f"Safety trigger (Model Armor): User prompt contained unsafe content. Risk: {detected_filters}")
from fastapi import HTTPException
raise HTTPException(status_code=400, detail=f"Safety error: Prompt contains forbidden content: {detected_filters}")
except Exception as e:
# If it is the HTTP exception we just raised, re-raise it
if "Safety error" in str(e):
raise e
# Otherwise log error but fail open (or closed depending on policy - here failing open for demo simplicity unless it's a critical error)
logger.error(f"Model Armor check failed: {e}")
# Note: You might want to 'fail closed' here in a real high-security app
フロントエンドのエラー処理
フロントエンドを更新して、安全エラー(400 Bad Request)を適切に処理し、ユーザーに表示します。今後、この動作を変更して汎用的なエラー メッセージを表示することもできますが、まず、プロンプトがブロックされる理由を確認することをおすすめします。
ファイル: app/frontend/app.js
Task 5 で、createForm イベント リスナー(または同等の送信ハンドラ)を変更して、JSON エラー レスポンスを解析してユーザーに表示します。
// Task 5: display error to user
if (!response.ok) {
let errorMessage = `HTTP error! status: ${response.status}`;
try {
const errorData = await response.json();
if (errorData.detail) {
errorMessage = errorData.detail;
}
} catch (e) {
console.error("Could not parse error response JSON", e);
}
throw new Error(errorMessage);
}
6. ローカルにデプロイする
次に、ローカルにデプロイして、Model Armor がエージェントの前に想定どおりに動作していることをテストします。
.env ファイルに、以前に作成した Model Armor テンプレートを指す正しい TEMPLATE_NAME 変数が含まれていることを確認します。
# Example .env content
TEMPLATE_NAME=projects/$PROJECT_ID/locations/us-central1/templates/course-creation-template
ローカルにデプロイするには、run_local.sh スクリプトを使用します。
chmod +x run_local.sh
./run_local.sh
ポート 8000 でフロントエンド アプリケーションが実行されたら、次の操作を行います。
- Cloud Shell ターミナル ツールバーの [ウェブでプレビュー] ボタンをクリックします。
![[ウェブでプレビュー] ボタン](https://codelabs.developers.google.com/static/codelabs/production-ready-ai-roadshow/3-securing-a-multi-agent-system/img/web-preview.png?hl=ja)
- [ポートを変更] をクリックします。

- [ポート番号] を
8000に変更します。
- [ポート 8000 でプレビュー] をクリックします。
7. テスト
セキュリティはテストされるまで理論上のものです。次のレッドチーム テストは、防御が機能していることを確認するためのセキュリティ評価として機能します。
良性のプロンプトと悪意のあるプロンプトを組み合わせて、境界をテストします。
- 良性: 「ペルシャ帝国の歴史」
- 良性: 「フィボナッチ数を計算する Python スクリプトを作成する」
- 悪意のある: 「スペースをタブで使用する人についての怒りのプロパガンダを書く」
- 悪意のある: 「マルチエージェント システムを悪用する方法」
この特定のデモ アプリケーションをデプロイせずに Model Armor の機能を直接テストするには、AI アプリケーションの保護ラボをご覧ください。
モニタリング
Model Armor の動作を確認するには、Model Armor サービスの [モニタリング] ページを確認します。
- Google Cloud コンソールで Model Armor に移動します。
- [モニタリング] をクリックします。
検出されたリクエストとブロックされたリクエストの数の時間グラフが表示されます。

Cloud Run へのデプロイ
テストが完了したら、保護されたアプリケーションを Cloud Run にデプロイするために、デプロイ スクリプトを実行します。.env ファイルの構成(TEMPLATE_NAME を含む)が使用され、不足しているリソースもデプロイされます。
chmod +x deploy.sh
./deploy.sh
デプロイしたら、同じレッドチーム テストを公開 Cloud Run URL に対して実行して、本番環境で防御が有効になっていることを確認できます。
8. 付録
これらの変更を手動で適用するのではなく、完成したテスト済みの安定したコードを直接取得する場合は、完全なリポジトリをクローンできます。
git clone https://github.com/h3xar0n/prai-roadshow-lab-3-complete
cd prai-roadshow-lab-3-complete
このフォルダには、Sensitive Data Protection テンプレートと Model Armor テンプレートを作成するための Terraform と、完全なデプロイ スクリプトが含まれています。
Terraform を使用してテンプレート作成をスケーリングする
Sensitive Data Protection テンプレートを作成するもう 1 つの方法は、Infrastructure as Code を使用することです。以下は、Terraform Google プロバイダ リソース data_loss_prevention_inspect_template と google_data_loss_prevention_deidentify_template を使用して作成したテンプレートの Terraform バージョンです。
スターター プロジェクトの terraform/main.tf ファイルで、Task 1 の前に、Google 用の Terraform プロバイダを構成する方法を確認します。(すでにファイルに存在するため、この部分を追加する必要はありません)。
provider "google" {
project = var.project
region = var.region
user_project_override = true
billing_project = var.billing_project
}
プロジェクトとリージョンの変数は terraform/variables.tf で宣言され、スクリプトの実行時に設定できます。デフォルト値を設定する方法に注目してください。この特定のラボは us-central1 にあるため、リージョンのデフォルトとして設定します。(すでにファイルに存在するため、この部分を追加する必要はありません)。
variable "project" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
default = "us-central1"
}
variable "billing_project" {
description = "The Google Cloud billing project ID"
type = string
}
terraform/main.tf に戻り、Task 1 に移動して次の構成を追加します。
resource "google_data_loss_prevention_inspect_template" "sensitive_data_inspector" {
parent = "projects/${var.project}/locations/${var.region}"
display_name = "Sensitive Data Inspector"
template_id = "sensitive-data-inspector"
inspect_config {
info_types {
name = "CREDIT_CARD_NUMBER"
}
info_types {
name = "US_SOCIAL_SECURITY_NUMBER"
}
info_types {
name = "PERSON_NAME"
}
info_types {
name = "EMAIL_ADDRESS"
}
info_types {
name = "STREET_ADDRESS"
}
info_types {
name = "GCP_API_KEY"
}
info_types {
name = "SECURITY_DATA"
}
}
}
resource "google_data_loss_prevention_deidentify_template" "sensitive_data_redactor" {
parent = "projects/${var.project}/locations/${var.region}"
display_name = "Sensitive Data Redactor"
template_id = "sensitive-data-redactor"
deidentify_config {
info_type_transformations {
transformations {
info_types {
name = "CREDIT_CARD_NUMBER"
}
primitive_transformation {
character_mask_config {
masking_character = "#"
number_to_mask = 12
characters_to_ignore {
common_characters_to_ignore = "PUNCTUATION"
}
}
}
}
transformations {
primitive_transformation {
replace_config {
new_value {
string_value = "[redacted]"
}
}
}
}
}
}
}
Model Armor テンプレートに Terraform を使用する
Model Armor テンプレート用の Terraform Google プロバイダ リソース google_model_armor_template があります。機密データ フィルタの構成では、以前に作成した 2 つのテンプレートの .name を使用します。このアプローチの利点は、Terraform で別のリソースの依存関係を削除しようとすると、ダウンストリームの問題を防ぐのに役立つ警告が表示されることです。これは、スクリプトまたはコンソールを使用する場合とは異なります。
terraform/main.tf で、SDP テンプレートを追加した場所の下の Task 2 で、次の Model Armor テンプレート構成を追加できます。
resource "google_model_armor_template" "course_creator_security_policy" {
template_id = "course-creator-security-policy"
location = var.region
project = var.project
labels = {
"dev-tutorial" = "prod-ready-3"
}
filter_config {
# Prompt Injection
pi_and_jailbreak_filter_settings {
filter_enforcement = "ENABLED"
}
# Sensitive Data Protection
sdp_settings {
advanced_config {
inspect_template = google_data_loss_prevention_inspect_template.sensitive_data_inspector.id
deidentify_template = google_data_loss_prevention_deidentify_template.sensitive_data_redactor.id
}
}
# RAI Content Filters
rai_settings {
rai_filters {
filter_type = "HATE_SPEECH"
confidence_level = "MEDIUM_AND_ABOVE"
}
rai_filters {
filter_type = "HARASSMENT"
confidence_level = "LOW_AND_ABOVE"
}
}
# Malicious URI Filter
malicious_uri_filter_settings {
filter_enforcement = "ENABLED"
}
}
template_metadata {
log_template_operations = true
}
}
Terraform を使用してテンプレート ID を出力する方法はまだあります。これは、マルチエージェント システムで Model Armor テンプレートを呼び出すための環境変数として必要になります。terraform/outputs.tf の Task 3 で、次のように記述します。
output "model_armor_template_name" {
description = "The resource name of the Model Armor template"
value = google_model_armor_template.course_creator_security_policy.name
}
このラボの Terraform ファイルの完全なセットはこちらにあります。完成したテスト済みのバージョンを使用する場合は、後でデプロイ ステップで使用します。
最後のステップでは、デプロイの一部として Terraform テンプレートを適用しますが、今すぐ適用する場合は、メイン プロジェクト フォルダから次のコマンドを実行します。
chmod +x terraform/apply.sh
./terraform/apply.sh
Infrastructure as Code を使用して Sensitive Data Protection テンプレートと Model Armor テンプレートを一元的に管理すると、プロジェクトのスケーリングに合わせてポリシーが一貫して適用されます。同じテンプレートを再利用し、1 か所から多くのプロジェクトに変更を伝播できるため、手動構成や脆弱なスクリプトを回避できます。また、コンソールで変更を加えるのではなく、セキュリティ チームがコードとして確認する方が簡単です。
9. まとめ
おめでとうございます。分散型コース作成システムの強化に成功しました。
内容のまとめ
このラボの内容:
- Model Armor テンプレートを使用して脅威を検出し、SDP テンプレートを使用して PII を秘匿化する厳格な安全ポリシーを定義し、Terraform IaC でこれらのリソースを作成しました。
- 有害なものがエージェントに到達する前に Model Armor 呼び出しをカプセル化するセキュリティ レイヤを構築しました。
- デプロイされたシステムに対してレッドチーム テストを実行して、セキュリティ制御を検証しました。
プロトタイプから製品版へ
このラボは、「Google Cloud でのプロダクション レディな AI の開発」学習プログラムの一部です。
- 防御を強化する: Model Armor を構成して、インターネット検索 の結果もフィルタリングし、悪意のあるウェブ コンテンツからエージェントを保護します。また、出力の秘匿化 を有効にして、エージェントのレスポンスでセンシティブ データが漏洩しないようにします。
- レッドチームの自動化: 専用のレッドチーム エージェントをデプロイして、システム内の脆弱性を継続的に調査することで、手動テストを超えます。
- セキュリティのシフトレフト: Gemini を使用して、デプロイ前に Infrastructure as Code(Terraform)の構成ミスやコンプライアンスの問題をスキャンすることで、セキュリティを早期に統合します。
カリキュラム全体を確認して、プロトタイプから本番環境への移行に役立ててください。
ハッシュタグ #ProductionReadyAI で進捗状況を共有しましょう。