メインコンテンツへスキップ
カスタマイズした PII ポリシーを追加する方法がコンソールでの手順を扱うのに対し、このページはルールの内容を扱います — どのフィールドに何を書けば検知エンジンが正確に動作するのか、そしてルール同士が衝突しないよう優先順位をどう設計するのか。例は Starfort デフォルト PII ポリシー(韓国の識別子 — 住民登録番号・韓国の住所・電話形式 — 向けにチューニングされて同梱)の構造に沿って、なじみやすいよう日本のデータに置き換えています。書き方の原則はどのロケールでも同じです。

ポリシー構造と処理順序

PII ポリシーは 3 種類のルール配列で構成されます。許可されるトップレベルキーは nerregexkeyword で、エンジンは常に Keyword → Regular Expression → NER の順に検査します。前の段階が確定したテキストは後の段階には隠された状態で渡されるため、前の段階の判定がそのテキストに対して最終となります。
ルール種別特性適した対象
Keyword大文字小文字を区別する完全一致。最速・決定的社内コードネーム、既知の安全な値(allowlist)
Regular Expressionパターン一致。決定的形式が固定された識別子(マイナンバー、電話番号、カード番号、メール)
NER EntityAI モデル検知。文脈を理解文脈に依存する情報(氏名、住所)、パターンが取りこぼす変形

優先順位の設計

ルールが増えるほど、ルール同士の相互作用が結果を左右します。3 つの優先順位を覚えてください。
  1. ルール種別の優先順位: Keyword > Regular Expression > NER。 前の段階が確定したテキストを後の段階が再判定することはありません。
  2. PASSING は allowlist です。 policy_type: "PASSING" ルールが一致したテキストは安全として確定し、以後どのマスキング・ブロックルールも上書きできません。同じ種別内で同じテキストに 2 つのルールが一致した場合は id が小さいルールが優先されます。
  3. action の優先順位: BLOCK > MASK > PASS。 リクエスト内でルールが 1 つでも BLOCK を決定すると、他のルールがマスキングしただけでもリクエスト全体がブロックされます。
この原則を活かすには、実データ用マスキング正規表現より小さい id にテストパターンの PASSING ルールを配置します。ドキュメントの例示や QA で使うサンプル値がマスキングされなくなります:
{
  "id": 0,
  "rule_id": "test_data:_my_number_test_pattern",
  "regex": "(?<!\\d)(?:0000[-\\s]?0000[-\\s]?0000|1234[-\\s]?5678[-\\s]?9012)(?![-\\s]?\\d)",
  "description": "0000-0000-0000, 1234-5678-9012 (よく使われるマイナンバーのサンプル値)",
  "policy_type": "PASSING",
  "mask_word": "TEST_DATA",
  "alert_message": "test data pattern - allowed"
}
同じ目的で keyword ルールも使えます — サンプル文書の定番名 山田太郎 を PASSING で先取りし、NER の氏名ルールがマスキングできないようにします。Keyword 段階は NER より先に実行されるため、この先取りは確実に機能します。

Regular Expression ルールの書き方

マイナンバー(個人番号)のルール:
{
  "id": 10,
  "rule_id": "my_number:_japan_individual_number",
  "regex": "(?<!\\d)\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}(?![-\\s]?\\d)",
  "description": "1234-5678-9012, 1234 5678 9012, 567890123456 | 末尾ガードで 16 桁カード番号の先頭 12 桁を先取りしない",
  "policy_type": "MASKING",
  "mask_word": "MY_NUMBER",
  "alert_message": "マイナンバーを検知しました"
}
このルールが示す作成プラクティス:
  • 数字境界を固定する。 前後の (?<!\d) / 末尾ガードがないと、より長い数字列(銀行口座、バーコード)の中間部分がマイナンバーとして誤検知されます。
  • 他ルールとの衝突はパターン側で解決する。 末尾の (?![-\s]?\d) ガードは、1234-5678-9012-3456 のような 16 桁カード番号の先頭 12 桁をマイナンバーとして先取りしてしまう誤検知を防ぎます。
  • description に一致例を記録する。 このフィールドは検知には使われませんが、後でルールをレビューする人がパターンを解読し直さずに済みます。
