はじめに
I'm a fullstack coding instructor. Every bootcamp cycle, I see the same pattern: new developers get excited about LLM APIs, build something cool in a weekend, and accidentally send customer data to OpenAI without realizing what they've done.
私はフルスタックのコーディングインストラクターです。毎期のブートキャンプで同じパターンを見ます:新人開発者がLLM APIに興奮し、週末でクールなものを作り、気づかないうちに顧客データをOpenAIに送ってしまいます。
This article covers the security mistakes I see most often — and how to avoid them from day one.
ミス1: プロンプトは平文で送信される
The prompt is sent in plaintext.
Many new developers think of an API call like a black box — you send input, get output. But every character of your prompt is transmitted to and stored on the provider's servers.
# This looks harmless...
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": "田中太郎様のメール tanaka@company.co.jp に請求書を送ってください"
}]
)
What actually happened:
-
田中太郎(customer name) → now on OpenAI's servers -
tanaka@company.co.jp(email) → now on OpenAI's servers - Both are logged and potentially used for model improvement
新人がよくやること: "動くからOK" と思ってそのままデプロイする。
ベテランがやること: プロンプトに個人情報が含まれていないか確認してから送信する。
ミス2: APIキーをハードコードする
API keys hardcoded in source code.
# ❌ 絶対にやってはいけない
client = openai.OpenAI(api_key="sk-abc123def456...")
# ✅ 環境変数を使う
import os
client = openai.OpenAI(api_key=os.environ["OPENAI_API_KEY"])
I've seen students push API keys to public GitHub repos. Within minutes, bots scrape them and run up thousands of dollars in charges.
GitHubにAPIキーをプッシュした学生を何人も見てきました。数分以内にボットがスクレイピングし、数千ドルの請求が発生します。
対策:
-
.envファイルを使い、.gitignoreに追加する -
git-secretsや GitHub's secret scanning を有効にする - APIキーにはスコープと利用制限を設定する
ミス3: エラーメッセージに個人情報が含まれる
PII leaking through error messages.
try:
process_customer(customer_data)
except Exception as e:
# ❌ 個人情報がログに残る
print(f"Error processing customer: {e}")
# エラーメッセージに顧客名やメールが含まれる可能性がある
# ✅ 安全なログ
print(f"Error processing customer ID: {customer_data['id']}")
Error messages, stack traces, and debug logs often contain the exact data you're trying to protect. In production, these end up in log aggregation services — another third party seeing your users' data.
ミス4: LLMの応答をそのまま信頼する
Trusting LLM output without validation.
# ❌ LLMの応答をそのまま実行
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_input}]
)
# LLMが生成したSQLをそのまま実行...
cursor.execute(response.choices[0].message.content)
LLMs can be manipulated through prompt injection. If user input flows into your prompt without sanitization, an attacker can make the LLM generate malicious output.
LLMはプロンプトインジェクションで操作される可能性があります。ユーザー入力をサニタイズせずにプロンプトに流すと、攻撃者がLLMに悪意のある出力を生成させることができます。
対策:
- ユーザー入力とシステムプロンプトを明確に分離する
- LLMの出力を検証してから使用する
- LLMの出力でSQLやコマンドを直接実行しない
ミス5: 個人情報の種類を把握していない
Not knowing what counts as PII.
New developers often think PII means "name and credit card number." The actual list is much longer:
新人開発者はPIIを「名前とクレジットカード番号」だと思いがちです。実際のリストはもっと長いです:
| カテゴリ | 例 | 見落としやすさ |
|---|---|---|
| 名前 | 田中太郎 | 低 |
| メール | tanaka@example.co.jp | 低 |
| 電話番号 | 090-1234-5678 | 中 |
| マイナンバー | 123456789012 | 低 |
| IPアドレス | 192.168.1.100 | 高 |
| APIキー | sk-abc123... | 高 |
| 住所 | 東京都渋谷区... | 高 |
| 医療情報 | 糖尿病、血液型A+ | 高 |
| JWT | eyJhbGciOi... | 高 |
IPアドレス、JWTトークン、住所 — これらは多くの新人が「個人情報」として認識しないデータですが、APPIでは保護対象です。
実践: LLM APIを安全に使う方法
Here's the pattern I teach my bootcamp students:
ステップ1: プロンプトに個人情報が含まれているか確認する
Before sending any prompt, scan it for PII:
from cloakllm import Shield, ShieldConfig
shield = Shield(ShieldConfig(locale="ja"))
# 分析のみ — 内容を変更しない
analysis = shield.analyze("田中太郎のメールは tanaka@example.co.jp です")
print(f"検出されたエンティティ: {analysis['entity_count']}")
for entity in analysis['entities']:
print(f" [{entity['category']}] confidence: {entity['confidence']}")
ステップ2: 個人情報を自動的に除去する
# 手動でサニタイズする必要なし — ミドルウェアが自動的に処理
from cloakllm import enable_openai
from openai import OpenAI
client = OpenAI()
enable_openai(client) # この一行で全てのAPIコールが保護されます
# 普通にOpenAIを使うだけ
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": "田中太郎様のメール tanaka@company.co.jp に請求書を送ってください"
}]
)
# プロバイダーには "[PERSON_0]様のメール [EMAIL_0] に請求書を送ってください" が送信される
# 応答では元の値が自動的に復元される
ステップ3: 監査ログを確認する
python -m cloakllm verify ./cloakllm_audit/
# Audit chain integrity verified — no tampering detected.
python -m cloakllm stats ./cloakllm_audit/
# 何件のPIIが検出・保護されたかを確認
チェックリスト: デプロイ前に確認すること
新人プログラマ向けのLLMセキュリティチェックリスト:
| チェック項目 | 確認 |
|---|---|
| APIキーが環境変数に格納されている | □ |
.env が .gitignore に含まれている |
□ |
| プロンプトに個人情報が含まれていないか確認した | □ |
| LLMの応答をバリデーションしている | □ |
| エラーログに個人情報が含まれていない | □ |
| ユーザー入力がサニタイズされている | □ |
| 個人情報保護法(APPI)の要件を理解している | □ |
先輩からのアドバイス
I've been teaching developers for years. The most important lesson about security isn't any specific technique — it's the habit of asking "what data am I sending, and where is it going?" before writing any API call.
LLMs make it incredibly easy to build powerful features. That ease is exactly what makes them dangerous — you can accidentally expose customer data in the time it takes to write a single function call.
Start with good habits now. Your future self (and your users) will thank you.
セキュリティで最も重要なのは特定のテクニックではありません。「どんなデータを送っていて、それはどこに行くのか?」を習慣的に問うことです。
リソース
- CloakLLM (open-source PII protection): https://github.com/cloakllm/CloakLLM
- OpenAI API security best practices: https://platform.openai.com/docs/guides/safety-best-practices
- APPI (個人情報保護法): https://www.ppc.go.jp/en/
Written by Ziv Chen — Building CloakLLM - open-source PII protection for LLMs | Founder of AI Training