mapbox-token-security について
Mapbox アクセストークンを管理する開発者やチーム向けのセキュリティスキルです。トークンの種類、最小権限、制限、保存、ローテーション、監視、監査、インシデント対応を扱います。
主な機能
- 01公開・シークレット・一時トークンの解説
- 02最小権限スコープの選択
- 03URL 制限パターンの提案
- 04安全な保存とトークンローテーション
- 05利用状況の監視とセキュリティ監査
- 06トークン漏えいへの対応手順
活用シーン
- 01クライアントまたはサーバーアプリ用トークンの選択
- 02スコープとドメインによるトークン制限
- 03定期または緊急ローテーションの計画
- 04トークン利用の監査や漏えいへの対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mapbox/ mcp-devkit-server --skill mapbox-token-securityインストール後、Claude Code で/mapbox-token-securityを入力して読み込まれたか確認します。
詳細
Mapbox トークンセキュリティスキル
このスキルでは、Mapbox のアクセストークンを安全かつ効果的に管理するためのセキュリティに関する知識を提供します。
トークンの種類と使用する場面
公開トークン(pk.*)
特徴:
- クライアントサイドのコードに安全に公開できます
- 特定の公開スコープのみ使用できます
- URL 制限を設定できます
- 機密性の高い API にはアクセスできません
使用する場面:
- クライアントサイドのウェブアプリケーション
- モバイルアプリ
- 一般公開向けのデモ
- ウェブサイトに埋め込む地図
許可されているスコープ:
styles:tiles- スタイルタイル(ラスター)の表示styles:read- スタイル仕様の読み取りfonts:read- Mapbox フォントへのアクセスdatasets:read- データセットデータの読み取りvision:read- Vision API へのアクセス
シークレットトークン(sk.*)
特徴:
- クライアントサイドのコードには絶対に公開しないでください
- すべてのスコープを使用できる完全な API アクセス権があります
- サーバーサイドでのみ使用します
- 他のトークンを作成・管理できます
使用する場面:
- サーバーサイドのアプリケーション
- バックエンドサービス
- CI/CD パイプライン
- 管理タスク
- トークン管理
一般的なスコープ:
styles:write- スタイルの作成・変更styles:list- すべてのスタイルの一覧表示tokens:read- トークン情報の表示tokens:write- トークンの作成・変更- ユーザーフィードバック管理用のスコープ
一時トークン(tk.*)
特徴:
- 有効期間が短い(最長 1 時間)
- シークレットトークンによって作成されます
- 単一の目的で使用します
- 自動的に期限切れになります
使用する場面:
- 一度限りの操作
- 一時的に委任するアクセス
- 有効期間の短いデモ
- セキュリティを重視するワークフロー
スコープ管理のベストプラクティス
最小権限の原則
必要最小限のスコープのみを常に付与してください:
❌ 悪い例:
// Overly permissive - don't do this
{
scopes: [
'styles:read',
'styles:write',
'styles:list',
'styles:delete',
'tokens:read',
'tokens:write'
];
}
✅ 良い例:
// Only what's needed for displaying a map
{
scopes: ['styles:read', 'fonts:read'];
}
用途別のスコープの組み合わせ
一般公開向けの地図表示(クライアントサイド):
{
"scopes": ["styles:read", "fonts:read", "styles:tiles"],
"note": "Public token for map display",
"allowedUrls": ["https://myapp.com/*"]
}
スタイル管理(サーバーサイド):
{
"scopes": ["styles:read", "styles:write", "styles:list"],
"note": "Backend style management - SECRET TOKEN"
}
トークン管理(サーバーサイド):
{
"scopes": ["tokens:read", "tokens:write"],
"note": "Token management only - SECRET TOKEN"
}
読み取り専用アクセス:
{
"scopes": ["styles:list", "styles:read", "tokens:read"],
"note": "Auditing/monitoring - SECRET TOKEN"
}
URL 制限
URL 制限が重要な理由
URL 制限を設定すると、公開トークンを使用できる場所が限定されるため、トークンが漏えいした場合の不正使用を防止できます。
効果的な URL パターン
✅ 推奨パターン:
https://myapp.com/* # Production domain
https://*.myapp.com/* # All subdomains
https://staging.myapp.com/* # Staging environment
http://localhost:* # Local development
❌ 次のパターンは避けてください:
* # No restriction (insecure)
http://* # Any HTTP site (insecure)
*.com/* # Too broad
複数環境の戦略
環境ごとに別々のトークンを作成します:
// Production
{
note: "Production - myapp.com",
scopes: ["styles:read", "fonts:read"],
allowedUrls: ["https://myapp.com/*", "https://www.myapp.com/*"]
}
// Staging
{
note: "Staging - staging.myapp.com",
scopes: ["styles:read", "fonts:read"],
allowedUrls: ["https://staging.myapp.com/*"]
}
// Development
{
note: "Development - localhost",
scopes: ["styles:read", "fonts:read"],
allowedUrls: ["http://localhost:*", "http://127.0.0.1:*"]
}
トークンの保管と取り扱い
サーバーサイド(シークレットトークン)
✅ 行うこと:
- 環境変数に保管する
- シークレット管理サービス(AWS Secrets Manager、HashiCorp Vault)を使用する
- 保存時に暗号化する
- IAM ポリシーを使ってアクセスを制限する
- トークンの使用状況をログに記録する
❌ 行わないこと:
- ソースコードに直接記述する
- バージョン管理にコミットする
- 暗号化されていない設定ファイルに保管する
- メールや Slack で共有する
- 複数のサービスで使い回す
例:安全な環境変数:
# .env (NEVER commit this file)
MAPBOX_SECRET_TOKEN=sk.ey...
# .gitignore (ALWAYS include .env)
.env
.env.local
.env.*.local
クライアントサイド(公開トークン)
✅ 行うこと:
- 公開トークンのみを使用する
- URL 制限を設定する
- アプリごとに異なるトークンを使用する
- 定期的にローテーションする
- 使用状況を監視する
❌ 行わないこと:
- シークレットトークンを公開する
- URL 制限のないトークンを使用する
- 関連のないアプリ間でトークンを共有する
- 過剰なスコープを持つトークンを使用する
例:安全なクライアントでの使用方法:
// Public token with URL restrictions - SAFE
const mapboxToken = 'pk.eyJ1IjoiZXhhbXBsZSIsImEiOiJjbGV4YW1wbGUifQ.example';
// This token is restricted to your domain
// and only has styles:read scope
mapboxgl.accessToken = mapboxToken;
トークンのローテーション戦略
トークンをローテーションするタイミング
必須のローテーション:
- 公開リポジトリでトークンが公開された場合
- トークンにアクセスできるチームメンバーが離職した場合
- 侵害または情報漏えいが疑われる場合
- サービスを廃止する場合
- コンプライアンス要件がある場合
定期的なローテーション:
- 90 日ごと(本番環境で推奨)
- 30 日ごと(セキュリティ要件の厳しい環境)
- 大規模なデプロイの後
- セキュリティ監査の際
ローテーション手順
ダウンタイムなしのローテーション:
- 同じスコープで新しいトークンを作成します
- カナリア/ステージング環境に新しいトークンをデプロイします
- 新しいトークンで機能を検証します
- 本番環境に段階的に展開します
- 24~48 時間、問題がないか監視します
- 確認後、古いトークンを失効させます
- ローテーション日をドキュメントに記載します
緊急ローテーション:
- 侵害されたトークンを直ちに失効させます
- 代替トークンを作成します
- すべてのサービスに緊急更新をデプロイします
- インシデントをチームに通知します
- 侵害がどのように発生したかを調査します
- 再発防止のために手順を更新します
監視と監査
トークンの使用状況を追跡する
監視する指標:
- トークンごとの API リクエスト量
- リクエストの地理的な分布
- トークンごとのエラー率
- 想定外の急増パターン
- 許可されていないドメインからのリクエスト
次の場合にアラートを発する:
- 想定外の IP/地域からの使用
- トラフィックの急増(通常の 200% 超)
- 高いエラー率(10% 超)
- 許可された URL 範囲外からのリクエスト
- 時間外のアクセスパターン
定期的なセキュリティ監査
月次チェックリスト:
- すべての有効なトークンを確認する
- トークンのスコープが引き続き適切か確認する
- 未使用のトークンを確認する(30 日超使用されていない場合は失効させる)
- URL 制限が最新であることを確認する
- チームメンバーのアクセス権を確認する
- 公開リポジトリにトークンがないか確認する(GitHub スキャン)
- ドキュメントが最新であることを確認する
四半期ごとのチェックリスト:
- 本番トークンをローテーションする
- トークンの完全な一覧を作成する
- アクセス制御を見直す
- インシデント対応手順を更新する
- チーム向けのセキュリティトレーニングを実施する
よくあるセキュリティ上のミス
1. クライアントコードでシークレットトークンを公開する
❌ 重大なエラー:
// NEVER DO THIS - Secret token in client code
const map = new mapboxgl.Map({
accessToken: 'sk.eyJ1IjoiZXhhbXBsZSIsI...' // SECRET TOKEN
});
✅ 正しい方法:
// Public token only in client code
const map = new mapboxgl.Map({
accessToken: 'pk.eyJ1IjoiZXhhbXBsZSIsI...' // PUBLIC TOKEN
});
2. スコープの許可範囲が広すぎる
❌ 範囲が広すぎる:
{
"scopes": ["styles:*", "tokens:*"]
}
✅ 具体的に指定:
{
"scopes": ["styles:read"]
}
3. URL 制限がない
❌ 制限なし:
{
"scopes": ["styles:read"],
"allowedUrls": [] // Token works anywhere
}
✅ ドメインで制限:
{
"scopes": ["styles:read"],
"allowedUrls": ["https://myapp.com/*"]
}
4. ローテーションせずに長期間トークンを使用する
❌ 一度もローテーションしない:
Token created: Jan 2020
Last rotation: Never
Still in production: Yes
✅ 定期的にローテーション:
Token created: Dec 2024
Last rotation: Dec 2024
Next rotation: Mar 2025
5. バージョン管理にトークンを含める
❌ Git にコミット:
// config.js (committed to repo)
export const MAPBOX_TOKEN = 'sk.eyJ1IjoiZXhhbXBsZSI...';
✅ 環境変数を使用:
// config.js
export const MAPBOX_TOKEN = process.env.MAPBOX_SECRET_TOKEN;
# .env (in .gitignore)
MAPBOX_SECRET_TOKEN=sk.eyJ1IjoiZXhhbXBsZSI...
インシデント対応計画
トークンが侵害された場合
直ちに行う対応(最初の 15 分以内):
- Mapbox ダッシュボードまたは API からトークンを失効させます
- 必要に応じて、異なるスコープ/制限を設定した代替トークンを作成します
- 侵害されたトークンを使用しているすべてのサービスを更新します
- インシデント用チャンネルでチームに通知します
調査(24 時間以内): 5. アクセスログを確認し、情報漏えいの状況を把握します 6. Mapbox ダッシュボードで不正使用がないか確認します 7. 根本原因を特定します(どのように公開されたか) 8. タイムラインと影響を含めてインシデントを記録します
再発防止(1 週間以内): 9. 再発を防ぐために手順を更新します 10. 追加の保護策を導入します(CI チェック、シークレットスキャン) 11. 得られた教訓についてチームをトレーニングします 12. 新しいセキュリティ対策をドキュメントに記載します
ベストプラクティスのまとめ
セキュリティチェックリスト
トークンの作成:
- クライアント側には公開トークン、サーバー側にはシークレットトークンを使用する
- スコープには最小権限の原則を適用する
- 公開トークンに URL 制限を追加する
- トークンを識別できる説明的な名前やメモを付ける
- 想定される用途と環境を記録する
トークンの管理:
- シークレットトークンは環境変数またはシークレットマネージャーに保存する
- トークンをバージョン管理にコミットしない
- 90 日ごと(またはポリシーに従って)にトークンをローテーションする
- 使用していないトークンは速やかに削除する
- 環境(開発/ステージング/本番)ごとにトークンを分ける
監視:
- トークンの使用パターンを追跡する
- 不審なアクティビティに対するアラートを設定する
- 定期的なセキュリティ監査(月次)
- チームのアクセス権を四半期ごとに確認する
- リポジトリをスキャンして、漏えいしたトークンがないか確認する
インシデント対応:
- 文書化された失効手順
- 緊急連絡先リスト
- ローテーション手順の文書化
- インシデント後のレビュー用テンプレート
- セキュリティ手順に関するチーム研修
このスキルを使用するタイミング
次の場合にこのスキルを呼び出します。
- 新しいトークンを作成するとき
- 公開トークンとシークレットトークンのどちらを使用するか決めるとき
- トークン制限を設定するとき
- トークンのローテーションを実装するとき
- セキュリティインシデントを調査するとき
- セキュリティ監査を実施するとき
- トークンセキュリティについてチームをトレーニングするとき
- トークンの漏えいがないかコードをレビューするとき