空文字に一致し得るパターン(\d*secret|)は何も検知せずスキップされます。またパターン前後の空白は保存時に除去されるため、意図的な境界空白は \s[ ] のようにパターン内に表現してください。

NER Entity ルールの書き方

NER ルールで AI モデルに渡されるのは Name、Description、Positive Examples、Negative Examples の 4 フィールドだけです。Policy Type、Mask Word、Alert Message は検知の処理だけを決め、検知自体には影響しません。つまり検知精度は前の 4 フィールドで決まります。 日本の住所ルールで各フィールドの役割を見ます。このルールの核心は具体性の境界です — 同じ「場所の話」でも、特定の個人や事業所にたどり着けるほど具体的なら機密情報、一般的な場所への言及ならそうではありません。以下の各節が例のどの部分を指しているか、対応させながら読んでください:
{
  "id": 2,
  "name": "住所 (日本)",
  "description": "特定の個人や事業所の位置を識別できる日本の住所。町名+丁目・番地(・号)のような具体的な要素を必ず含み、建物名・階・部屋番号のような詳細情報が続くことがある。ランドマーク、駅の出口、建物名単独、番地のない地名のような一般的な場所への言及は住所ではない。",
  "policy_type": "MASKING",
  "mask_word": "ADDRESS",
  "alert_message": "住所を検知しました",
  "positive_examples": [
    "本社: 東京都千代田区丸の内1丁目9-2 グラントウキョウサウスタワー 21階 →丸の内1丁目9-2 グラントウキョウサウスタワー 21階",
    "配送先: 大阪府大阪市北区梅田3-1-3 ノースゲートビルディング 7階 →梅田3-1-3 ノースゲートビルディング 7階",
    "オフィスの住所は港区六本木6-10-1 六本木ヒルズ森タワー 18F です →六本木6-10-1 六本木ヒルズ森タワー 18F"
  ],
  "negative_examples": [
    "渋谷駅ハチ公口で待ち合わせ",
    "スターバックス新宿店で会おう",
    "代官山のカフェを教えて"
  ]
}
同梱されるデフォルトポリシーは韓国のトラフィック向け(韓国の住所・住民登録番号・電話形式)に書かれています。上のルールはその住所ルールを日本のデータに置き換えたものです — フィールド構造と書き方の原則は変わりません。

Description — 定義 + 具体性の条件

上の Description は 4 つの要素を順に含んでいます: 定義(個人・事業所の位置を識別)、必須の具体性条件(「町名+丁目・番地」)、許容される詳細の変形(建物名・階・部屋番号)、そして除外条件(ランドマーク、駅の出口、建物名単独、番地のない地名)。機密/非機密を分ける境界線を、Description が文章で引いているのです — モデルは「この場合は該当しない」と書かれたケースに NO と答えるよう指示されるため、除外条件は実際に機能します。下のシナリオ 3 が、この境界が実際に判定を分ける様子をそのまま見せます。

Positive Examples — 矢印の規約

すべての肯定例は 文脈 →値 の形式で書きます。モデルは の後ろが検知すべき正確な値だと学習します。
  • の前の文はいつ発動するか(再現率)を、 の後ろの値は正確な出力形態(精度)を教えます。
  • 値はマスキング範囲も教えます。上の 3 例はいずれも、値が広域単位(東京都千代田区、大阪府大阪市北区 など)を除いて町名から始まっています — どこからどこまでを機密情報と見なすかを、例の値で教えているのです。
  • 値は入力内で再度見つけられる必要があります。現れたとおりに書くのが最も安全で(スペースの違い程度は許容)、町名と建物名を並べ替えるような再構成をした値は位置を特定できず破棄されます。
  • 上の 3 例は実際に登場する表記を 1 つずつ教えています: ラベル付きの本社住所、配送先ラベル+ビル名の変形、ラベルなしで文中に埋め込まれた住所。取りこぼせない形ごとに例を 1 つずつ置いてください。
  • 検知したいデータの言語・形式で例を書いてください。

Negative Examples — 誤検知の防壁

