GenUのバックエンド (CDK) 詳細解説　⑧GuardrailStack スタックの解説

## はじめに

皆さん、こんにちは。

私は業務でデータ利活用基盤を取り扱っていること、2024 AWS Japan Top Engineer に選出されたということから、[AWS GenU](https://aws-samples.github.io/generative-ai-use-cases-jp/) およびそれに必要なデータ基盤の探求 ([Snowflake](https://www.snowflake.com/ja/), [dbt](https://www.getdbt.com/), [Iceberg](https://iceberg.apache.org/), etc) に取り組む必要があると考えています。

本投稿では、[GenU のバックエンドである CDK コード](https://github.com/aws-samples/generative-ai-use-cases-jp/tree/main/packages/cdk)を詳細に解説します。
自身そして閲覧して頂いた皆様の GenU への理解が少しでも深まり、生成 AI の民主化につながっていければと考えています。

## 前回までのおさらい

前回までで、以下が完了しました。

- [①AWS CDK のセットアップ](https://qiita.com/siruko/items/fd25fdcf89615cb85262)
- [②AWS CDK の動作確認](https://qiita.com/siruko/items/73169f986b4173e3d3a5)
- [③GenU の概要](https://qiita.com/siruko/items/625801b9e1847b305c1e)
- [④GenU CDK スタックの概要](https://qiita.com/siruko/items/8570ed43f7162ea4b907)
- [⑤CloudFrontWafStack スタックの解説](https://qiita.com/siruko/items/30439576ee7c63165d21)
- [⑥RagKnowledgeBaseStack スタックの解説](https://qiita.com/siruko/items/1223c9d22e73168a8809)
- [⑦WebSearchAgentStack スタックの解説](https://qiita.com/siruko/items/aef0a9599df60d47eb1e)

GenU の CDK は最大で以下の 6 つの子スタックを作成します。

- `CloudFrontWafStack`
- `RagKnowledgeBaseStack`
- `AgentStack`
- `GuardrailStack`
- `GenerativeAiUseCasesStack` ※メインスタック
- `DashboardStack`

今回は GenU 内の `GuardrailStack` スタックを解説していきたいと思います。

### GuardrailStack スタック

GuardrailStack は 生成 AI の入出力に含まれる機密情報のフィルタリング機能のスタックです。
アーキテクチャ図でいうと、以下の赤枠の部分にあたります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217144/31167e46-4871-448d-856d-9ce2e1f4bfe3.png)

GuardrailStack の実体は [`packages/cdk/lib/guardrail-stack.ts`](https://github.com/aws-samples/generative-ai-use-cases-jp/blob/main/packages/cdk/lib/guardrail-stack.ts) にあります。

```typescript:packages/cdk/lib/guardrail-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Guardrail } from './construct';

interface GuardrailStackProps extends StackProps {}

export class GuardrailStack extends Stack {
  public readonly guardrailIdentifier: string;

  constructor(scope: Construct, id: string, props: GuardrailStackProps) {
    super(scope, id, props);

    const guardrail = new Guardrail(this, 'Guardrail');
    this.guardrailIdentifier = guardrail.guardrailIdentifier;
  }
}
```

このスタックでは、以下のリソースを作成しています。

- `Guardrail`

#### GuardrailStack > Guardrail リソース

Guardrail リソースの実体は `packages/cdk/lib/construct/guardrail.ts` にあります。
以下のソースコードが Guardrail の定義です。

```typescript:packages/cdk/lib/construct/guardrail.ts
import { Construct } from 'constructs';
import { aws_bedrock as bedrock, Lazy, Names } from 'aws-cdk-lib';

export class Guardrail extends Construct {
  public readonly guardrailIdentifier: string;

  constructor(scope: Construct, id: string) {
    super(scope, id);

    const suffix = Lazy.string({ produce: () => Names.uniqueId(this) });

    const cfnGuardrail = new bedrock.CfnGuardrail(this, `guardrail`, {
      blockedInputMessaging:
        '禁止された入力を検出しました。会話を最初からやり直すか、管理者にお問い合わせください。',
      blockedOutputsMessaging:
        'システムが禁じている内容の出力を検出しました。会話を最初からやり直すか、管理者にお問い合わせください。',
      name: `Guardrail-${suffix}`,
      sensitiveInformationPolicyConfig: {
        // NAME, DRIVER_ID は日本のものが機能しないので設定しない
        // CA_*, US_*, UK_* はそれぞれの国固有のものなので設定しない
        piiEntitiesConfig: [
          { action: 'BLOCK', type: 'AGE' },
          { action: 'BLOCK', type: 'AWS_ACCESS_KEY' },
          { action: 'BLOCK', type: 'AWS_SECRET_KEY' },
          { action: 'BLOCK', type: 'CREDIT_DEBIT_CARD_CVV' },
          { action: 'BLOCK', type: 'CREDIT_DEBIT_CARD_EXPIRY' },
          { action: 'BLOCK', type: 'CREDIT_DEBIT_CARD_NUMBER' },
          { action: 'BLOCK', type: 'EMAIL' },
          { action: 'BLOCK', type: 'INTERNATIONAL_BANK_ACCOUNT_NUMBER' },
          { action: 'BLOCK', type: 'IP_ADDRESS' },
          { action: 'BLOCK', type: 'LICENSE_PLATE' },
          { action: 'BLOCK', type: 'MAC_ADDRESS' },
          { action: 'BLOCK', type: 'PASSWORD' },
          { action: 'BLOCK', type: 'PHONE' },
          { action: 'BLOCK', type: 'PIN' },
          { action: 'BLOCK', type: 'SWIFT_CODE' },
          { action: 'BLOCK', type: 'URL' },
          { action: 'BLOCK', type: 'USERNAME' },
        ],
      },
    });

    this.guardrailIdentifier = cfnGuardrail.attrGuardrailId;
  }
}
```

この中では、Bedrock が組み込まれた生成 AI アプリケーションの入出力について、機密情報のフィルタリングを目的としたガードレール `CfnGuardrail` を生成しています。

- 名前は `Guardrail-ABCD1234`
- 機密情報フィルター `sensitiveInformationPolicyConfig` を設定
  - PII エンティティの検知設定である [`piiEntitiesConfig`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-bedrock-guardrail-piientityconfig.html) のうち、以下を指定
    ※PII（Personally Identifiable Information）とは、個人を識別できる情報のこと
    - `AGE`: 個人の年齢
    - `AWS_ACCESS_KEY`: AWS のアクセスキー ID
    - `AWS_SECRET_KEY`: AWS のシークレットキー
    - `CREDIT_DEBIT_CARD_CVV`: クレジットカード検証コード (CVV) (3 桁または 4 桁)
    - `CREDIT_DEBIT_CARD_EXPIRY`: クレジットカードの有効期限
    - `CREDIT_DEBIT_CARD_NUMBER`: クレジットカード番号
    - `EMAIL`: 電子メールアドレス
    - `INTERNATIONAL_BANK_ACCOUNT_NUMBER`: 国際銀行口座番号
    - `IP_ADDRESS`: IPv4 アドレス
    - `LICENSE_PLATE`: 自動車のナンバープレート (5 桁から 8 桁)
    - `MAC_ADDRESS`: MAC アドレス
    - `PASSWORD`: パスワード
    - `PHONE`: 電話番号 (FAX 番号やポケベルも含む)
    - `PIN`: 銀行口座の暗証番号 (4 桁の PIN)
    - `SWIFT_CODE`: 銀行識別コード (BIC) (8 桁または 11 桁)
    - `URL`: Web サイトの URL
    - `USERNAME`: ログイン名などのアカウントを識別するユーザー名
- 入力内容に機密情報が含まれていることを検出した際のメッセージ
  **禁止された入力を検出しました。会話を最初からやり直すか、管理者にお問い合わせください。**
- 出力内容に機密情報が含まれていることを検出した際のメッセージ
  **システムが禁じている内容の出力を検出しました。会話を最初からやり直すか、管理者にお問い合わせください。**

以上です。
次回は ついにメインとなる GenU 内の `GenerativeAiUseCasesStack` スタックを解説していきたいと思います。

## (参考) GenU のバックエンド (CDK) 詳細解説投稿一覧

- [①AWS CDK のセットアップ](https://qiita.com/siruko/items/fd25fdcf89615cb85262)
- [②AWS CDK の動作確認](https://qiita.com/siruko/items/73169f986b4173e3d3a5)
- [③GenU の概要](https://qiita.com/siruko/items/625801b9e1847b305c1e)
- [④GenU CDK スタックの概要](https://qiita.com/siruko/items/8570ed43f7162ea4b907)
- [⑤CloudFrontWafStack スタックの解説](https://qiita.com/siruko/items/30439576ee7c63165d21)
- [⑥RagKnowledgeBaseStack スタックの解説](https://qiita.com/siruko/items/1223c9d22e73168a8809)
- [⑦WebSearchAgentStack スタックの解説](https://qiita.com/siruko/items/aef0a9599df60d47eb1e)
- [⑧GuardrailStack スタックの解説](https://qiita.com/siruko/items/d16e9fe27df4673d7554)
- [⑨GenerativeAiUseCasesStack > Auth スタックの解説](https://qiita.com/siruko/items/0c14040a1af132f42382)
- [⑩GenerativeAiUseCasesStack > Database, Api スタックの解説](https://qiita.com/siruko/items/5f249f11847f3829c18a)
- [⑪GenerativeAiUseCasesStack > CommonWebAcl, Web, Rag スタックの解説](https://qiita.com/siruko/items/1063daa2efe0b374a3fc)
- [⑫GenerativeAiUseCasesStack > RagKnowledgeBase, UseCaseBuilder, Transcribe スタックの解説](https://qiita.com/siruko/items/73d6006004caf8648594)
- [⑬DashBoard スタックの解説](https://qiita.com/siruko/items/73a75c7d0146d12ecbc3)
- [⑭GenU の Outputs の解説](https://qiita.com/siruko/items/afc14128a5b1a15ab69c)