形は似ているが具体性が足りない近接事例を入れてください。上の 3 つの negative はそれぞれ別の誤検知経路を塞ぎます: 渋谷駅ハチ公口(待ち合わせ場所のランドマーク)、スターバックス新宿店(店名+支店名)、代官山(番地のない街の名前)。3 つとも Description の除外条件と対になっています。NER ルールは小さなバッチでまとめてスクリーニングされるため、あるルールの弱い negative が隣のルールの過検知まで誘発することがあります。

Keyword ルールの書き方

Keyword は大文字小文字を区別する完全一致です。文脈を見ないため、短く一般的な単語は避けてください。
  • 良い BLOCKING キーワード: PROJECT-ORION のような社内コードネーム — どこに現れてもそれ自体が機密。
  • 良い PASSING キーワード: 山田太郎 — サンプル文書の定番名を先取りして、NER の氏名ルールにマスキングさせない allowlist。
  • 悪いキーワード: アカウント のような一般名詞 — 現れるすべての箇所で無差別に発動。

シナリオ例

上のようなルールを割り当てた Guardian にリクエストを送ったときの動作です。

シナリオ 1 — 携帯電話番号のマスキング

「私の番号は 090-1234-5678 です。080.9876.5432 でも連絡できます。」
区切り文字が違っても電話番号の正規表現が両方の値に一致します。結果は "action": "MASK"、本文は 私の番号は [PHONE_NUMBER_1] です。[PHONE_NUMBER_2] でも連絡できます。 — マスクワードには出現順にインデックスが付きます。

シナリオ 2 — テストデータは通過、実データはマスキング

「テスト用のマイナンバーは 1234-5678-9012、本番は 5678-9012-3456 です。」
1234-5678-9012 はマイナンバーのマスキングルールの形にも一致しますが、よく知られたサンプル値なので PASSING テストパターン(id 0)が先に先取りし、そのまま通過します。マスキングされるのは 5678-9012-3456 だけです: テスト用のマイナンバーは 1234-5678-9012、本番は [MY_NUMBER_1] です。 — allowlist ルールが実データルールより小さい id を持つ理由です。

シナリオ 3 — 具体的な住所だけが機密情報

「ミーティングは渋谷駅ハチ公口前のカフェでやりましょう。契約書は東京都千代田区丸の内1丁目9-2 グラントウキョウサウスタワー 21階に送ってください。」
1 つのメッセージに場所への言及が 2 回ありますが、判定は分かれます。渋谷駅ハチ公口 はランドマークレベルの一般的な言及なので — Description の除外条件と negative example が教えたとおり — 通過します。町名+丁目・番地のある具体的な住所だけがマスキングされ、マスキング範囲は例の値が教えたとおり町名から始まります: ミーティングは渋谷駅ハチ公口前のカフェでやりましょう。契約書は東京都千代田区 [ADDRESS_1] に送ってください。

シナリオ 4 — BLOCK はすべてに勝つ

マスキングルールが 10 個一致していても、BLOCKING ルールが 1 つ一致すれば結果は "action": "BLOCK" で、マスキングされた本文は返されません。送信そのものを止めるべき値(社外秘コードネームなど)にだけ BLOCKING を使い、残りは MASKING にするのが良い設計です。

チェックリスト

  • 正規表現に数字・単語境界((?<!\d)、末尾ガード)を入れたか?
  • テスト・例示用の値を PASSING ルールで先取りしたか?
  • NER の Description に定義 + 具体性・文脈条件 + 除外条件を書いたか?
  • Positive Examples を 文脈 →値 形式で、値がマスキング範囲を正確に指すように書いたか?
  • Negative Examples に具体性の足りない近接事例を入れたか?
  • BLOCKING は本当に遮断が必要なルールだけに使ったか?
Starfort には包括的なデフォルト PII ポリシー(韓国の識別子向けに著述)が同梱されており、コンソールの JSON エディタで読み込めます — このページがしたように、構造のテンプレートとして使い、ルールを自組織のロケールに合わせて調整してください。コンソールのポリシーページにある TIP ボタンでもこのガイドの要約を確認できます。
ルール数と例の分量はそのまま検知コストです。すべての呼び出しにルール定義の全文が渡されるため、冗長すぎるポリシーはすべてのリクエストを遅くし、極端な場合はモデルの入力上限を超えてリクエストを失敗させます。ルールあたり鋭い例 5〜10 個が、網羅的な羅列に勝ります。